<script setup lang='ts'>
import { ref,Directive, watchEffect } from "vue"
/**
* Implement the custom directive
* Make sure the list item text color changes to red when the `toggleTab` is toggled
*
*/
const VActiveStyle:Directive = {
mounted(el,binding){
const [styleObject, conditionFn] = binding.value
const stop = watchEffect(()=>{
if(conditionFn && conditionFn() ){
Object.assign(el.style,styleObject)
}
else{
Object.assign(el.style,{color:null})
}
})
},
beforeUnmount(){
stop()
}
}
const list = [1, 2, 3, 4, 5, 6, 7, 8]
const activeTab = ref(0)
function toggleTab(index: number) {
activeTab.value = index;
}
</script>
<template>
<ul>
<li
v-for="(item,index) in list"
:key="index"
v-active-style="[{'color':'red'},() => activeTab === index]"
@click="toggleTab(index)"
>
{{ item }}
</li>
</ul>
</template>
watchEffect
watchEffect 是 Vue 3 的响应式 API 之一,用于立即执行一个函数,并响应式地追踪其依赖(即函数内部访问的响应式状态),当任何依赖改变时重新执行该函数。
追踪的状态:conditionFn() 的执行依赖于 activeTab 的当前值。因此,activeTab 是被 watchEffect 追踪的响应式状态。
样式应用逻辑:当 conditionFn() 返回 true(即当前元素对应的索引等于 activeTab 的值),styleObject(这里是 { ‘color’: ‘red’ })将被应用到元素的样式上。否则,元素的颜色样式会被设置为 null,实际上会移除之前应用的颜色样式,回退到默认或先前定义的样式。
mounted 和 onMounted 可以呼唤吗
在 Vue 的自定义指令定义中,mounted 和 onMounted 并不是可以互换使用的概念。mounted 是自定义指令的一个生命周期钩子,它在指令第一次绑定到元素上时调用,相当于组件的 mounted 生命周期钩子。而 onMounted 是 Vue Composition API 中的一个函数,用于在组件的 setup 函数中注册一个在组件挂载完成后执行的副作用。
在你的代码示例中,mounted 正确地用作自定义指令的生命周期钩子。如果你尝试将其更改为 onMounted,将不会达到预期效果,因为 onMounted 在这个上下文中没有定义,且不会被识别为自定义指令的有效钩子。
const VActiveStyle: Directive = {
mounted(el, binding) {
// 正确的使用方式
// ...代码实现...
}
// 不能替换为 onMounted
};
自定义指令的生命周期钩子包括:
beforeMount:在指令第一次绑定到元素并且在挂载父组件之前调用。
mounted:在绑定元素的父组件被挂载后调用。
beforeUpdate:在包含组件的 VNode 更新之前调用,但可能在其子 VNode 更新之后。
updated:在包含组件的 VNode 及其子 VNode 更新后调用。
beforeUnmount:在卸载绑定元素的父组件之前调用。
unmounted:在卸载绑定元素的父组件之后调用。