1、需求:要在小程序中展示新手指引富文本,某位吃饱没事做的后端拉着我要弄一个pc端编辑富文本的页面。
2、思路:pc端wangEditor怼上去就好,比较注意的就是自定义的视频上传,小程序端要注意的就是视频不能用微信自带的rich-text去展示
3、实现
视频自定义上传
.vue
createWangeditor() { let _this = this this.editor = new E(this.$refs.guide) this.editor.config.height = this.$refs.guide.offsetHeight - 42 this.editor.config.uploadImgShowBase64 = true this.editor.config.showLinkVideo = false this.editor.config.customUploadVideo = function(resultFiles, insertVideoFn) { // resultFiles 是 input 中选中的文件列表 // insertVideoFn 是获取视频 url 后,插入到编辑器的方法 let file = resultFiles[0] const form = new FormData() form.append(\'file\', file) form.append(\'displayName\', file.name) form.append(\'busiType\', \'priceChange\') _this.ajax .post(\'/com/file/upload\', form, { \'Content-Type\': \'multipart/form-data\' }) .then(res => { console.log(res) // 上传视频,返回结果,将视频地址插入到编辑器中 insertVideoFn(res.fileUrl) }) } this.editor.create() }
小程序展示组件
richtext.js
// components/richtext/richtext.js Component({ /** * 组件的属性列表 */ properties: { contentText: { type: String, default: \'\', observer: function (newVal) { this.deCodeRich(newVal) } } }, /** * 组件的初始数据 */ data: { content: [] }, /** * 组件的方法列表 */ methods: { deCodeRich(str) { // 移除iframe // const iframeReg = /<iframe[\s\S]*?(\/>|><\/iframe>){1}/g //原本 const iframeReg = new RegExp(\'<iframe[\\s\\S]*?(\\/>|><\\/iframe>){1}\', \'g\') str = str.replace(iframeReg, \'\') // 获取video // const videoReg = /<video[\s\S]*?(\/>|><\/video>){1}/g //原本 const videoReg = new RegExp(\'<video[\\s\\S]*?(\\/>|><\\/video>){1}\', \'g\') const videoMatch = (str.match(videoReg) || []).map(e => ({ type: \'video\', text: e })) // 获取audio // const audioReg = /<audio[\s\S]*?<\/audio>{1}/g //原本 const audioReg = new RegExp(\'<audio[\\s\\S]*?<\\/audio>{1}\', \'g\') const audioMatch = (str.match(audioReg) || []).map(e => ({ type: \'audio\', text: e })) const matchAry = [].concat(...videoMatch, ...audioMatch) let richData = [] if (matchAry.length > 0) { // 匹配到 for (let m of matchAry) { let splitData = str.split(m.text) let restOfStr = \'\' //剩余字符串 const notMiddle = (splitData[0] ? 1 : 0) ^ (splitData[splitData.length - 1] ? 1 : 0) if (!notMiddle) { let newSplitData = [] splitData.forEach((d, i) => { newSplitData.push(d) if (i !== splitData.length - 1) { newSplitData.push(\'\') } }) splitData = newSplitData } const newData = splitData.map(s => { if (!s) { // 获取 src&style // /(?<=src=")[\s\S]*?(?=")/ 原本 // /(?<=style=")[\s\S]*?(?=")/ 原本 const srcReg = new RegExp(\'(?<=src=")[\\s\\S]*?(?=")\') const styleReg = new RegExp(\'(?<=style=")[\\s\\S]*?(?=")\') let src = m.text.match(srcReg) let style = m.text.match(styleReg) return { type: m.type, src: src ? src[0] : null, style: style ? style[0] : null } } else { restOfStr += s return s } }) str = restOfStr if (newData.length > 1) { //内容正常 const rIndex = richData.findIndex(rich => typeof rich === "string") rIndex !== -1 ? richData[rIndex] = newData : richData = newData // 展开二维数组 richData = Array.prototype.concat.apply([], richData) } // console.log(richData); } } else { //匹配不到 richData.push(str) } this.setData({ content: richData.map(e => { if (typeof e === "string") { return { type: \'rich\', rich: e } } else return Object.assign(e) }) }) } } })
richtext.wxml
<block wx:for="{{content}}" wx:key="index"> <rich-text wx:if="{{item.type===\'rich\'}}" nodes="{{item.rich}}" /> <video wx:if="{{item.type===\'video\'}}" src="{{item.src}}" style="{{item.style}}" /> <view style="text-align:center" wx:if="{{item.type===\'audio\'}}"> <audio name="{{title}}" author="{{title}}" controls="{{true}}" src="{{item.src}}" style="{{item.style}}" /> </view> </block>
4、效果
请发表评论