4月24日开始接触Vue这个前端框架,看了一天的官方文档后开始找一个项目的视频看了4天,对于Vue的组件化开发有了一个初步的认识,也理解了MVVM的思想。我觉得Vue框架的特点就是数据驱动,把对DOM的操作放到了他已经封装好的一些代码中,对用户来说是透明的。下面我说下我在做弹幕功能上踩到的坑。
弹幕思路分析
当有新的消息提交时,生成一个div然后设置这个div的position属性为absolute,这个就可以通过left属性控制div的位置了,然后循环设置div的位置左移直到边界最右边,这样就实现了弹幕。
这是单个弹幕的实现,然后还需要有一个弹幕wrap来承载这些弹幕,充当一个弹幕的控制器。所以我的结构逻辑是这样的:

我在wrap里面维护了一个弹幕数组,当某个弹幕移动到了终点(左边界),则在数组中移除这个弹幕,Vue框架是数据驱动的,所以会自动删除这个DOM,如果要是自己用js或者jq写的话,就需要把这个dom的删除也显式的写出来,比如这样:
Element.remove();
但是如果使用的是vuejs,我们就不需要关注DOM的操作,完全考虑这个DOM绑定到的数据上,然后通过改变数据,自动改变DOM表示,这就是MVVM的思路。
扯远了,现在说说弹幕的弹道参数,所谓弹道就是弹幕在wrap上的滚动轨道,这个接触过弹幕的应该不难理解,如果所有的弹幕在一行上显示肯定会很乱。我的思路就是维护一个弹道的数组,然后获取一个有上下值得随机数,并把随机数的值,从弹道数组中取出,当弹幕完全进入到wrap的右边界时,产生一个事件通知父元素,然后再把这个弹道的值push进弹道数组,实现一个弹道开闭的功能。
“就地复用”坑
在开发过程中遇到了一个关于vue渲染DOM“就地复用”机制的坑,这个在官方文档中也有讲解,可能乍一看不是太清楚,不过只要自己动手写一下就能了解。
这个机制大致的坑是这样的:
如果用v-for执行循环渲染了div#a和div#b两个div,如果div#a因为绑定的数据删除从而引起div#a删除,div#b重新渲染来更新循序,但是他是直接把div#b的值绑定到了div#a上,这就是所谓的就地复用,这种机制虽然能够减少修改dom的消耗,但是有时会引起不预期的结果,比如这个弹幕这块,如果删除了a,b也会因为位置改变从而删除掉,不是我们想要的。
解决办法
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
注意这个item.id一定是不变的并且和别的不同,下面的代码是错误的演示
<div v-for="(item,index) in items" :key="index"> //index是变化的,所以错误
<!-- 内容 -->
</div>
总结
所以这里面的点是绑定数组生成一个一个的item DOM,然后有一个父子组件的通讯功能,父组件可以监听子组件的事件,实现这点,还有就是判定弹幕移动的状态(“未进入”,“已进入”,“已退出”),大致是这样能实现最基本的一个弹幕功能,当然还有很多待优化的点,比如不同随机数设置弹道,优先使用上方的弹道,设置弹幕的颜色不同等等,以后我会一一优化,不过目前我打算先学习下vuex,实现线上通讯的弹幕系统。
本博客没贴代码,一是因为代码还很多别的博客上都有分享,第二个是我的代码在github上(手动滑稽)
欢迎学前端的朋友一起交流。里面有什么讲的不清楚的地方也可以告诉我,我会改进的。
