Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍。以下将详细介绍如何实现自定义指令v-lazyload。
先看如何使用这个指令:
1
|
<img v-lazyload= "imageSrc" >
|
imageSrc是要加载的图片的实际路径。
为了实现这个指令,我们首先单独建立一个文件,名字为lazyload.js.并填写基本的代码,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
export default (Vue , options = {})=>{
var init = {
}
const addListenner = (ele,binding) =>{
}
Vue.directive( 'lazyload' ,{
inserted:addListener,
updated:addListener
})
}
|
inserted 和 updated为Vue指令的执行不同阶段提供的钩子函数,查看Vue的官网可以看到一共有5个阶段,
指令定义函数提供了几个钩子函数(可选):
bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
unbind: 只调用一次, 指令与元素解绑时调用。
这里我们只用inserted和updated就够了。
接下来我们具体实现addListener的实现。我们的具体思路如下:
1、先看看这个图片是否需要懒加载。有两种情况,一是图片还没到达可视区域,二是图片已经加载过了。
2、然后监听窗口的scroll事件,判断哪些图片可以进行懒加载了。
这里我们需要一个需要进行监听需要懒加载的图片列表和一个需要记录已经加载过得图片列表。另外为了方便数组的操作,我们加一个数组的remove方法。
继续我们的代码。
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
export default (Vue , options = {})=>{
if (!Array.prototype.remove){
Array.prototype.remove = function (item){
if (! this .length) return
var index = this .indexOf(item);
if ( index > -1){
this .splice(index,1);
return this
}
}
}
var init = {
}
var listenList = [];
var imageCatcheList = [];
const isAlredyLoad = (imageSrc) => {
}
const isCanShow = (item) =>{
};
const onListenScroll = () =>{
}
const addListener = (ele,binding) =>{
var imageSrc = binding.value;
if (isAlredyLoad(imageSrc)){
ele.src = imageSrc;
return false ;
}
var item = {
ele:ele,
src:imageSrc
}
ele.src = init. default ;
if (isCanShow(item)){
return
}
listenList.push(item);
onListenScroll();
}
Vue.directive( 'lazyload' ,{
inserted:addListener,
updated:addListener
})
}
|
接下来就几个空方法的实现了。
isAlredyLoad ,判断是否已经加载过了这个图片
1
2
3
4
5
6
7
|
const isAlredyLoad = (imageSrc) => {
if (imageCatcheList.indexOf(imageSrc) > -1){
return true ;
} else {
return false ;
}
}
|
isCanShow 图片是否进入可视区域,如果已经进入则进行加载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
const isCanShow = (item) =>{
var ele = item.ele;
var src = item.src;
var top = ele.getBoundingClientRect().top;
var windowHeight = window.innerHight;
if (top + 10 < window.innerHeight){
var image = new Image();
image.src = src;
image.onload = function (){
ele.src = src;
imageCatcheList.push(src);
listenList.remove(item);
}
return true ;
} else {
return false ;
}
};
|
onListenScroll监听滚动事件,并且检测是否进入可视区域。
1
2
3
4
5
6
7
8
|
const onListenScroll = () =>{
window.addEventListener( 'scroll' , function (){
var length = listenList.length;
for (let i = 0;i<length;i++ ){
isCanShow(listenList[i]);
}
})
}
|
最终我们的代码如下:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
export default (Vue , options = {})=>{
if (!Array.prototype.remove){
Array.prototype.remove = function (item){
if (! this .length) return
var index = this .indexOf(item);
if ( index > -1){
this .splice(index,1);
return this
}
}
}
var init = {
lazyLoad: false ,
}
var listenList = [];
var imageCatcheList = [];
const isAlredyLoad = (imageSrc) => {
if (imageCatcheList.indexOf(imageSrc) > -1){
return true ;
} else {
return false ;
}
}
const isCanShow = (item) =>{
var ele = item.ele;
var src = item.src;
var top = ele.getBoundingClientRect().top;
var windowHeight = window.innerHight;
if (top + 10 < window.innerHeight){
var image = new Image();
image.src = src;
image.onload = function (){
ele.src = src;
imageCatcheList.push(src);
listenList.remove(item);
}
return true ;
} else {
return false ;
}
};
const onListenScroll = () =>{
window.addEventListener( 'scroll' , function (){
var length = listenList.length;
for (let i = 0;i<length;i++ ){
isCanShow(listenList[i]);
}
})
}
const addListener = (ele,binding) =>{
var imageSrc = binding.value;
if (isAlredyLoad(imageSrc)){
ele.src = imageSrc;
return false ;
}
var item = {
ele:ele,
src:imageSrc
}
ele.src = init. default ;
if (isCanShow(item)){
return
}
listenList.push(item);
onListenScroll();
}
Vue.directive( 'lazyload' ,{
inserted:addListener,
updated:addListener
})
}
|
使用时需要在主文件中引入这个文件,并且vue.use();
1
2
|
import LazyLoad from 'lazyLoad.js'
Vue.use(LazyLoad);
|
并且在需要懒加载的图片上均按照如下使用v-lazyload指令即可
<img v-lazyload="imageSrc" >
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关推荐
在vue中使用图片懒加载详细指南,分享给大家。具体如下: 说明 当网络请求比较慢的时候,提前给这张图片添加一个像素比较低的占位图片,不至于堆叠在一块,或显示大片空白,让用户体验更好一点。 使用方式 使用vue...
vue中封装自定义指令,该指令主要功能是到达指定区域加载图片,若已加载过就不再加载
前端项目-vue-lazyload,用于在Vue.js应用程序中延迟加载图像的Vue模块。
一个组件实现lazyload图片当在视窗内(或附近)时才加载
$ npm i vue-lazyload -S CDN CDN: : < script src =" https://unpkg.com/vue-lazyload/vue-lazyload.js " > </ script > < script > Vue . use ( VueLazyload ) . . . </ script > ...
vue-lazyload, 在你的应用程序中,你的图像或者组件的一个 Vue.js 插件 lazyload 用于应用程序中lazyloading图像的Vue模块。 这个项目的一些目标值得注意:轻巧,功能强大,易于使用处理任何图像类型加载图像时添加...
图片懒加载插件 Vue-Lazyload,现在支持 Vue2.0
本文介绍了浅谈vue-lazyload实现的详细过程,分享给大家,也给自己留个笔记 首先 ,在命令行输入npm install vue-lazyload&&cnpm install vue-lazyload 然后,在main.js里引入这个模块。 import 'VueLazyload' from ...
vue-l-lazyload Vue.js v2.x +的惰性加载和视图内检测插件。 演示版 或npm install vue-l-lazyload && npm run startDev进行播放! 拉请求是受欢迎的:) 执照 LGPL-V3 特征 除了Vue外,没有其他依赖项 渐进式配置 ...
ue vue-tiny-lazyload-img一个小尺寸的Vue.js指令,用于使用IntersectionObserver API演示页延迟加载图像https://mazipan.github.io/vue-:snail:vue-tiny-lazyload-img一个小尺寸的Vue.js使用IntersectionObserver ...
Vue自定义v-has指令实现按钮权限判断 以后台管理系统为例,每个用户所拥有的按钮权限不一样。管理员配置权限之后,用户登录时,从接口拿到按钮权限列表,然后根据后台数据判断显示哪些按钮。 简单说一下,自定义...
查阅资料后发现Vue-Lazyload这个插件用的频率还是比较高,最近刚好也在研究vue的懒加载,顺便也仔细研究了以下这个插件,这个插件确实能够实现懒加载,但是坑也有不少,今天就一起来看看Vue-Lazyload。 Vue-Lazyload...
适用于vanilla-lazyload的lazyload-vue Vue插件构建状态:功能可与v-lazy-src轻松使用接受选项Vue.use(LazyloadVue,options)适用于vanilla-lazyload的Multipl lazyload-vue Vue插件构建状态:功能可与v-lazy轻松...
vue自定义指令--实现div和图片的拖拽,放大,缩小,已封装成组件,下来导入后可直接使用
vue中的指令就是v-on v-bind v-show等等,那么自定义指令是什么呢? 自己定义的指令就是自定义指令。 语法: Vue.directive(id, definition) 这里可以参考vue中的指令 <h1 v-if=”yes”>Yes</h1> 其中,if就是指令ID...
1、首先在npm上下载vue-lazyload的引用包 npm install vue-lazyload --save-dev 2、然后我们在main.js里面import这个包,当然,单单这一个包是不够的,还得其他的文件 import Vue from 'vue'; import App from './...
Vue-Lazyload Vue模块,用于在应用程序中延迟加载图像。 该项目的一些目标值得注意:•重量轻,功能强大且Vue-Lazyload Vue模块用于在应用程序中延迟加载图像。 该项目的一些目标值得注意:重量轻,功能强大且易于...