signed

QiShunwang

“诚信为本、客户至上”

可复用性组合

2020/12/26 12:27:47   来源:

自定义指令

  • 用于对 DOM 进行底层操作
  • vue3 自定义指令的周期变为

自定义指令周期

  1. beforeMount 在挂载之前调用,可以进行初始化配置
  2. mounted: 挂载到父组件的时候调用
  3. beforeUpdate: 更新包含此组件的 VNode 值钱调用
  4. updated: 在更新之后调用
  5. beforeUnmount: 在卸载之前调用
  6. unmounted: 当指令与元素解除绑定且父组件已卸载时调用
  7. 每一个周期都接受 el, binding 参数

自定义指令参数

  1. el: 可用于直接操作 dom
  2. binding:
  • instance: 使用指令的组件实例
  • value: 传递给指令的值
  • arg 传递的指令
  • modifiers 修饰符
  • dir:一个对象,在注册指令时作为参数传递
  • vnode, oldVnode 虚拟节点

取得元素:

<template>
  <div v-demo class="div"></div>
</template>
directives: {
    demo: {
      beforeMount(el, binding) {
        el.innerHTML = 'beforeMount'
        console.log('beforeMount')
      },
      mounted(el) {
        console.log('mounted')
        el.style.color = 'red'
      },
    }
  }

传值

<template>
  <div v-demo="20" class="div">aa</div>
</template>
 directives: {
    demo: {
      mounted(el, binding) {
        const {value} = binding
        el.style.position = 'fixed'
        el.style.top = `${value}px`
      },
    }

动态传值或者指令参数

<div v-demo:[dierection]="number" class="div">aa</div>
import { defineComponent, ref, onMounted, toRefs } from "vue";

export default defineComponent({
  name: "App",
  setup(props) {
    const number = ref(0);
    const dierection = ref("top");
    onMounted(() => {
      setInterval(() => {
        number.value = number.value + 10;
        console.log(number.value);

        if (dierection.value === "top") {
          dierection.value = "left";
        } else {
          dierection.value = "top";
        }
      }, 1000);
    });
    return {
      number,
      dierection,
    };
  },
  directives: {
    demo: {
      mounted(el, binding) {
        const { value, arg } = binding;
        el.style.position = "fixed";
        el.style[arg] = `${value}px`;
      },
      updated(el, binding) {
        // 涉及到更新,要写 updated 周期的逻辑了
        const { value, arg } = binding;
        el.style.position = "fixed";
        el.style[arg] = `${value}px`;
      },
    },
  },
});

其他

  • 指令函数能够接受所有的画法的 javascript 表达式
  • 在 3.0 中有了片段的支持,组件可能有多个根节点。如果在具有多个根节点的组件上使用自定义指令,则会产生问题(还是写一个根节点的好)

Teleport

  • 可以将组件挂载到理想元素上,可以用于解决之前遇到的弹窗穿透的问题
    组件中:
<template>
  <teleport to="#modal">
    <div>tel</div>
  </teleport>
</template>

index.html 中

<div id="app"></div>
<div id="modal"></div>
  • 可以在同一个目标上使用多次 teleport,效果是简单的追加,顺序为书写的顺序