<script setup lang='ts'>
import { ref } from "vue"
const state = ref(false)
/**
* Implement the custom directive
* Make sure the input element focuses/blurs when the 'state' is toggled
*
*/
// 以v开头的驼峰式命名的变量都可以作为一个自定义指令
const VFocus = {
mounted:(el)=>el.focus(), // el是指令绑定到的元素
updated:(el,binding)=>{ // 包含传递给指令的值、指令修饰符modifiers(v-directive.upper)、指令参数arg(v-directive:foo)等属性
binding.value ? el.focus() : el.blur()
}
}
setInterval(() => {
state.value = !state.value
}, 2000)
</script>
<template>
<input v-focus="state" type="text">
</template>
自定义指令的对象提供了7个钩子函数:
created、beforeMounted、 mounted、 beforeUpdate、updated、beforeUnmount、unmounted
大多数情况仅需要使用mounted和updated。
对比vue的8个生命周期(自定义指令的生命周期缺少了一个beforeCreate):
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeUnmount、unmounted
实现v-active-style自定义指令:
<script setup lang='ts'>
import { BindingTypes } from "@vue/compiler-core";
import { ref ,watchEffect} from "vue"
/**
* Implement the custom directive
* Make sure the list item text color changes to red when the `toggleTab` is toggled
*
*/
const VActiveStyle = {
mounted:(el,bingding)=>{
let [style,fn] = bingding.value
watchEffect(()=>{
if(fn()){
Object.keys(style).forEach((key)=>{
el.style[key] = style[key]
})
}else{
Object.keys(style).forEach((key)=>{
el.style[key] = ''
})
}
})
}
}
const list = [1, 2, 3, 4, 5, 6, 7, 8]
const activeTab = ref(0)
function toggleTab(index: number) {
activeTab.value = index
console.log( activeTab.value)
}
</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>
实现v-model指令:
<script setup lang='ts'>
import { ref, watch, watchEffect } from "vue"
/**
* Implement a custom directive
* Create a two-way binding on a form input element
*
*/
const onInput = function(){
value.value = this.value
}
const VOhModel = {
mounted:(el,binding)=>{
el.value = value.value
el.addEventListener('input',onInput.bind(el))
},
unmounted:(el,binding)=>{
el.removeEventListener('input',onInput.bind(el))
}
}
const value = ref("Hello Vue.js")
</script>
<template>
<input v-oh-model="value" type="text" />
<p>{{ value }}</p>
</template>