vue使用directive
- 前言
- vue2使用
- vue3使用
前言
关于使用自定义指令在官网中是这样描述的
vue2:对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
vue3:自定义指令主要是为了重用涉及普通元素的底层 DOM 访问的逻辑。
在 Vue.js 中使用自定义指令(directive)可以带来许多好处,包括但不限于这些:
- 代码复用:自定义指令可以封装一些常用的 DOM 操作,使得这些操作可以在多个组件中复用,减少代码冗余。
- 简化模板:通过自定义指令,可以将一些复杂的 DOM 操作从模板中移除,使模板更加简洁和易读。
- 增强功能:自定义指令可以提供一些 Vue 框架本身不直接支持的功能,比如自动聚焦、拖拽、动画等。
- 更好的封装性:自定义指令可以将 DOM 操作的逻辑封装在指令内部,使得组件的代码更加清晰和模块化。
- 更细粒度的控制:自定义指令可以绑定到特定的 DOM 元素或属性,提供更细粒度的控制,比如只对某个元素应用某些效果。
- 生命周期钩子:自定义指令提供了生命周期钩子函数,可以在不同的阶段执行特定的逻辑。
vue2使用
在vue2使用使用directive
根据官网介绍可以这样使用
// 注册一个全局自定义指令 `v-focus`
import Vue from 'vue'
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
然后在页面中绑定
<input v-focus>
这样就能 聚焦元素 的效果
当然在项目中可以更加优化
这里单独创建一个文件夹来存放自定义指令的js文件并使用index导出引入的文件, 这里拿两个实例来举例子 ,一个是复制文本的copy.js文件,一个控制权限的role.js文件。
main.js 文件这样集中引入指令文件
import Vue from 'vue'
import App from './App.vue'
import directives from './directives';
Vue.config.productionTip = false
Object.keys(directives).forEach(name => {
Vue.directive(name, directives[name]);
});
new Vue({
render: h => h(App),
}).$mount('#app')
index.js 文件导出引入的指令
import copy from './copy';
import role from './role';
export default {
copy,
role
};
copy.js文件
import { Message } from 'element-ui';
let timer = null;
const copy = {
bind(el, binding) {
if (binding.value) {
el.addEventListener('click', () => copyClick(el, binding));
}
},
};
const copyClick = (el, binding) => {
if (timer) clearTimeout(timer);
timer = setTimeout(async () => {
await navigator.clipboard.writeText(binding.value);
Message.success('复制成功!');
timer = null;
}, 200);
};
export default copy;
role.js文件
const role = {
bind (el, binding) {
//只有包含了2的dom元素才显示
if (!binding.value.includes(2)) {
el.style.display = 'none';
}
},
};
export default role;
最后在文件中使用
<template>
<div class="hello">
<el-button type="primary" round v-copy="text">点击我复制</el-button>
<li v-role="[1]">这是一号dom</li>
<li v-role="[1,2]">这是二号dom</li>
<li v-role="[1,2,3]">这是三号dom</li>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
text: 'hello world'
}
}
}
</script>
最后看实际效果
这就是基础的使用,
关于生命周期钩子函数
官网提供了像bind
、inserted
、update
、componentUpdated
、unbind
等,可以在不同的阶段执行特定的逻辑。
更多的参考 vue2指令官网
vue3使用
在vue3中使用指令与vue2写法有点不同
官网是这样使用的
const app = createApp({})
// 使 v-focus 在所有组件中都可用
app.directive('focus', {
/* ... */
})
// 使用的组件
<template>
<input v-focus />
</template>
这里的举例跟vue2的一样,不过项目是用vite+ts搭建的
单独创建一个文件夹来存放自定义指令的js文件并使用index导出引入的文件, 这里拿两个实例来举例子 ,复制文本的copy.ts文件和控制权限的role.ts文件。
main.ts 文件这样集中引入指令文件
import { createApp } from 'vue'
import App from './App.vue'
import directives from './directives';
const app = createApp(App)
for (const [name, directive] of Object.entries(directives)) {
app.directive(name, directive);
}
app.mount('#app')
在index.ts 文件中导出
import copy from './copy';
import role from './role';
export default {
copy,
role
};
copy.ts文件
import { DirectiveBinding } from 'vue';
import { ElMessage } from 'element-plus';
let timer: any = null;
const copy = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
if (binding.value) {
el.addEventListener('click', () => copyClick(el, binding));
}
},
};
const copyClick = (el: HTMLElement, binding: DirectiveBinding) => {
if (timer) clearTimeout(timer);
timer = setTimeout(async () => {
// 复制文本
await navigator.clipboard.writeText(binding.value);
ElMessage.success('复制成功!');
timer = null;
}, 200);
};
export default copy;
role.ts文件
import { DirectiveBinding } from 'vue';
const role = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
//包含了 2 的元素才显示
if (!binding.value.includes(2)) {
el.remove();
}
},
};
export default role;
使用的vue件
<script setup lang="ts">
import { ref } from "vue";
const text = ref("这是赋值的值12345");
</script>
<template>
<el-button type="primary" round v-copy="text">点击我复制</el-button>
<li v-role="[1]">这是一号dom</li>
<li v-role="[1,2]">这是二号dom</li>
<li v-role="[1,2,3]">这是三号dom</li>
</template>
最后看效果
最后关于生命周期钩子函数,官网给出了这些
更多的扩展使用可以参考官网
vue3指令官网