自定义指令
- 用于对 DOM 进行底层操作
- vue3 自定义指令的周期变为
自定义指令周期
- beforeMount 在挂载之前调用,可以进行初始化配置
- mounted: 挂载到父组件的时候调用
- beforeUpdate: 更新包含此组件的 VNode 值钱调用
- updated: 在更新之后调用
- beforeUnmount: 在卸载之前调用
- unmounted: 当指令与元素解除绑定且父组件已卸载时调用
- 每一个周期都接受 el, binding 参数
自定义指令参数
- el: 可用于直接操作 dom
- 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,效果是简单的追加,顺序为书写的顺序