查了很多文章,凡在vue项目中引入video.js插件,
都会出现视频播放器中间出现一个大叉号导致视频无法播放,同时控制台出现no compatible source was found for this media的错误提醒的情况,
究竟是什么原因呢?
翻译过来是找不到匹配媒体资源:
no compatible source was found for this media 该媒体没有找到兼容的源代码。
有网友提出是因为chrome禁止了flash的加载,,只需把flash选项更改为‘允许’即可。
操作如下:
然而,我依照网友的建议,依然无效,报错情况涛声依旧。
那到底是什么情况!!!
请来大神,发出“解决不了就吃屎”的毒誓,终于搞定了这个问题!
其实解决方法很简单:Vue.nextTick()
如果不引入video.js,那么视图更新迅速,DOM元素解析和异步数据获取之后,视图就可以即时得到更新;然而由于插件video.js的运行机制,导致在获取数据之后,视图也无法得以快速更新,那么按照传统的做法,即使在mounted中调用了对videojs的初始化函数,依然出现后台提示获取不到数据的情况。
这时候$nextTick就发挥了功能。
Vue.nextTick()是在下次 DOM 更新循环结束之后延迟执行的回调函数,
在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
(dom的改变是发生在nextTick()之后)
这个方法作用是当数据被修改后,使用该回调方法获取更新后的dom并再次render出来
Vue.nextTick()作用:
在下次dom更新循环结束之后执行延迟回调。
在修改数据之后立即使用这个方法,获得更新后的dom。
搬出Vue官方文档:
Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部对异步队列尝试使用原生的
Promise.then
、MutationObserver
和setImmediate
,如果执行环境不支持,则会采用setTimeout(fn, 0)
代替。
我表示这一段看不懂。
例如,当你设置
vm.someData = 'new value'
,该组件不会立即重新渲染。当刷新队列时,组件会在事件循环队列清空时的下一个“tick”更新。多数情况我们不需要关心这个过程,但是如果你想在 DOM 状态更新后做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用Vue.nextTick(callback)
。这样回调函数在 DOM 更新完成后就会调用。
在DOM状态更新后,立即使用Vue.nextTick(callback)的回调,促使数据再次更新,得到DOM的再次渲染。
是否可以直白点说:Vue.nextTick(callback)
使得数据再次驱动,最终让DOM的得到再次渲染呢?
好了,反反复复说这么多,具体我的项目中是这样使用的。
这是组件的DOM结构部分:
其中有两处数据绑定,分别是poster和视频来源src,
因为使用了video.js,导致这两处需要数据的再次异步更新,而这两处也正是Vue.nextTick(callback)回调函数的中心任务。
就是这么一个回调函数,终于解决了vue项目中后台不断提醒找不到匹配的媒体资源的问题。
小小的总结一下,数据驱动视图更新,第一次获取数据,使得页面内容整体得到渲染,而数据变化之后的瞬间,立即调用Vue.nextTick(callback),得以视频部分获取属于其自己的数据并迅速渲染更新。这样我的页面就完整啦!
参考文章:
https://www.jianshu.com/p/a7550c0e164f