Vue自定义指令及实现图片懒加载指令

举报
北极光之夜。 发表于 2021/09/27 16:46:47 2021/09/27
【摘要】 一. 速识概念:  在我们使用 Vue 的过程中,遇到了很多方便我们操作的vue内置指令,以 v-xxx 表示。比如有 v-module,v-for,v-if,v-show 等等,每个指令都能实现一些相对应的功能。但是,在实际的开发过程中,可能这些内置指令并不能满足所有的需求,这时候,就需要用到 Vue 给我们提供的一个强大又灵活的功能「 自定义指令 」。  同样,vue自定义指令可以分为...

一. 速识概念:

  在我们使用 Vue 的过程中,遇到了很多方便我们操作的vue内置指令,以 v-xxx 表示。比如有 v-module,v-for,v-if,v-show 等等,每个指令都能实现一些相对应的功能。但是,在实际的开发过程中,可能这些内置指令并不能满足所有的需求,这时候,就需要用到 Vue 给我们提供的一个强大又灵活的功能「 自定义指令 」。
  同样,vue自定义指令可以分为全局注册指令和局部注册指令。下面我将以最简单的例子带你认识vue自定义指令。

二.全局注册指令:

  比如,我们想要定义一个 v-color=" " 指令 ,标签引用这个指令后可以改变自身背景颜色。一个全局注册指令的基本语法如下:

Vue.directive('color',{
   bind(){},
   inserted(){},
   update(){}, 
   componentUpdated(){},
   unbind()
})

 第一个参数,color 为自定义指令的名称,不用带 v- 。第二个参数为一个对象,其中有5个钩子函数,你可以类似于vue的生命周期钩子函数,它们也是被绑定元素各个周期会触发的钩子函数。每个的执行期间如下:

bind():只调用一次,指令第一次绑定到HTML元素时调用。在这里可以进行一次性的初始化设置。

inserted():当指令绑定的元素插入到父节点中的时候触发。

update():当指令绑定的元素状态/样式、内容(这里指元素绑定的 vue 数据) 发生改变时触发。

componentUpdated():当 update() 执行完毕之后触发。

unbind():只调用一次,指令与元素解绑时调用。

  其实,我们最常用的就是 bind()和 inserted(),也可以理解为在 bind()里设置被绑定元素的css样式,在 inserted()里设置被绑定元素的 js 操作。
 我们的 v-color=" " 指令 ,标签引用这个指令后可以改变自身背景颜色,只定义bind()函数就行,如下:

   <div v-color="'red'">北极光之夜。</div>
-------------------------------------------
    Vue.directive("color", {
        bind(el, binding) {
          console.log(el);
          console.log(binding);
        },
      });

其中,每个钩子函数都有4个参数,我们只讨论 el 和 binding ,打印看看是什么:

在这里插入图片描述
  可以看到,el 就是使用该指令的元素,而binding为一个对象,它保存着很多值,根据vue官方文档,其属性值包括:

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 }。

  那么就很简单了,我们想利用 v-color 自定义指令把背景颜色改为红色可以如下设置:

   <div v-color="'red'">北极光之夜。</div>
-------------------------------------------
    Vue.directive("color", {
        bind(el, binding) {
           el.style.cssText = `background-color:${binding.value}`;
        },
      });

效果成功:
在这里插入图片描述
函数简写形式:
  在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。这时候函数可以简写如下:

      Vue.directive("color", function (el, binding) {
          el.style.cssText = `background-color:${binding.value}`;
      });

三.局部注册指令:

 上面我们定义的全局自定义指令是在Vue实例上定义的,全局可以,如果我只想在某个组件上使用也是可以的,vue组件中规定了directives方法,与data和methods这些同级别,如下:

    <div id="app">
      <div v-color="'red'">北极光之夜。</div>
    </div>
 --------------------------------------
  var app = new Vue({
    el: "#app",
    data: {},
    directives: {
      color: {
        bind(el, binding) {
          el.style.cssText = `background-color:${binding.value}`;
        },
      },
    },
  });

可以看到跟全局也是差不多写法,就是换个位置写而已。

四:图片懒加载:

 我们可以用自定义指令实现图片懒加载。这里只介绍写法,关于图片懒加载原理可以看我另一篇文章,对懒加载原理和原生js实现分析的很全面:前端必会的图片懒加载,你造吗? 。地址 https://auroras.blog.csdn.net/article/details/119789741 看完了再回来看这里就一目了然啦~

 下面将用到 Intersection Observer 观察器接口实现懒加载。

1.建一个HTML单页面,引入vue,然后new一个vue实例,变量moren为图片默认地址,arrSrc数组为图片真实地址:

  var app = new Vue({
        el: "#app",
        data: {
          moren: "img/0.png",
          arrSrc: [
            "img/1.jpg",
            "img/2.jpg",
            "img/3.jpg",
            "img/4.jpg",
            "img/5.jpg",
            "img/6.jpg",
            "img/7.jpg",
            "img/8.jpg",
          ],
        },
      });

2.使用 v-for 渲染 arrSrc 数组,但是图片的src都设为moren:

    <div id="app">
      <div class="container">
        <img
          v-for="(item,index) in arrSrc"
          :key="index"
          :src="moren"
          alt="x"
        />
      </div>
    </div>

此时页面效果如下:

在这里插入图片描述

3.定义 v-lazy = “图片地址” 自定义指令:

<img
  v-for="(item,index) in arrSrc"
  :key="index"
  :src="moren"
  v-lazy="item"
  alt="x"
/>

实现:

  Vue.directive("lazy", {
        inserted(el, binding) {
          //定义一个观察器,entries为状态改变元素的数组
          let observer = new IntersectionObserver((entries) => {
            // 遍历
            for (let i of entries) {
              // 如果改元素处于可视区
              if (i.isIntersecting > 0) {
                // 获取该元素
                let img = i.target;
                // 重新设置src值
                img.src = binding.value;
                //取消对该元素的观察
                observer.unobserve(img);
              }
            }
          });
          // 为 img 标签添加一个观察
          observer.observe(el);
        },
      });

效果,可以看到右边控制台,当图片出现在可视区时才加载:

在这里插入图片描述

五.总结:

  上面就是vue自定义指令的一些简单用法与应用的全部内容啦。总的来说,Vue 给我们提供的一个强大又灵活的功能「 自定义指令 ,可以分为全局注册指令和局部注册指令。全局注册为 Vue.directive(‘name’,{ bind(el,binding){} ,inserted(el,binding){}})。其中,el为该元素,binding为一个对象等等。当然,vue自定义指令肯定没这么简单,在一些复杂用法上是很难的,只能说学无止境了~
  下次见啦~

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。