Taro+vue3开发的小程序自定义富文本编辑器-editor
#笔记记录使用微信小程序原生自定义富文本编辑器。微信小程序官方文档editor | 微信开放文档效果1·、先封装一个富文本配置组件WeEditor.vue其中icon是已经在根目录的app.js中引入import ./assets/iconfont/iconfont.cssicon自行挑选网址iconfont-阿里巴巴矢量图标库template view classeditor-box view classborder-line view classeditor-box-header view classoperate-box v-for(item, index) in config :keyindex taphandleEditor(item) text :class[iconfont, item.iconfont] / /view /view view classeditor-box-content editor refeditor :ideditorId classeditor :valueeditorValue :placeholderplaceholder :read-onlyreadOnly show-img-size show-img-toolbar show-img-resize bluronEditorBlur readyonEditorReady inputonEditorInput/editor /view /view /view /template script setup import { reactive, ref } from vue import Taro from tarojs/taro import { useUploadFile } from /hooks/network //自定义上传图片组件 import { useProcessStatus } from /hooks/form const editor ref(null) const state reactive({ editorCtx: , }) const editorId editor_${new Date().getTime()} //导入本地配置图标根据自定义需求找 const config [ { iconfont: icon-tupian, name: image, value: , }, { iconfont: icon-xieti, name: italic, value: , }, { iconfont: icon-jiacu, name: bold, value: , }, { iconfont: icon-yijibiaoti, name: header, value: h1, }, { iconfont: icon-erjibiaoti, name: header, value: h2, }, { iconfont: icon-sanjibiaoti, name: header, value: h3, }, { iconfont: icon-zuoduiqi, name: align, value: left, }, { iconfont: icon-juzhongduiqi, name: align, value: center, }, { iconfont: icon-youduiqi, name: align, value: right, }, { iconfont: icon-youxuliebiao, name: list, value: ordered, }, { iconfont: icon-wuxuliebiao, name: list, value: bullet, }, { iconfont: icon-chexiao, name: undo, value: , }, ] const props defineProps({ readOnly: { type: Boolean, default: false, }, placeholder: { type: String, default: 请输入图文详情, }, editorValue: { type: String, default: , }, }) const emits defineEmits([editorInput]) const onEditorReady () { Taro.createSelectorQuery() .select(#${editorId}) .context((res) { state.editorCtx res.context setTimeout(() { if (props.editorValue) { state.editorCtx.setContents({ html: props.editorValue, }) } else { state.editorCtx.setContents({ html: , }) } state.editorCtx.blur() Taro.pageScrollTo({ scrollTop: 0, duration: 0, }) }, 100) }) .exec() } const handleEditor (item) { const type item.name const val item.value if (type image) { onAddImage() } else if (type undo) { undo() } else { onFormat(type, val) } } const onEditorBlur () { state.editorCtx.blur() } // 插入图片 const onAddImage (event) { Taro.chooseMedia({ count: 1, sizeType: [image, video], sourceType: [album], success: (res) { Taro.showLoading({ title: 上传中, mask: true, }) onUploadImage(res.tempFiles[0]) }, }) } const onUploadImage async (tempFilePath) { //自定义的图片上传路径 let res await useUploadFile(tempFilePath.tempFilePath) //处理成功狗的造册 useProcessStatus(res, { success() { state.editorCtx.insertImage({ src: res.result.url, }) Taro.hideLoading() }, fail() { Taro.showToast({ icon: error, title: 上传失败, mask: true, }) Taro.hideLoading() }, }) } const onFormat (type, val) { state.editorCtx.format(type, val) } // 撤销 const undo () { state.editorCtx.undo() } // 监控输入 const onEditorInput (e) { const html e.detail.html //当输入数据再清空时会遗留一个带标签的br .,这样的的必填则无意义在此清空更换掉 if (!e.detail.text.replace(/\n|\r/g, )) { emits(editorInput, ) } else { emits(editorInput, html) } } /script style langscss .iconfont { font-size: 34rpx; } .editor-box { width: 100%; padding: 28rpx; box-sizing: border-box; background-color: #fff; .border-line { border: 1rpx solid #e6e6e6; .editor-box-header, .editor-box-content { width: 100%; } .editor-box-header { display: flex; flex-flow: row nowrap; align-items: center; justify-content: space-between; padding: 20rpx; box-sizing: border-box; border-bottom: 2rpx solid #e6e6e6; .operate-box { width: 40rpx; height: 40rpx; overflow: hidden; color: gray; .active { font-weight: bold; color: #000; } } } .editor-box-content { padding: 20rpx; box-sizing: border-box; .editor { height: auto; color: var(--nut-title-color); } } } } .ql-container { height: auto; color: var(--nut-title-color); line-height: 1.2; } /style2、导入以上组件到同级目录下的index,jsimport WeEditor from ./WeEditor.vue export {WeEditor}3、在页面使用导人组件import { WeEditor } from /components使用组件WeEditor :editor-valuestate.value placeholder请填写分会简介 editorInputonEditorInput /