Vue中自定义指令
认识自定义指令
- 在Vue的模板语法中我们学习过各种各样的指令: v-show、v-for、v-model等等,除了使用这些指令之外,Vue也允许我们来
自定义自己的指令- 注意:在Vue中,
代码的复用和抽象主要还是通过组件
- 通常在某些情况下,你需要
对DOM元素进行底层操作
,这个时候就会用到自定义指令
- 注意:在Vue中,
- 自定义指令分为两种:
自定义局部指令
: 组件中通过directives 选项
,只能在当前组件中使用;自定义全局指令
: app的directive 方法
,可以在任意组件中被使用;
局部自定义指令(了解)
在组件内部定义的指令称为局部自定义指令。这样的指令只在组件的范围内有效,不会影响到其他组件。在组件的 directives 选项中注册指令:
<template>
<div v-local-example></div>
</template>
<script>
export default {
directives: {
localExample: {
bind(el, binding) {
// 指令绑定时的初始化操作
},
// 其他生命周期钩子函数
}
}
};
</script>
全局自定义指令
全局自定义指令在整个应用中可用。可以在 main.js 或其他入口文件中注册全局指令:
import { createApp ] from 'vue'
import App from'./自定义指令/App.vue'
const app = createApp(App)
//第一个参数即名称
app.directive("focus",{
//生命周期的函数( 自定义指今)
mounted(el) {
//console.Log("v-focus应用的元素被挂载了”,eL)
el?.focus()
app.mount('#app')
指令的生命周期
一个指令定义的对象,Vue提供了如下的几个钩子函数:
生命周期 | 调用时间 |
---|---|
created | 在绑定元素的 attribute 或事件监听器被应用之前调用 |
beforeMount | 当指令第一次绑定到元素并且在挂载父组件之前调用 |
mounted | 在绑定元素的父组件被挂载后调用 |
beforeUpdate | 在更新包含组件的 VNode 之前调用 |
updated | 在包含组件的 VNode 及其子组件的 VNode 更新后调用 |
beforeUnmount | 在卸载绑定元素的父组件之前调用 |
unmounted | 当指令与元素解除绑定且父组件已卸载时,只调用一次 |
自定义指令案例
下面是一些例子帮助理解掌握
价格拼接
- 使用指令是可传入符号单位,如¥;以实现¥/$100的效果
- 价格拼接单位符号使用示例< h2 v-unit=“¥’”>{{111}} < /h2>
案例代码:
import { createApp } from 'vue';
import App from './01_自定义指令/App.vue';
const app = createApp(App);
// 自定义指令:在元素上添加单位
app.directive("unit", {
// 指令绑定时调用
bind(el, binding) {
const defaultText = el.textContent;
let unit = binding.value;
// 如果没有传入单位,则默认为 "¥"
if (!unit) {
unit = "¥";
}
// 更新元素内容,拼接单位
el.textContent = unit + defaultText;
}
});
app.mount('#app');
时间格式化案例
- 对需要展示的时间使用指令进行格式化;可传入参数决定格式化效果
案例代码:
import { createApp } from 'vue';
import App from './01_自定义指令/App.vue';
import dayjs from 'dayjs'; //
const app = createApp(App);
// 自定义指令:时间格式化
app.directive("ftime", {
// 指令绑定时调用
mounted(el, binding) {
// 1. 获取时间,并转换为毫秒
let timestamp = el.textContent;
if (timestamp.length === 1) {
timestamp = timestamp * 1000;
}
// 2. 获取传入的参数
let value = binding.value;
if (!value) {
value = "YYYY-MM-DD HH:mm:ss";
}
// 3. 对时间进行格式化
const formatTime = dayjs(timestamp).format(value);
el.textContent = formatTime;
}
});
app.mount('#app');
在这个例子中:
- 使用 mounted 钩子替代 bind,因为 bind 更适用于初始绑定逻辑。
- 使用 dayjs 库进行时间格式化,需要确保已安装该库。
- 如果传入的参数为空,则默认使用 “YYYY-MM-DD HH:mm:ss” 格式。
- 对获取的时间进行格式化,并更新元素的文本内容。
- 在模板中使用该指令示例:
<h2 v-ftime="YYYY/MM/DD'">{{timestamp}}</h2> // 2009/01/08
<h2 v-ftime>([ 1551111166666 ]]</h2> // 1551-11-13 19:06:06
permission权限指令
最后在这里附上公司当前项目采用的权限指令,供参考学习使用:
/**
* Permission 权限指令
* 指令用法:
* - 在需要控制 permission 级别权限的组件上使用 v-permission:[组件code] , 如下:
* <a-button v-permission:[123]="'disable'">内容</a-button>
* <a-button v-permission:124>内容</a-button>
* - 当前用户没有权限时,组件上使用了该指令则会被隐藏
*/
export const permission = {
mounted: (el, binding) => {
const code = binding.arg || '';
const value = binding.value || '';
const baseStore = useBaseStore();
let userPermissions = [];
Object.keys(baseStore.userPermissions).forEach((item) => {
userPermissions = userPermissions.concat(baseStore.userPermissions[item]);
});
if (!userPermissions.includes(code)) {
if (value === 'disable') {
el.classList.add('is-disabled');
el.disabled = true;
} else {
// eslint-disable-next-line no-unused-expressions
(el.parentNode && el.parentNode.removeChild(el)) || (el.style.display = 'none');
}
}
},
unmounted: () => {},
};