实现一个简单的 vue 无限加载指令
vue 中的自定义指令是对底层 dom 进行操作,下面以实现滚动到底部加载数据,实现无限加载来介绍如何自定义一个简单的指令。
无限加载的原理是通过对滚动事件对监听,每一次滚动都要获取到已滚动到距离,如果滚动的距离加上浏览器窗口高度,会大于等于内容高度,就触发函数加载数据。
vue 中的自定义指令是对底层 dom 进行操作,下面以实现滚动到底部加载数据,实现无限加载来介绍如何自定义一个简单的指令。
无限加载的原理是通过对滚动事件对监听,每一次滚动都要获取到已滚动到距离,如果滚动的距离加上浏览器窗口高度,会大于等于内容高度,就触发函数加载数据。
在Vue.js中,数据的变化会引起 DOM 的改变,是否能理解为 DOM 订阅了数据的改变事件,每当数据改变时,就发布广播,DOM 得以知道数据改变?
具体如何实现呢?尝试以自己对数据绑定的理解,先实现一个“看起来”能够监听数据的实例,而不是一开始就阅读 Vue 的源码(不过如果没先阅读过,也不知道自己看不懂…),再将该实例进行优化。
虽然不直接阅读源码,但首先需要对 Vue 的使用方式了解。
数据绑定的功能基本实现了,但也很明显存在很多问题,
首先,第一个问题,现在是将属性名作为了事件名来实现数据的监听,假设存在name
和person.name
,我们是将name
传入渲染函数,对节点遍历查找“指令的值”,将其与name
进行对比,符合就是找到了,但是很明显'person.name' !== 'name'
,所以无法实现双向绑定;第二个问题当然是数组类型的处理;
参考 Vue 源码(v0.10)来解决这些问题。
之前代码存在很多问题,最大的问题是,实现的并不是一个严格意义上的观察者模式(发布-订阅模式),因为默认订阅了所有数据,且不能取消订阅。
在《JavaScript设计模式与开发实践》中,使用售楼处的例子来类比观察者模式:
售楼处属于发布者,小明(需要购房的人)是订阅者,小明向售楼处订阅了房子开售的信息,售楼处就把小明的信息写入记录表,当房子开售时,售楼处遍历记录表通知到小明(和其他记录表上的人)。
把这个例子和 vue 的实现类比:
创建实例时,发布者(售楼处)会把渲染函数(购房者)添加到发布列表(记录表)中,数据变化(房子开售)时,发布者(售楼处)会调用渲染函数(通知购房者)。
而且不同的数据可以类比于不同户型的房子。不同的数据(不同户型的房子)改变(发售)时,可以通知不同的渲染函数(购买者)。