腾讯的cherry-markdown如何在vue项目中自定义视频播放器?【引入自定义组件版,非普通html】
调研
好久没给维护的社区增加新内容了,想到社区的播放器还是浏览器原生的,看着挺丑的,因此我打算给社区的cherry-markdown渲染的markdown文章里的视频样式给改改。
首先为了让事情不复杂化,我打算引入西瓜视频播放器(https://h5player.bytedance.com ),它支持的功能挺多的,还能通过插件的形式进行扩展。
我们已经找好播放器了,那么我还得调研下 cherry-markdown如何实现自定义视频播放器的样式,我们第一时间想到的就是去看看它的仓库中的文档描述以及issue里搜索下有没有人提起过,然后其他开发者是如何解决的。
功夫不负有心人,我在issue中搜索“video”后,立马在issue list中看到了一个videonative视频播放器(并且还是close的,看来是已经得到了解决!):https://github.com/Tencent/cherry-markdown/issues/746
我通过这篇issue得知,该markdown在0.8.4之前和之后的实现方案,并且哪个简单和复杂,甚至还贴心的给出了示例,这将大大的提高我的实现速度。那么废话不多说,开始实现。
实现
我为了简单以及看见该markdown项目的发布版本的log来看,修复了挺多内容我就直接将它更新到最新版本,并且编辑和渲染了一篇文章检查了是否影响我以前的功能是否正常使用(防止升级带来明显bug)
首先我们已经从issue中得知如何自定义html:
engine: {
syntax: {
image: {
videoWrapper: (link, type, defaultWrapper) => {
if (type !== 'video')
return defaultWrapper;
return 自己的视频解析(link);
},
},
}
}
只需要return出去你希望的html内容就算是自定义了,但是我要用vue组件实现一些功能啊!怎么办呢?需要让html内容先渲染出来,拿到html再给这返回出去,我们都知道在vue项目的mian.js里我们会通过createApp(component)得到一个vue app,然后我们可以将组件渲染挂在的 el上,得到vm:调用app.mount(el),挂在最终得到vm,可以通过vm得到最终渲染好的html!它也带有vue的任何能力!但是如果我们的component有用到ui库呢?那需要用这个app.use一下它哦!具体代码如下:
const renderComponentToHTML = (component, props) => {
// 创建一个临时 DOM 元素用于挂载
const container = document.createElement('div');
// 创建 Vue 应用实例
const app = createApp(component, props);
app.use(PrimeVue, { ripple: true })
// 手动挂载到临时容器
const vm = app.mount(container);
// 获取生成的 HTML
const html = container.innerHTML;
// 清空临时容器
container.innerHTML = '';
return html;
}
那么我们将两个代码合并,最终形成这样的效果:
engine: {
syntax: {
image: {
videoWrapper: (link, type, defaultWrapper) => {
if (type !== 'video')
return defaultWrapper; // 默认播放器(原生的:video)
return renderComponentToHTML(MyVideoCom, {url: link}); // 渲染我自己写的vue组件,还能传入props
},
},
}
}
最终挂载成功效果: