自定义指令:自定义指令就是自己创建一个指令,有时候vue提供的指令,不能满足我们的需求,刚好vue提供了允许我们自己注册自定义指令,所有我们就自己创建一个了指令,这个就是自定义指令。写法:v-指令名称。

创建自定义指令分别有全部注册 和 局部注册。通过创建好的自定义指令实现:

  • 操作DOM:可以直接对 DOM 元素进行操作,比如修改样式、添加事件监听器
  • 数据绑定:让数据和 DOM 元素实现双向绑定
  • 表单校验:对表单进行验证,比如自定义输入框格式、校验规则等
  • 代码复用:将一些常用的操作封装成指令,提到代码的复用性
  • 按钮权限:根据不同的用户权限,显示不同的按钮 比如管理员具有增删改查,普通用户则只有查
    同时还可以实现一些特殊的需求
    全局自定义指令:Vue.directive(‘指令名’,{ inserted(el) { } })
    局部自定义指令:directives:{ }

vue2和vue3的自定义指令的区别,它们基本使用方式和原理是一样的,只是它们携带的生命周期钩子函数有所改变,写法不同
vue2中的绑定的钩子函数

  • bind - 绑定 指令绑定到元素后调用,且只调用一次,因为只会绑定一次
  • inserted - 节点在插入的时候调用
  • update - 在更新的时候调用
  • componentUpdated - 在组件更新完成后调用
  • unbind - 解绑的时候调用 也是只会调用一次

vue3中绑定的钩子函数

  • bind - beforeMount
  • inserted - mounted
  • beforeUpdate - 新增 元素更新之前调用
  • componentUpdated - updated
  • beforeUnmount - 新增 在元素卸载之前调用
  • unbind - unmounted

详情:

const myDirective = {
  // 在绑定元素的 attribute 前
  // 或事件监听器应用前调用
  created(el, binding, vnode, prevVnode) {
    // 下面会介绍各个参数的细节
  },
  // 在元素被插入到 DOM 前调用
  beforeMount(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都挂载完成后调用
  mounted(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件更新前调用
  beforeUpdate(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都更新后调用
  updated(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载前调用
  beforeUnmount(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载后调用
  unmounted(el, binding, vnode, prevVnode) {}
}

钩子函数中的参数我们一般使用 el 和 binding

  • el:指令绑定的元素,一般用来直接操作DOM
  • binding:一个对象,包含多个属性

    • value: 元素绑定指令给传递的值。 如:v-指令名称='传递的值'
    • oldValue: 之前的值。只在 beforeUpdateupdated中可以用。不管值是否更改,都可以使用
    • arg:传递给指令的参数。如:v-指令名称:foor;参数就是 foor
    • dir: 指令的定义对象
    • instance: 使用该指令的组件实例
    • modifiers:包含修饰符的对象。如:v-指令名称.foor.bar;修饰符对象就是{foo:true,bar:true}

还有两个参数是:
vnode:代表绑定元素的底层 VNode。
prevNode:代表之前的渲染中指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。
image.png
image.png

小案例:图片裂图
局部注册

<script>
import {ref} from "vue"
    // 正常图片
const img = ref("https://pic3.zhimg.com/v2-d5605e12f258084b0f31c857892f5629_r.jpg?source=1940ef5c")
// 图片裂图
const errImg = ref("https://img.ixintu.com/download/jpg/20200811/384e01b995f6c72ff79a1f1c8a7a87ba_512_384.jpg!ys")
// 自定义图片裂图指令
const vImg = { // 必须是 v开头的驼峰式命名
    mounted(el: any, bing: any) {
        // console.log(111, el, bing);
        el.onerror = function () {
            console.log(111);
            // 更改图片
            el.src = bing.value
        }
    }
}
</script>
<template>
    <!-- 图片裂图 -->
    <img v-img="errImg" :src="img">
</template>

全局注册自定义指令在main.ts中

main.ts

app.directive("img", {
    mounted: (el, binding) => {
        console.log(666, el, binding);
        // 监听错误信息
        el.addEventListener('error', function () {
            // 发送错误后 显示裂图
            el.src = binding.value
        })
    }
})

Home.vue组件中
<scirpt lang="ts" setup>
import {ref} from "vue"
// 正常图片
const img = ref("https://pic3.zhimg.com/v2-d5605e12f258084b0f31c857892f5629_r.jpg?source=1940ef5c")
// 图片裂图
const errImg = ref("https://img.ixintu.com/download/jpg/20200811/384e01b995f6c72ff79a1f1c8a7a87ba_512_384.jpg!ys")
<template>
    <!-- 图片裂图 -->
    <img v-img="errImg" :src="img">
</template>

注意:在全局中注册 因为使用了directive创建自定义指令,他接受两个参数(参1:创建自定义指令的名称,ps:不用加v 直接写名称就可以 否则会报错)
image.png
参2:是对象,对象里面写生命周期钩子函数

vue2中写法
在main.js中全局注册

// 1. 自定义指令
/* 
  自定义指令
    适应 Vue.directive
      第一个参数:指令名称
      第二个参数:对象{}
*/
Vue.directive('focus', {
  // 绑定 在绑定的时候开始调用 并且只调用一次 因为只会绑定一次
  /* 
     每个都有两个参数
      element,binding
      
  */
  bind(el, binding) {
    el.focus();
    el.style.border="2px solid #f00"
    console.log(el,binding);

  },
  // 节点在插入的时候调用
  inserted() {},
  // 在更新的时候调用
  update() {},
  // 在组件更新完成之后调用
  componentUpdated() {},
  // 解绑的时候调用
  unbind() {

  }
})

在组件中使用
<input v-focus type="text">


hanbo_bo
13 声望1 粉丝

« 上一篇
地图下钻
下一篇 »
同源策略