成都 广告公司网站建设,地域性旅游网站建设系统结构,辽宁网站建设多少钱,自助网站建设厦门网站制作前言 说到 vue 中的自定义指令#xff0c;相信大家都不陌生。在官网中是这么说的#xff0c;除了核心功能默认内置的指令 (v-model 和 v-show)#xff0c;vue 也允许注册自定义指令。那什么时候会用到自定义指令呢#xff1f;代码复用和抽象的主要形式是组件。然而#xf…前言 说到 vue 中的自定义指令相信大家都不陌生。在官网中是这么说的除了核心功能默认内置的指令 (v-model 和 v-show)vue 也允许注册自定义指令。那什么时候会用到自定义指令呢代码复用和抽象的主要形式是组件。然而有的情况下你仍然需要对普通 dom 元素进行底层操作这时候就会用到自定义指令。 自定义指令
自定义指令分为全局自定义指令局部自定义指令。它有两个参数参数1指令的名称参数2是一个对象这个对象身上有钩子函数。
全局自定义指令 通过 Vue.directive() 函数注册一个全局的指令 // 注册一个全局自定义指令 v-focus
Vue.directive(focus, {// 当被绑定的元素插入到 DOM 中时……inserted: function (el) {// 聚焦元素el.focus()}
})在 main.js 中引入 import focus from /utils/focus局部自定义指令 通过组件的 directives 属性对该组件添加一个局部的指令 directives: {focus: {// 指令的定义inserted: function (el) {el.focus()}}
}然后你可以在组件中任何元素上使用 v-focus 自定义的指令如下 input v-focus/批量注册指令
在 src 目录下新建文件夹directives/index.js管理各个子文件自定义指令文件然后在根文件index.js中对外暴露 api最后在 main.js 中引入并注册这样做的好处是统一管理后后期比较好维护而且会比较清晰。 文件目录 src/directives/index.js import Vue from vue;
import copy from ./modules/copy;//引入自定义指令
const directives {// 自定义指令copy,
};
export default {install(Vue) {Object.keys(directives).forEach(key Vue.directive(key, directives[key]))}
}在 main.js 中引入并注册 import Directives from /directives;
Vue.use(Directives);钩子函数 bind 只调用一次指令第一次绑定到元素时调用。 inserted 被绑定元素插入父节点时调用。 update 所在组件的虚拟节点更新时调用。 componentUpdated 所在组件的虚拟节点及其子虚拟节点全部更新时调用。 unbind 只调用一次指令与元素解绑时调用。 实例
看到这里你可能对自定义指令已经有了大概的了解和认识那可能有的同学要问了在实际的开发中自定义指令有什么使用场景吗下面分享在开发中常用的使用场景。 1. 复制粘贴指令 文件目录src/directives/modules/copy.js export default {bind(el, {value}) {el.$value value;el.handler () {if (!el.$value) {// 值为空的时候给出提示console.log(无复制内容);return;}const textarea document.createElement(textarea);// 将该textarea设为readonly防止iOS下自动唤起软键盘textarea.readOnly readonly;textarea.style.position absolute;textarea.style.left -9999px;// 将要copy的值赋给textarea标签的value属性textarea.value el.$value;// 将textarea插入到body中document.body.appendChild(textarea);// 选中值并复制textarea.select();const result document.execCommand(Copy);if (result) {console.log(复制成功);}// 赋值成功后将textarea移除掉document.body.removeChild(textarea);};// 绑定点击事件el.addEventListener(click, el.handler);},componentUpdated(el, {value}) {el.$value value;},// 指令与元素解绑的时候移除事件绑定unbind(el) {el.removeEventListener(click, el.handler);}
}组件中使用 templatedivbutton v-copycopyText复制/button/div
/template
script
export default {data() {return {copyText: 等待被复制的内容,};},
};
/script实现效果 2. 长按指令 文件目录src/directives/modules/longpress.js export default {bind(el, {value}) {if (function ! typeof value) {throw callback must be a function;}let pressTimer null;let start e {if (click e.type 0 ! e.button) {return;}if (null pressTimer) {pressTimer setTimeout(() {// 执行函数value(e);}, 1000);}};let cancel e {if (null ! pressTimer) {clearTimeout(pressTimer);pressTimer null;}};// 添加事件监听器el.addEventListener(mousedown, start);el.addEventListener(mouseout, cancel);el.addEventListener(click, cancel);el.addEventListener(touchstart, start);el.addEventListener(touchend, cancel);el.addEventListener(touchcancel, cancel);}
}组件中使用 templatedivbutton v-longpresslongpress长按我/button/div
/template
script
export default {methods: {longpress() {alert(触发了长按);},},
};
/script实现效果 3. 输入框防抖指令 文件目录src/directives/modules/debounce.js export default {inserted(el, {value}) {if (function ! typeof value) {throw directive value must be function;}let timer;el.addEventListener(keyup, () {timer clearTimeout(timer);timer setTimeout(() {value value();}, 1000);});}
}组件中使用 templatedivbutton v-longpresslongpress长按我/button/div
/template
script
export default {methods: {longpress() {alert(触发了长按);},},
};
/script实现效果 4. 输入框自动聚焦指令 文件目录src/directives/modules/focus.js export default {inserted(el, {value}) {// 聚焦元素el.focus()}
}组件中使用 templatedivinput v-focus typetext //div
/template实现效果 5. 全屏指令 文件目录src/directives/modules/fullScreen.js export default {bind(el, binding) {if (binding.modifiers.icon) {if (el.hasIcon) return// 创建全屏图标const iconElement document.createElement(i)iconElement.setAttribute(class, el-icon-full-screen)iconElement.setAttribute(style, margin-left:5px)el.appendChild(iconElement)el.hasIcon true}el.style.cursor el.style.cursor || pointer// 监听点击全屏事件el.addEventListener(click, () handleClick())}
}function handleClick() {let FullScreen falselet element document.documentElement;if (FullScreen) {if (document.exitFullscreen) {document.exitFullscreen();} else if (document.webkitCancelFullScreen) {document.webkitCancelFullScreen();} else if (document.mozCancelFullScreen) {document.mozCancelFullScreen();} else if (document.msExitFullscreen) {document.msExitFullscreen();}} else {if (element.requestFullscreen) {element.requestFullscreen();} else if (element.webkitRequestFullScreen) {element.webkitRequestFullScreen();} else if (element.mozRequestFullScreen) {element.mozRequestFullScreen();} else if (element.msRequestFullscreen) {element.msRequestFullscreen();}}FullScreen !FullScreen;
}组件中使用 templatedivspan v-fullScreen.icon全屏/span/div
/template实现效果 6. 文字超出展示省略号指令 文件目录src/directives/modules/ellipsis.js export default {bind(el, binding) {console.log(el,binding);el.style.width binding.arg || 100 vwel.style.whiteSpace nowrapel.style.overflow hidden;el.style.textOverflow ellipsis;}
}组件中使用 templatedivdiv v-ellipsis给你一首诗的时间坐在炉火边捧着诗卷阅读听不见大摆钟的摇摆远离岁月的尘埃/div/div
/template实现效果 7. 拖拽指令 文件目录src/directives/modules/drag.js export default {bind(el, binding) {document.onselectstart function () {return false //禁止选择网页上的文字}el.style.cursor move // 图标el.style.position absoluteel.onmousedown function (ev) {// 用元素距离视窗的X、Y坐标减去el元素最近的相对定位父元素的left、top值var sX ev.clientX - el.offsetLeftvar sY ev.clientY - el.offsetTopdocument.onmousemove function (ev) {var eX ev.clientX - sXvar eY ev.clientY - sY// 不断地更新元素的left、top值el.style.left eX pxel.style.top eY px}document.onmouseup function () {// 清除mousemove事件document.onmousemove null}}}
}组件中使用 templatedivdiv classbox v-drag拖拽/div/div
/template
script
export default {data() {return {};},
};
/script
style scoped
.box {width: 100px;height: 100px;background: cadetblue;text-align: center;line-height: 100px;color: #fff;
}
/style实现效果 8. 字符串整形指令 文件目录src/directives/modules/format.js export default {bind(el, binding, vnode) {const {value,modifiers} bindingif (!value) returnlet formatValue valueif (modifiers.toFixed) {formatValue value.toFixed(2)}console.log(formatValue)if (modifiers.price) {formatValue formatNumber(formatValue)}el.innerText formatValue},
}function formatNumber(num) {num ;let strs num.split(.);let x1 strs[0];let x2 strs.length 1 ? . strs[1] : ;var rgx /(\d)(\d{3})/;while (rgx.test(x1)) {x1 x1.replace(rgx, $1 , $2);}return x1 x2
}组件中使用 templatedivdiv v-format.toFixed.price123456789/divdiv v-format.toFixed123.4567/div/div
/template实现效果 持续更新中...