官网后台又加一个新需求 - 上传视频,那就接上一篇的接着说,在 Vue 中使用 Tinymce 富文本编辑器 + 上传图片到七牛
效果图如下
首先确保引入了media插件
import 'tinymce/plugins/media'
在init数据源中添加media以及处理函数
data() {
return {
qnToken: '',
mediaUploaded: false, //有没有上传完成
resVideo: '', //返回的视频url
init: {
plugins: 'media',
toolbar: 'media',
//文件选择器的使用场景,参数可为media(媒体)、image(图片)、file(文件)
file_picker_types: 'media',
//文件上传回调
file_picker_callback: (cb, value, meta) => {
if (meta.filetype == 'media') {
let input = document.createElement('input') //创建一个隐藏的input
input.setAttribute('type', 'file')
let that = this
input.onchange = function () {
let file = this.files[0] //选取第一个文件
that.meidaUpload(file) // 下文的方法,上传到七牛拿到url
console.log(that.resVideo)
if (that.mediaUploaded) {
cb(`你的CDN地址/${that.resVideo}`) //将url显示在弹框输入框中
} else {
setTimeout(() => {
cb(`你的CDN地址/${that.resVideo}`)
}, 2000)
}
}
//触发点击
input.click()
}
}
}
}
},
接下来是上传七牛获得视频地址的方法,和上一篇上传图片大同小异。
methods: {
meidaUpload(file) {
const axiosInstance = axios.create({ withCredentials: false }) //withCredentials 禁止携带cookie,带cookie在七牛上有可能出现跨域问题
let data = new FormData()
data.append('token', this.qnToken) //七牛需要的token,叫后台给,是七牛账号密码等组成的hash
data.append('file', file)
axiosInstance({
method: 'POST',
url: 'https://up-z1.qiniup.com', //上传地址,根据情况自行更换
data: data,
headers: {
// 修改请求头
"Content-Type": "multipart/form-data"
},
timeout: 30000, //超时时间,因为图片上传有可能需要很久
})
.then((res) => {
this.mediaUploaded = true // 标记为上传成功
this.resVideo = res.data.key //设置七牛返回的key
})
.catch(function (err) {
//上传失败
console.log(err)
})
},
}
到此,上传应该没问题了。但是在编辑器中显示的如下(WTF),哈哈哈哈哈哈。。。
网上有不少解决的办法,改源码的,自定义上传方法的……看起来挺复杂,直接上我觉得最简单的一个,亲测有效!
在init数据中添加以下代码。
//自定义逻辑替换 Tinymce 的默认媒体嵌入逻辑
media_url_resolver: function (data, resolve) {
try {
let videoUri = encodeURI(data.url);
let embedHtml = `<p>
<span
class="mce-object mce-object-video"
data-mce-selected="1"
data-mce-object="video"
data-mce-p-width="100%"
data-mce-p-height="auto"
data-mce-p-controls="controls"
data-mce-p-controlslist="nodownload"
data-mce-p-allowfullscreen="true"
data-mce-p-src=${videoUri} >
<video src=${data.url} width="100%" height="auto" controls="controls" controlslist="nodownload">
</video>
</span>
</p>
<p style="text-align: left;"></p>`;
resolve({ html: embedHtml });
} catch (e) {
resolve({ html: "" });
}
}
大功告成O(∩_∩)O