这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
建议按序观看
Vue 也允许注册自定义指令。注意代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
在 src 目录下,新建directive目录,在目录中
├── drag
│ └── index.ts
├── index.ts
├── permission
│ └── index.ts
└── typinng.ts
自定义指令插件封装
directive/index.ts
import { App } from 'vue'
import drag from './drag/index'
const install = (app: App): void => {
app.directive('drag', drag)
//...等等可配置
}
export default install
配置类型
typinng.ts
export interface IDirectiveOptionsWithInstall extends ObjectDirective {
install?: (app: App) => void
}
drag移动指令的配置
/**
* @description: drag移动指令
* @param {HTMLElement} el
* @param {DirectiveBinding} binding
* @return {*}
*/
const drag = (el: HTMLElement) => {
const odiv: HTMLElement = el // 获取当前元素
odiv.onmousedown = (e) => {
// 算出鼠标相对元素的位置
const disX = e.clientX - odiv.offsetLeft
const disY = e.clientY - odiv.offsetTop
document.onmousemove = (e) => {
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
let left = e.clientX - disX
let bottom = document.body.offsetHeight - (e.clientY - disY) - odiv.clientHeight
if (left < 0) left = 0
if (left > document.body.offsetWidth - odiv.offsetWidth) {
left = document.body.offsetWidth - odiv.offsetWidth
}
if (bottom < 0) {
bottom = 0
}
if (bottom > document.body.offsetHeight - odiv.offsetHeight) {
bottom = document.body.offsetHeight - odiv.offsetHeight
}
// 移动当前元素
odiv.style.left = left + 'px'
odiv.style.bottom = bottom + 'px'
}
document.onmouseup = () => {
document.onmousemove = null
document.onmouseup = null
}
}
}
const plugin = (el: HTMLElement) => {
drag(el)
}
export default plugin as IDirectiveOptionsWithInstall
权限指令
// 是否有权限
export function isAuthor(id: number | number[] | undefined): boolean {
if (id === undefined) {
return false;
}
let groups = [];
if (userModule.userInfo) {
// 这里要和状态管理一起用,按照当前的后端接口设计
groups = userModule.userInfo.permid || [];
}
let show: boolean = false;
if (typeof id === 'number') {
id = [id];
}
groups &&
groups.forEach((item: number) => {
if ((id as number[]).includes(item)) {
show = true;
}
});
return show;
}
/**
* @description: 权限指令
* @param {HTMLElement} el
* @param {DirectiveBinding} binding
* @return {*}
*/
const checkPermission = (el: HTMLElement, binding: DirectiveBinding) => {
const { value } = binding
const id: number = binding.value ? binding.value : 0;
const show: boolean = isAuthor(id);
// 如果是 hide,就直接移除 dom
if ('hide' in binding.modifiers || !Object.keys(binding.modifiers).length {
!show && el.parentNode && el.parentNode.removeChild(el);
}
// 如果是disabled,就给当前标签,添加上disabled的属性
if ('disabled' in binding.modifiers) {
!show && el.setAttribute('disabled', 'true');
!show && el.classList.add('is-disabled');
}
}
const plugin = (el: HTMLElement, binding: DirectiveBinding) => {
checkPermission(el, binding)
}
// modifiers 特殊修饰符
// v-premiss.hide
// v-premiss.disabled