网站建设项目设计表,网页版式设计分析图片,h5微场景制作软件,网站建设微盘下载除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外#xff0c;Vue 还允许你注册自定义的指令 (Custom Directives)。
1. 生命周期钩子函数
一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。
在 script …除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外Vue 还允许你注册自定义的指令 (Custom Directives)。
1. 生命周期钩子函数
一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。
在 script setup 中任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令。
!-- App.vue --
templatedivbutton切换/button!-- 钩子函数里面都可以接受这些值myParam: 自定义参数myModifier: 自定义修饰符 --A v-move:myParam.myModifier{ background: pink }/A/div
/templatescript setup langts
import { reactive, ref, Directive } from vue;
import A from ./components/A.vue;
import B from ./components/B.vue;
let flag refboolean(true)
const vMove: Directive {created() {console.log(created)},beforeMount() {console.log(beforeMount)},mounted(...args: Arrayany) {console.log(mounted)console.log(args);},beforeUpdate() {console.log(beforeUpdate)},updated() {console.log(updated)},beforeUnmount() {console.log(beforeUnmount)},unmounted() {console.log(unmounted)}
}
/scriptstyle scoped langless/style0该 div 元素。1传入的参数等。比如 arg 参数modifiers 自定义修饰符dir 目录传入的 value 值instance 组件实例。2当前组件的虚拟 DOM3上一个虚拟 DOM
!-- App.vue --
templatedivbutton切换/button!-- 钩子函数里面都可以接受这些值myParam: 自定义参数myModifier: 自定义修饰符 --A v-move:myParam.myModifier{ background: pink }/A/div
/templatescript setup langts
import { reactive, ref, Directive, DirectiveBinding } from vue;
import A from ./components/A.vue;
import B from ./components/B.vue;
let flag refboolean(true)
type Dir {background: string;
}
const vMove: Directive {created() {console.log(created)},beforeMount() {console.log(beforeMount)},mounted(el: HTMLElement, dir: DirectiveBindingDir) {console.log(mounted)console.log(el);console.log(dir);el.style.background dir.value.background;},// 传入的数据发生变化比如此时的background时触发 beforeUpdate 和 updatedbeforeUpdate() {console.log(beforeUpdate)},updated() {console.log(updated)},beforeUnmount() {console.log(beforeUnmount)},unmounted() {console.log(unmounted)}
}
/scriptstyle scoped langless/style2. 指令简写
!-- App.vue --
templatediv classbtnsbutton v-has-show123创建/buttonbutton编辑/buttonbutton删除/button/div
/templatescript setup langts
import { reactive, ref, DirectiveBinding } from vue;
import type { Directive } from vue
const vHasShow: Directive (el, binding) {console.log(el, binding) ;
}
/scriptstyle scoped langless
.btns {button {margin: 10px;}
}
/style应用场景1按钮鉴权
根据能否从 localStorage或者后台返回 中获取数据来判断是否显示某个按钮。
!-- App.vue --
templatediv classbtnsbutton v-has-showshop:create创建/buttonbutton v-has-showshop:edit编辑/buttonbutton v-has-showshop:delete删除/button/div
/templatescript setup langts
import { reactive, ref, DirectiveBinding } from vue;
import type { Directive } from vue
localStorage.setItem(userId, xiuxiu)
// mock 后台返回的数据
const permissions [xiuxiu:shop:create,// xiuxiu:shop:edit, // 后台没有相应数据则不显示该对应的按钮xiuxiu:shop:delete
]
const userId localStorage.getItem(userId) as string
const vHasShow: Directive (el, binding) {if(!permissions.includes(userId : binding.value)) {el.style.display none}
}
/scriptstyle scoped langless
.btns {button {margin: 10px;}
}
/style应用场景2鼠标拖拽
拖拽粉色框移动大盒子。
!-- App.vue --
templatediv v-move classboxdiv classheader/divdiv内容/div/div
/templatescript setup langts
import { Directive, DirectiveBinding } from vue;const vMove:Directiveany,void (el:HTMLElement, binding:DirectiveBinding) {let moveElement:HTMLElement el.firstElementChild as HTMLElement;console.log(moveElement);const mouseDown (e:MouseEvent) {// 记录原始位置// clientX 鼠标点击位置的X轴坐标// clientY 鼠标点击位置的Y轴坐标// offsetLeft 鼠标点击的子元素距离其父元素的左边的距离// offsetTop 鼠标点击的子元素距离其父元素的顶部的距离let X e.clientX - el.offsetLeft;let Y e.clientY - el.offsetTop;const move (e:MouseEvent) {console.log(e);el.style.left e.clientX - X px;el.style.top e.clientY - Y px;}document.addEventListener(mousemove, move);document.addEventListener(mouseup, () {document.removeEventListener(mousemove, move);})}moveElement.addEventListener(mousedown, mouseDown);
}
/scriptstyle scoped langless
.box {position: fixed;height: 200px;width: 200px;top: 50%;left: 50%;transform: translate(-50%, -50%);border: 1px solid #000;.header {height: 50px;width: 100%;background: pink;border-bottom: #000 1px solid;}
}
/style应用场景3懒加载
let imageList import.meta.glob(./assets/images/*.*, { eager: true })let imageList import.meta.glob(./assets/images/*.*)// 判断图片是否在可视区const observer new IntersectionObserver((e) {console.log(e[0]);}) // 监听元素observer.observe(el)!-- App.vue --
templatedivdivimg v-lazyitem width400 height500 v-foritem in arr alt/div/div
/templatescript setup langts
import { Directive, DirectiveBinding } from vue;let imageList:Recordstring,{default:string} import.meta.glob(./assets/images/*.*, { eager: true })
let arr Object.values(imageList).map(itemitem.default)
console.log(arr);
let vLazy:DirectiveHTMLImageElement,string async (el,binding) {const def await import(./assets/pinia.svg)el.src def.default// 判断图片是否在可视区const observer new IntersectionObserver((e) {console.log(e[0],binding.value);if(e[0].intersectionRatio 0) {setTimeout(() {el.src binding.value},2000)observer.unobserve(el)}}) // 监听元素observer.observe(el)
}
/scriptstyle scoped langless/style进入可视区比例 0 过 2s 替换图片