騰訊的cherry-markdown如何在vue專案中自定義影片播放器?【引入自定義元件版,非普通html】

LiusCraft發表於2024-08-04

調研

  好久沒給維護的社群增加新內容了,想到社群的播放器還是瀏覽器原生的,看著挺醜的,因此我打算給社群的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
        },
      },
  }
}

最終掛載成功效果:
image

相關文章