回首Vue3之API篇(二)

343 阅读4分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

这篇文章我们来讲一下应用APIdirective的使用,以及我们需要注意的地方。

directive可以用来注册或检索全局指令。当我们需要对普通DOM进行操作的时候,我们这个用这个API来进行自定义指令。

注册指令

创建应用实例

在注册指令之前,我们需要创建应用实例,如下:

import { createApp } from 'vue'
const app = createApp({})

注册

注册指令的时候我们需要用到很多的钩子函数,使用方法如下所示:

app.directive('my-directive', {
  // 指令是具有一组生命周期的钩子:
  // 在绑定元素的 attribute 或事件监听器被应用之前调用
  created() {},
  // 在绑定元素的父组件挂载之前调用
  beforeMount() {},
  // 绑定元素的父组件被挂载时调用
  mounted() {},
  // 在包含组件的 VNode 更新之前调用
  beforeUpdate() {},
  // 在包含组件的 VNode 及其子组件的 VNode 更新之后调用
  updated() {},
  // 在绑定元素的父组件卸载之前调用
  beforeUnmount() {},
  // 卸载绑定元素的父组件时调用
  unmounted() {}
})

这些指令钩子有三个参数:elbindingvnode,而beforeUpdate 和 updated 钩子中多了一个参数prevNode。参数详情如下:

  1. el 指令绑定到的元素。这可用于直接操作 DOM。

  2. binding 包含以下 property 的对象:

    • instance:使用指令的组件实例。
    • value:传递给指令的值。例如,在 v-my-directive="1 + 1" 中,该值为 2
    • oldValue:先前的值,仅在 beforeUpdate 和 updated 中可用。值是否已更改都可用。
    • arg:参数传递给指令 (如果有)。例如在 v-my-directive:foo 中,arg 为 "foo"
    • modifiers:包含修饰符 (如果有) 的对象。例如在 v-my-directive.foo.bar 中,修饰符对象为 {foo: true,bar: true}
    • dir:一个对象,在注册指令时作为参数传递。例如,在以下指令中
  3. vnode 当前虚拟节点。

  4. prevNode 上一个虚拟节点。

注册简写

如果我们想在 mounted 和 updated 时触发相同行为,而不关心其他的钩子函数。那么我们可以通过回调函数传递来简写这个指令,如下:

app.directive('my-directive', (el,binding) => {
    console.log(el,binding);
})

使用指令

我们把指令注册好又如何使用呢,也许不仅仅是加v-指令名,还可以有其他的用法。

v-指令名

我们在注册好一个指令后,该怎么使用呢,如下:

自定义指令

app.directive('my-directive', {
    mounted(el, binding) {
        el.style.color = 'red';
    }
})

使用

<h1 v-my-directive>hello world</h1>

此时渲染出来的文本是红色的。

动态指令参数

假定一个动态指令如下:

//数据 
const obj = ref({
    style: 'background',
    color: 'red'
})

//指令
app.directive('my-directive', {
    mounted(el, binding) {
        el.style[binding.arg] = binding.value;
    }
})

那么,我们可以这样使用:

<h1 v-my-directive:[obj.style]="obj.color">hello world</h1>

我们得到的结果是h1的背景色为红色,当然数据改变得时候,也会发生变化,注册指令里面钩子函数的内容也是要根据自己的需求来灵活改变的。当然我们可以直接传一个值:

<h1 v-my-directive="obj.color">hello world</h1>

如果这样写,我们钩子函数里面的内容需要发生变化,在这里面我们只能保证binding.value这个值是动态的。

对象字面量

上述指令传值可以是动态的,但是仅仅只有一个值,那当我们需要很多参数的时候该怎么办呢?这时候我们就需要用到对象字面量,使用如下:

<h1 v-my-directive="{ color: 'red', text: 'hello!' }">hello world</h1>

我们可以根据传值信息来改变钩子函数里面的内容。

检索指令

在开发中,我们在注册指令的时候,可能会检测一下这个指令是否存在,然后在做其他的操作。那么我们就可以用以下方法进行检索全局指令。

const myDirective = app.directive('my-directive')

总结

  1. 虽然开发用用的频率不是很高,但是我们还是需要了解一下,因为你不知道什么时候就用到了。

  2. 在注册和使用指令中,我们要根据自己的需求,去写符合自己需求的指令。如果指令可以被复用,我们要尽可能的去复用它,就像组件一样。

想了解更多文章,传送门已开启:回首Vue3目录篇