由于富文本编辑器的视频上传组件需要自定义,下面先定义富文本组件中的视频上传
富文本编辑器使用
html部分
<div>
<el-upload
:action="uploadImgUrl"
:before-upload="handleBeforeUpload"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
name="file"
:show-file-list="false"
:headers="headers"
style="display: none"
ref="upload"
v-if="this.type == 'url'"
>
</el-upload>
<div class="editor" ref="editor" :style="styles" @paste="onPaste($event)"></div>
<!-- 自定义视频上传 -->
<el-dialog :close-on-click-modal="false" width="50%" style="margin-top: 1px" title="视频上传"
:visible.sync="videoForm.show" append-to-body
>
<el-tabs v-model="videoForm.activeName">
<el-tab-pane label="添加视频链接" name="first">
<el-input v-model="videoForm.videoLink" placeholder="请输入视频链接" clearable></el-input>
<el-button type="primary" size="small" style="margin: 20px 0px 0px 0px "
@click="insertVideoLink(videoForm.videoLink)"
>确认
</el-button>
</el-tab-pane>
<el-tab-pane label="本地视频上传" name="second">
<el-upload v-loading="loading" style="text-align: center;" drag :action="uploadVideoConfig.uploadUrl"
accept="video/*" :name="uploadVideoConfig.name" :headers="headers"
name="file"
:before-upload="onBeforeUploadVideo"
:on-success="onSuccessVideo" :on-error="onErrorVideo" :multiple="false"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传MP4文件,且不超过{{ uploadVideoConfig.maxSize }}M</div>
</el-upload>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
可以在data中声明富文本配置项,后续方便初始化富文本组件
options: {
theme: 'snow',
bounds: document.body,
debug: 'warn',
modules: {
// 工具栏配置
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
['blockquote', 'code-block'], // 引用 代码块
[{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
[{ indent: '-1' }, { indent: '+1' }], // 缩进
[{ size: ['small', false, 'large', 'huge'] }], // 字体大小
[{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
[{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
[{ align: [] }], // 对齐方式
['clean'], // 清除文本格式
['link', 'image', 'video'] // 链接、图片、视频
],
handlers: {
'video': () => {
// 覆盖默认的上传视频,点击视频图标,显示弹窗
_self.videoForm.show = true
this.range = this.$refs.editor.quill.selection.savedRange.index
},
'image': (value) => {
document.querySelector('.avatar-uploader input').click()
this.range = this.$refs.editor.quill.selection.savedRange.index
}
}
}
},
placeholder: '请输入内容',
readOnly: this.readOnly
},
初始化组件
init() {
const editor = this.$refs.editor
this.Quill = new Quill(editor, this.options)
// 如果设置了上传地址则自定义图片上传事件
let toolbar = this.Quill.getModule('toolbar')
toolbar.addHandler('video', () => {
// 覆盖默认的上传视频,点击视频图标,显示弹窗
this.videoForm.show = true
this.range = this.Quill.getSelection().index
})
if (this.type == 'url') {
toolbar.addHandler('image', (value) => {
if (value) {
this.$refs.upload.$children[0].$refs.input.click()
} else {
this.quill.format('image', false)
}
})
}
this.Quill.pasteHTML(this.currentValue)
this.Quill.on('text-change', (delta, oldDelta, source) => {
const html = this.$refs.editor.children[0].innerHTML
const text = this.Quill.getText()
const quill = this.Quill
this.currentValue = html
this.$emit('input', html)
this.$emit('on-change', { html, text, quill })
})
this.Quill.on('text-change', (delta, oldDelta, source) => {
this.$emit('on-text-change', delta, oldDelta, source)
})
this.Quill.on('selection-change', (range, oldRange, source) => {
this.$emit('on-selection-change', range, oldRange, source)
})
this.Quill.on('editor-change', (eventName, ...args) => {
this.$emit('on-editor-change', eventName, ...args)
})
},
自定义视频上传方法
insertVideoLink(videoLink) {
if (!videoLink) return this.$message.error('视频地址不能为空!')
this.videoForm.show = false
let quill = this.Quill
// 获取富文本
let range = quill.getSelection()
// 获取光标位置:当编辑器中没有输入文本时,这里获取到的 range 为 null
let index = range ? range.index : this.range
// 在光标所在位置 插入视频
quill.insertEmbed(index, 'video', videoLink)
// 调整光标到最后
quill.setSelection(index + 1)
},
// el-文件上传组件
onBeforeUploadVideo(file) {
this.loading = true
let acceptArr = ['video/mp4']
const isVideo = acceptArr.includes(file.type)
const isLt1M = file.size / 1024 / 1024 < this.uploadVideoConfig.maxSize
if (!isVideo) {
this.hideLoading()
this.$message.error('只能上传mp4格式文件!')
}
if (!isLt1M) {
this.hideLoading()
this.$message.error(`上传文件大小不能超过 ${this.uploadVideoConfig.maxSize}MB!`)
}
return isLt1M && isVideo
},
// 文件上传成功时的钩子
onSuccessVideo(res) {
this.hideLoading()
if (res.code === 200) {
this.insertVideoLink(res.data.url)
} else {
this.$message.error(res.msg)
}
},
// 文件上传失败时的钩子
onErrorVideo() {
this.hideLoading()
this.$message.error('上传失败')
}
需要注意的是当点击上传视频时,光标会失去焦点,所以在视频上传完毕后回显到富文本中时需要获取插入的光标
uni中使用mp-html组件,且需要对富文本内容进行处理
info= info.replace(/<iframe[^>]*src=["']([^"']*)["'][^>]*>/g,
'<video src="$1" autoplay style="height: 200px;width:100%" > '
);
const reg = new RegExp('</iframe>', "g")
info = info.replace(reg,'</video>');