开始开发
在 src/directives
下新建一个 index.ts
统一注册全局自定义指令
// src/directives/index.ts
import { App } from "vue";
export const createDirective = {
install(app: App) {
// 指令注册
app.directive("xxx", {
// ...
});
},
};
在main.ts
引入,使用给vue
// main.ts
import { createDirective } from "@/directives";
app.use(createDirective);
封装指令
为 ant-button
绑定倒计时
为按钮绑定倒计时,倒计时结束按钮才可以被点击。
// src/directives/ctd.directive.ts
/**
* 设置按钮状态
* @param {BtnStatusOption} btnStatusOption - 设置按钮状态参数
* @param {HTMLButtonElement} btnStatusOption.el - 按钮元素
* @param {string} btnStatusOption.className - 按钮class
* @param {string} btnStatusOption.disabled - 按钮禁用状态
* @param {number} btnStatusOption.timeTotal - 倒计时总时间,单位s
* @param {number} btnStatusOption.timeCur - 当前经过的时间,单位s
* @param {string} btnStatusOption.orginText - 按钮原始文字
* */
const setBtnStatus = (btnStatusOption: BtnStatusOption) => {
const { el, className, disabled, timeTotal, timeCur, orginText } = btnStatusOption;
el.className = className;
el.disabled = disabled;
setBtnText({ el, timeTotal, timeCur, orginText });
};
/**
* 设置按钮文字
* @param {BtnTextOption} btnTextOption - 设置按钮文字参数
* @param {HTMLButtonElement} btnTextOption.el - 按钮元素
* @param {number} btnTextOption.timeTotal - 倒计时总时间,单位s
* @param {number} btnTextOption.timeCur - 当前经过的时间,单位s
* @param {string} btnTextOption.orginText - 按钮原始文字
* */
const setBtnText = (btnTextOption: BtnTextOption) => {
const { el, timeTotal, timeCur, orginText } = btnTextOption;
if (el.disabled) {
el.innerText = `(${timeTotal - timeCur})${orginText}`;
} else {
el.innerText = `${orginText}`;
}
};
/**
* 自定义指令使用方法
* @example <a-button v-ctd>确认</a-button> 默认5秒
* @example <a-button v-ctd="10">确认</a-button> 可设置10秒倒计时
* */
export const createCtdDirective = {
beforeMount(el: HTMLButtonElement, binding: any, vnode) {
const timeTotal = binding.value || 5; // 倒计时,单位s
let timeCur = 0; // 当前经过的时间,单位s
const orginClassName = el.className; // 原始class
const orginText = el.innerText; // 原始文字
// 设置按钮禁用
setBtnStatus({
el,
timeTotal,
timeCur,
orginText,
className: "ant-btn",
disabled: true,
});
const timer = setInterval(() => {
timeCur += 1;
// 动态修改按钮文字
setBtnText({ el, timeTotal, timeCur, orginText });
if (timeCur >= timeTotal) {
// 设置按钮启用
setBtnStatus({
el,
timeTotal,
timeCur,
orginText,
className: orginClassName,
disabled: false,
});
clearInterval(timer);
}
}, 1000);
},
};
// 设置按钮状态参数
declare type BtnStatusOption = BtnTextOption & {
className: string; // 原始class
disabled: boolean; // 按钮禁用状态
};
// 设置按钮文字参数
declare type BtnTextOption = {
el: HTMLButtonElement; // 按钮元素
timeTotal: number; // 倒计时,单位s
timeCur: number; // 当前经过的时间,单位s
orginText: string; // 原始文字
};
最后将指令在 src/directives/index.ts
注册
import { createCtdDirective } from "./ctd.directive"; // 新增这一行
import { App } from "vue";
export const createDirective = {
install(app: App) {
// 按钮倒计时指令
app.directive("ctd", createCtdDirective); // 新增这一行
},
};
快速使用
<!-- 默认5秒倒计时 -->
<a-button type="primary" v-ctd>确认</a-button>
<!-- 自定义60秒倒计时 -->
<a-button type="primary" v-ctd="60">确认</a-button>
效果如图