图片懒加载
-
-
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind:只调用一次,指令与元素解绑时调用。
-
指令钩子函数会被传入以下参数:
el:指令所绑定的元素,可以用来直接操作 DOM。binding:一个对象,包含以下 property:name:指令名,不包括v-前缀。value:指令的绑定值,例如:v-my-directive="1 + 1"中,绑定值为2。oldValue:指令绑定的前一个值,仅在update和componentUpdated钩子中可用。无论值是否改变都可用。expression:字符串形式的指令表达式。例如v-my-directive="1 + 1"中,表达式为"1 + 1"。arg:传给指令的参数,可选。例如v-my-directive:foo中,参数为"foo"。modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar中,修饰符对象为{ foo: true, bar: true }。
vnode:Vue 编译生成的虚拟节点。oldVnode:上一个虚拟节点,仅在update和componentUpdated钩子中可用。
-
除了
el之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的dataset来进行。
-
-
// 全局注册 Vue.directive('lazyload', { bind: function (el, binding) { console.log(el,binding); let lazyImageObserve = new IntersectionObserver((entries, observer) => { entries.forEach((entry, index) => { let lazyImage = entry.target if (entry.isIntersecting) { setTimeout(() => { lazyImage.src = binding.value lazyImageObserve.unobserve(lazyImage) },1000) } }) }) lazyImageObserve.observe(el) } }) -
// 局部注册 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <!-- 引入vue文件 --> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <style> [v-clock] { display: none; } .container { width: 80%; margin: 0 auto; } img { height: 300px; width: 100%; } </style> </head> <body> <div v-clock id="box"> <h3 style="text-align: center;">{{title}}</h3> <p class="container" v-for="item in imgs"> <img v-lazyload="item"> </p> </div> <script> // 全局注册 // Vue.directive('lazyload', { // bind: function (el, binding) { // console.log(el,binding); // let lazyImageObserve = new IntersectionObserver((entries, observer) => { // entries.forEach((entry, index) => { // let lazyImage = entry.target // if (entry.isIntersecting) { // setTimeout(() => { // lazyImage.src = binding.value // lazyImageObserve.unobserve(lazyImage) // },1000) // } // }) // }) // lazyImageObserve.observe(el) // } // }) const vm = new Vue({ // 挂载元素 el: '#box', // 局部注册 directives: { lazyload: { bind: function (el, binding) { let lazyImageObserve = new IntersectionObserver((entries, observer) => { entries.forEach((entry, index) => { let lazyImage = entry.target if (entry.isIntersecting) { lazyImage.src = binding.value lazyImageObserve.unobserve(lazyImage) } }) }) lazyImageObserve.observe(el) } } }, data: { title: '我的图片', imgs: [] }, created() { this.getImage() }, methods: { getImage() { // 模拟数据请求 new Promise((resolve, reject) => { setTimeout(() => { resolve([ './img/微信图片_1.jpg', './img/微信图片_2.jpg', './img/微信图片_3.jpg', './img/微信图片_4.jpg', './img/微信图片_5.jpg', './img/微信图片_6.jpg', './img/微信图片_7.jpg', './img/微信图片_8.jpg', './img/微信图片_9.jpg', ]) }, 1000) }).then(res => { this.imgs = res }) } } }) </script> </body> </html>