自定义指令归类

This commit is contained in:
lzp
2026-03-31 15:45:15 +08:00
parent f931ce4927
commit ef52525651
7 changed files with 72 additions and 32 deletions

View File

@@ -13,10 +13,16 @@
> >
<svg-icon :name="v.icon" :size="v.iconSize" /> <svg-icon :name="v.icon" :size="v.iconSize" />
</span> </span>
<span class="more" v-if="v.child" @click="onClickMore(v)"> <span class="more" v-if="v.child" @click="onClickMore(v)" :bind-id="v.name">
<svg-icon name="dc-down_arrow2" size="7" /> <svg-icon name="dc-down_arrow2" size="7" />
</span> </span>
<div v-if="v.child" class="child" v-show="v.showChild"> <div
v-if="v.child"
class="child"
v-show="v.showChild"
:bind-id="v.name"
v-clidk-besides="() => (v.showChild = false)"
>
<div v-for="(v_, i_) in v.child" :key="i_" @click="onClickTool(v_, v)"> <div v-for="(v_, i_) in v.child" :key="i_" @click="onClickTool(v_, v)">
<span v-show="tool === v_.name" class="dui"> <span v-show="tool === v_.name" class="dui">
<svg-icon name="dc-dui" size="9" /> <svg-icon name="dc-dui" size="9" />

View File

@@ -199,8 +199,8 @@ export class AISelectboxToolManager {
if (!this.isDragging) return; if (!this.isDragging) return;
this.isDragging = false; this.isDragging = false;
const object = this.indicatorObject.toJSON("evented") const object = this.indicatorObject.toJSON("evented")
// if (object.width === 0) object.width = 100 if (object.width === 0 || object.height === 0) return
// if (object.height === 0) object.height = 100
this.clearIndicatorObject() this.clearIndicatorObject()
this.canvasManager.canvas.renderAll() this.canvasManager.canvas.renderAll()

View File

@@ -0,0 +1,27 @@
// 点击外部区域触发事件
// 用法v-clidk-besides="() => {}"
// 说明:点击外部区域触发事件,不包括点击元素本身
// 注意点击元素本身或者属性bind-id相同元素不会触发事件
export default {
name: 'clidk-besides',
mounted(el, binding) {
console.log("mounted", el, binding);
const call = binding.value
const id = el.getAttribute("bind-id");
window.addEventListener("touchstart", fun, true);
window.addEventListener("mousedown", fun, true);
function fun(e) {
var k = true;
iterator(e.target);
if (k) call && call();
function iterator(el) {
if (!el || el.nodeName == "#document") return;
if (el.getAttribute("bind-id") == id) {
k = false;
} else {
iterator(el.parentNode);
}
}
}
},
};

View File

@@ -1,11 +1,10 @@
import type { Directive } from 'vue'
/** /**
* 多行文本省略指令悬浮显示完整内容) * 多行文本省略指令悬浮显示完整内容)
* @directive v-ellipsis * @directive v-ellipsis
* @param {number} [value=3] - 超过value行数时显示省略号,不传参数默认为3 * @param {number} [value=3] - 超过value行数时显示省略号,不传参数默认为3
*/ */
const applyStyles = (el: HTMLElement, binding: any) => { const applyStyles = (el, binding) => {
const lines = typeof binding.value === 'number' && binding.value > 0 ? binding.value : 3 const lines = typeof binding.value === 'number' && binding.value > 0 ? binding.value : 3
el.style.display = '-webkit-box' el.style.display = '-webkit-box'
@@ -16,7 +15,7 @@ const applyStyles = (el: HTMLElement, binding: any) => {
el.style.maxHeight = `${lines}lh` el.style.maxHeight = `${lines}lh`
} }
const checkTruncated = (el: HTMLElement) => { const checkTruncated = (el) => {
const isTruncated = el.scrollHeight > el.clientHeight + 1 const isTruncated = el.scrollHeight > el.clientHeight + 1
if (isTruncated) { if (isTruncated) {
el.title = el.textContent?.trim() || '' el.title = el.textContent?.trim() || ''
@@ -25,14 +24,15 @@ const checkTruncated = (el: HTMLElement) => {
} }
} }
const vEllipsis: Directive<HTMLElement> = { export default {
name: 'ellipsis',
mounted(el, binding) { mounted(el, binding) {
applyStyles(el, binding) applyStyles(el, binding)
checkTruncated(el) checkTruncated(el)
const ro = new ResizeObserver(() => checkTruncated(el)) const ro = new ResizeObserver(() => checkTruncated(el))
ro.observe(el) ro.observe(el);
;(el as any)._ellipsisObserver = ro el._ellipsisObserver = ro
}, },
updated(el, binding) { updated(el, binding) {
@@ -41,12 +41,10 @@ const vEllipsis: Directive<HTMLElement> = {
}, },
unmounted(el) { unmounted(el) {
const ro = (el as any)._ellipsisObserver const ro = el._ellipsisObserver
if (ro) { if (ro) {
ro.disconnect() ro.disconnect()
delete (el as any)._ellipsisObserver delete el._ellipsisObserver
} }
} }
} }
export default vEllipsis

9
src/directives/index.js Normal file
View File

@@ -0,0 +1,9 @@
export default {
install(app) {
const directivesList = import.meta.glob('./*.js', { eager: true });
// 遍历指令文件实现自动注册
Object.keys(directivesList).forEach(key => {
app.directive(directivesList[key].default.name, directivesList[key].default);
});
}
};

16
src/directives/loadimg.js Normal file
View File

@@ -0,0 +1,16 @@
// 加载图片
export default {
name: 'loadimg',
mounted(el, binding) {
const src = binding.value
if (el.src === src) return
const img = new Image()
img.src = src
img.onload = () => {
el.src = src
}
img.onerror = () => {
console.log('图片加载失败:', src)
}
},
};

View File

@@ -7,6 +7,7 @@ import 'normalize.css'
import './assets/css/style.css' import './assets/css/style.css'
import SvgIcon from "@/components/SvgIcon/index.vue"; import SvgIcon from "@/components/SvgIcon/index.vue";
import "virtual:svg-icons-register"; import "virtual:svg-icons-register";
import directives from "./directives/index.js";
import i18n from "./lang/index"; import i18n from "./lang/index";
import flexible from "./utils/flexible.js"; import flexible from "./utils/flexible.js";
@@ -17,32 +18,15 @@ import 'element-plus/dist/index.css'
import ignoredWarning from './ignoredWarning' import ignoredWarning from './ignoredWarning'
import vEllipsis from './utils/ellispsis'
const app = createApp(App) const app = createApp(App)
ignoredWarning(app) ignoredWarning(app)
app.directive('ellipsis', vEllipsis)
app.use(router) app.use(router)
.use(directives)
.use(ElementPlus) .use(ElementPlus)
.use(store) .use(store)
.component("SvgIcon", SvgIcon) .component("SvgIcon", SvgIcon)
.use(i18n) .use(i18n)
.mount('#app') .mount('#app')
const vLoadimg = (el, binding) => {
const src = binding.value
if (el.src === src) return
const img = new Image()
img.src = src
img.onload = () => {
el.src = src
}
img.onerror = () => {
console.log('图片加载失败:', src)
}
}
// 注册
app.directive('loadimg', vLoadimg)
flexible(); flexible();