vue自定义指令

vue自定义指令分为
局部指令
全局指令
一.局部指令的开发
通过dirctives属性配置方式定义多个局部指令,通过key和value的定义来配置指令,局部指令只能在当前定义的vue实例对应的容器使用,如图:
如果多次调用就是多次执行指令
看个小案例,有一个盒子,需要使用指令进行拖拽,如何完成那,详情代码如下
 <style>
      body {
        padding-bottom: 800px;
      }
      .box {
        background-color: brown;
        width: 100px;
        height: 100px;
        border-radius: 6px;
        box-shadow: 0 0 6px #999;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div class="box" v-drag></div>
    </div>
    <script type="module">
      import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
      createApp({
        data() {
          return {};
        },
        directives: {
          // el 参数为自定义指令在页面调用时所对应的vnode生成的DOM元素
          drag(el) {
            el.style.position = "absolute";
            // 绑定鼠标左键按下的事件
            el.onmousedown = function (event) {
              if (event.left != 0) return;
              // 在按下的事件中再次绑定鼠标移动事件
              let ox = event.offsetX;
              let oy = event.offsetY;
              console.log(ox, oy);
              el.onmousemove = function (event) {
                let px = event.pageX;
                let py = event.pageY;
                console.log(px, py);
                el.style.top = py - oy + "px";
                el.style.left = px - ox + "px";
              };
            };
            // 绑定鼠标左键弹起的事件
            el.onmouseup = function () {
              // 在弹起时移除鼠标移动事件
              el.onmousemove = null;
            };
          },
        },
      }).mount("#app");
    </script>

二.全局指令开发
需要由应用程序对象的directive方法来完成自定义指令的描述
app.directive(指令命,指令的回调执行方法)
方法执行,跟局部指令可以比较差别,就可以看出区别,如图
注意:vue3的全局概念与vue2不同,vue3中的全局概念不在同一个环境就都属于vue语法的全局环境,vue3全局指的是由一个createApp作为全局启动代码,完成多个vue实例的加载,此时对于这些vue实例而言全局环境为创建APP
自定义指令的回调形参
       自定义指令如何绑定data数据仓库的数据或者方法,在这里我们试用一下全局指令
     指令定义是直接取值,回调方法相当于同时定义了初始化和变量更新调用两个功能
    app.directive(指令命,指令的回调执行方法)根据全局指令中的binding来回调形参
modifieers
value
vue3中新增数据instance,表示的instance记录的是当前所在的容器对用的vue实例对象
注意如果程序运行中数据发生变化,oldValue也会发生变化
指令上一次=后的取值表达式运行的结果
dir记录的是当前指令被调用时定义的相关的生命周期钩子函数
图片预加载指令
使用全局指令来定义图片预加载
在开展前都必须去判断一下binding.value==binding.oldValue,如果相等即使没有变化,name就直接retuen.不在做处理
创造承载容器
data放图片数据
在vue实例没有被渲染出来时,图片是不能被渲染的,所以我们要在DOM 上有一个可显示的实例,所以使用循环将loading在一开始就加载出来
为了保证顾客的体验在图片没有加载完成前我们需要添加一个loading图片,然后再利用我们图片会被缓存的特性,只要发送请求的地址一致,就从缓存调用图片,完成图片的快速加载.
cssText在style包含了此标签上所有的文本属性
onload表示当前img加载完毕(onload使用在那个元素就表示那个元素的完成)
可以看到下图的样式如果写在全局指令里,就会影响他的样式,因为指令是可以多次调用,但是每个对图片的样式设置是不同的,为了避免这种情况出现,不要在指令里对样式进行处理,而是在行内直接对样式进行添加绑定
骨架屏
上述的loading是老版本使用,现在比较新的是骨架屏,利用CSS样式来完成,可以看一下代码,简单地写了一下样式,可以根据自己所需补充样式,让样式变得更完善
​
<style>
      body {
        padding-bottom: 800px;
      }
      img {
        width: 400px;
        height: 400px;
        border: 1px solid #dedede;
      }
      /* 骨架屏 loading */
      img[v-preload],
      .preload {
        background-color: #dedede;
        background-image: linear-gradient(
          to right,
          rgba(255, 255, 255, 0) 0%,
          rgba(255, 255, 255, 0.8) 10%,
          rgba(255, 255, 255, 0) 20%
        );
        background-size: 230% 100%;
        background-position: 30% 0%;
        animation: skeleton 1.5s infinite;
      }
      @keyframes skeleton {
        0% {
          background-position: 30% 0%;
        }
        100% {
          background-position: -100% 0%;
        }
      }
    </style>
  </head>
  <body>
    <div id="app">
      <img v-preload=" img " style="object-fit: cover" />
    </div>
    <script type="module">
      import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
      const app = createApp({
        data() {
          return {
            img: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1112%2F11251Q24100%2F1Q125124100-5.jpg&refer=http%3A%2F%2Fpic.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1665718104&t=91a061cac8657bf9b1bc3ead30017584",
          };
        },
      });
      app.directive("preload", function (el, binding) {
        if (binding.value == binding.oldValue) return;
        el.classList.add("preload");
        let imgDom = new Image();
        imgDom.src = binding.value;
        imgDom.onload = function () {
          // console.log("图片加载完成");
          el.src = binding.value;
          el.classList.remove("preload");
        };
      });
      app.mount("#app");
    </script>
​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值