有关vue的自定义指令
介绍
对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小,
而代码也许就只有几十KB。当页面图片很多时,页面的加载速度缓慢,
几S钟内页面没有加载完成,也许会失去很多的用户。
所以,对于图片过多的页面,为了加速页面加载速度,所以很多时候我们
需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区
域后再去加载。这样子对于页面加载性能上会有很大的提升,也提高了用户体验。
原理
页面加载时将img标签中的src属性指向一张默认图片或者指向空并且设置高度,
然后定义data-src属性指向真实的图片地址。
例如: <img src="default.jpg" data-src="http://xxxxx.jpg" />
对屏幕滚动事件进行监听,判断哪些图片是暴露在视野里的将图片的src指向
原来data-src指向的图片地址,就能实现简单的图片懒加载了
vue-lazyload实现
- index.js
1 | /* |
- lazy.js
先看构造函数
1 | constructor ({ preLoad, error, throttleWait, preLoadTop, dispatchEvent, loading, attempt, silent = true, scale, listenEvents, hasbind, filter, adapter, observer, observerOptions }) { |
_lazyLoadHandler
1 | /* |
那么问题来了,这个listener到底是何方神圣呢?
在解释这个问题之前我们先看看setMode做了什么事情 这牵扯到另一个核心代码
setMode
1 | /* |
_initIntersectionObserver
See: [http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34/*
* 为每个绑定指令并且选择了observer模式的节点绑定状态监听事件 并使用_observerHandler作为监听回调
* 这里涉及到IntersectionObserver Api
* 作者对此api做了浏览器兼容判断 并将isIntersecting这个属性与intersectionRatio做了代理
* 个人猜测isIntersecting更好理解吧
*/
_initIntersectionObserver () {
if (!hasIntersectionObserver) return
this._observer = new IntersectionObserver(this._observerHandler.bind(this), this.options.observerOptions)
if (this.ListenerQueue.length) {
this.ListenerQueue.forEach(listener => {
this._observer.observe(listener.el)
})
}
}
/*
* entries表示的是被检测到发生可见性变化的节点 可能会有多个
*/
_observerHandler (entries, observer) {
entries.forEach(entry => {
// 如果节点在页面存在可见部分
if (entry.isIntersecting) {
this.ListenerQueue.forEach(listener => {
// 找到目标节点
if (listener.el === entry.target) {
// 如果图片已经加载 取消对改节点的监听
if (listener.state.loaded) return this._observer.unobserve(listener.el)
// 加载图片
listener.load()
}
})
}
})
}
下面就看看指令周期内的做了什么? 上代码!!!
1 | Vue.directive('lazy', { |
lazy.add
1 | /* |
ReactiveListener
1 | /* |
lazy._elRenderer
1 | _elRenderer (listener, state, cache) { |
lazy._addListenerTarget
1 | /* |
小结
本章重点主要是在对于Lazy类的解读,作者实现的思路极为巧妙,而且将dom操作的逻辑和状态更新的逻辑拆开,很直观,
而且涉及到很多浏览器兼容性的处理考虑的比较全面,还是很值得学习的.