公司有个新项目由我这边独立选型开发,项目需求是做一个英文的产品展示官网,考虑到项目比较简单且周期不长,最终决定使用 Nuxt 框架来进行开发。

开发过程还算顺利,但中途遇到一个 Bug 花了我不少的时间,在网上找了许久,仅能检索到极少数相关内容,都是在 Vue 的 Github 仓库中的 issues,且最终仍未能够找到问题所在,当然这也许并不是 Bug,而是框架本身设计的就是这样。

以下是我的解决思路,如果各位大佬有别的见解,请指出交流。

问题现象

在产品展示的官网首页有一个全屏的 video 元素,视频默认自动播放,在大多数现代化浏览器的最新版本中,要实现这个功能,需要在 video 元素中加入 autoplay 属性,且还需要设置一个 muted 属性用于默认静音播放。

可以看到在第一次页面加载时是正常自动播放的,且此时 DOM 结构跟在 Vue 模板里写的代码是一样的。

这时候切换一下路由到产品页面,再切回首页时就出现了问题,原来 video 元素中的 muted 莫名其妙的消失了,导致视频自动播放也随之失效。

问题分析

起初我以为是 Nuxt 路由切换的问题,测试了使用 Nuxt 提供的 navigateTo() 方法和 Vue 路由提供的 $router.push() 方法,均存在该问题。

第二次测试了给页面设置 keepalive: true 来实现路由缓存,但仍未解决该问题,且因此引出了其他的 Bug,没往其深究所以暂且按下不表。

第三次测试了给 video 元素通过 v-bind 去动态绑定 muted 属性,不管是通过 ref 定义的值还是直接绑定 :muted="true",均未能解决问题。

我开始怀疑是不是 Nuxt 的问题,于是我第四次使用另一个纯 Vue 的项目做了测试。得出结果首次加载就失去了 muted 属性,但诡异的是视频仍可以实现自动播放,这个奇怪的问题逐渐变得扑朔迷离。

最终在 Vue 的 Github 仓库中找到了一个还未解决的 issues,遇到了跟我一样的问题。

这是一个在 2022 年 10 月 12 日创建的 issues,至今为止仍未关闭。值得一提的是,底下有一条回复指出「Vue 不应该真的破坏原生浏览器功能」,但可能这确实是 Vue.js 的 Bug。

问题解决

最终我不再去纠结问题所在,开始着手准备解决方案。既然通过动态绑定属性不能解决问题,那就只能使用最原始的方案了,通过操作 DOM 去出发元素的播放事件。

在 Vue 挂载完成之后,通过 document.getElementsByTagName('video') 去拿到首页的所有视频元素,再依次触发播放事件,如此就能够在切换路由再切回首页时,视频仍能够保持自动播放。

尽管如此可以简单的解决问题,但感觉这并不是最终的解决方案,其问题核心应该还是出现在框架上,希望能够有大佬能深入研究一下,也能给我指点一二。

如果觉得我的文章对你有用,请随意赞赏