江西南昌网站制作,dj音乐网站建设,小学生作文网,阳江房价Vue 自定义命令
官方的vue命令包括#xff1a;v-html v-if v-else v-show v-for等等为了提高效率#xff0c;减少重复项编写#xff0c;vue支持自定义命令#xff0c;可以封装一些DOM操作#xff0c;扩展额外的功能
语法
注册 全局注册
//在main.js中
Vue.directive(…Vue 自定义命令
官方的vue命令包括v-html v-if v-else v-show v-for等等为了提高效率减少重复项编写vue支持自定义命令可以封装一些DOM操作扩展额外的功能
语法
注册 全局注册
//在main.js中
Vue.directive(指令名, {inserted (el) {// 可以对 el 标签扩展额外功能el.focus()}
}) 局部注册
//在Vue组件的配置项中
directives: {指令名: {inserted () {// 可以对 el 标签扩展额外功能el.focus()}}
}
使用
注意在使用指令的时候一定要先注册再使用否则会报错使用指令语法 v-指令名。
如input typetext v-focus/ 注册指令时不用加v-前缀但使用时一定要加v-前缀
扩展
钩子函数:
Vue 2.X 与 Vue 3.X 相比钩子函数是存在变化的
Vue 2.X钩子函数 bind自定义指令绑定到DOM后调用。只调用一次指令第一次绑定到元素的调用。在这里可以进行一次性的初始化设置。注意只是加入进了DOM但是渲染没有完成。 inserted自定义指令所在DOM插入到父DOM后调用渲染已经完成父节点存在即可调用不必存在于document中。 update元素更新但子元素尚未更新将调用此钩子自定义指令所在组件更新时执行但是不保证更新完成,和自定义指令所在组件有关。 componentUpdated组件和子级更新后执行自定义指令所在组件更新完成且子组件也完成更新 unbind解绑销毁自定义指令所在DOM销毁时执行只调用一次。
Vue 3.X钩子函数 created自定义指令所在组件创建后调用 beforeMount相当于Vue 2.X中的bind当元素被插入到DOM前调用 mounted相当于Vue 2.X中的inserted当绑定元素的父组件被挂载后调用 beforeUpdate绑定元素的父组件更新前调用 updated相当于Vue 2.X中的componentUpdated在绑定元素的父组件及他自己的所有子节点都更新后调用 beforeUnmount绑定元素的父组件卸载前调用 unmounted绑定元素的父组件卸载后调用
钩子函数参数
指令的钩子会传递以下几种参数 el指令绑定到的元素。这可以直接操作DOM。 binding一个对象包含以下属性。 value传递给指令的值。例如在v-my-directive11中值是2. oldValue之前的值仅在beforeUpdate和updated中可用。无论值是否更改它都可用. arg传递给指令的参数如果有的话。例如在v-my-directive:foo中参数是foo. modifiers一个包含修饰符的对象如果有的话。例如在v-my-directive:foo:bar中修饰符对象是{ foo: true, bar: true }. instance使用该指令的组件实例. dir指令的定义对象. vnode代表绑定元素的底层VNode。虚拟DOM节点一个真实DOM元素的蓝图对应el. prevNode上一个虚拟节点。之前的渲染中代表指令所绑定元素的VNode。仅在beforUpdate和updated钩子中使用.
常用指令
1.复制粘贴指令 v-copy
实现一键复制文本内容用于粘贴思路1.动态创建textarea标签并设置reaOnly属性及移除可视区域2.将要复制的值赋给textarea标签的value属性并插入到body3.选中值textarea并复制4.将body中插入的textarea移除5.在第一次调用时绑定事件在解绑时移除事件
const copy {bind(el, { value }) {el._value valueel.handler () {if (!el._value) {// 复制的值为空时给出的提示操作。console.log(无可复制的内容)return}
// 创建 textarea 标签const textarea document.createElement(textarea)// 设置readOnly(规定字段为只读)属性防止 iOS下自动唤起键盘并移除可视区域textarea.readOnly readOnlytextarea.style.position absolutetextarea.style.left -9999px// 将需要复制的值赋给 textarea 标签的 value 值textarea.value el._value // 将 textarea 插入到 body 中document.body.appendChild(textarea)
// 选中值并复制textarea.select()const result document.execCommand(Copy)if (result) {console.log(复制成功)}document.body.removeChild(textarea)}// 绑定点击事件el.addEventListener(click, el.handler)},// 当传进来的值更新的时候触发componentUpdated(el, { value }) {el._value value},// 指令与元素解绑的时候触发移除事件绑定unbind(el) {el.removeEventListener(click, el.handler)}
}
export default copy
使用给DOM节点加上v-copy及复制文本即可
templatebutton v-copytext复制/button
/template
scriptexport default {data () {return {text: 这是一条复制文本}}}
/script
2.长按指令 v-longpress
实现长按超过两秒执行回调函数思路1.创建一个计时器两秒后执行函数2.当用户按下按钮时触发mousedown事件移动端touchstart事件)启动计时器3.用户松开按钮时调用mouseout事件移动端touchend事件4.如果mouseup事件在两秒内触发此事件当作普通点击事件5.如果计时器没有在两秒内清除定为长按事件触发相关回调函数
const longpress {bind: (el, binding, vNode) {// 没有绑定函数抛出错误if (typeof binding.value ! function) {throw longpress callback not a function}
// 计时器变量el._timer null// 运行函数el._handler e {binding.value(e)}// 创建计时器2秒后执行函数el._start e {// 0为鼠标左键if (e.type click e.button ! 0) return
if (el._timer null) {el._timer setTimeout(_ {el._handler()}, 2000)
// 取消浏览器默认事件el.addEventListener(contextmenu, e {e.preventDefault()})}}// 两秒内松手取消计时器el._cancel e {if (el._timer ! null) {clearTimeout(el._timer)el._timer null}}
// 添加计时监听el.addEventListener(mousedown, el._start)el.addEventListener(touchstart, el._start)// 添加取消监听el.addEventListener(click, el._cancel)el.addEventListener(mouseout, el._cancel)el.addEventListener(touchend, el._cancel)el.addEventListener(touchcancel, el._cancel)},unbind(el) {// 移除监听el.removeEventListener(mousedown, el._start)el.removeEventListener(touchstart, el._start)el.removeEventListener(click, el._cancel)el.removeEventListener(mouseout, el._cancel)el.removeEventListener(touchend, el._cancel)el.removeEventListener(touchcancel, el._cancel)}
}
export default longpress
使用给DOM节点加上v-longpress及相应回调函数
templatebutton v-longpresshandleLongpress复制/button
/template
scriptexport default {methods: {handleLongpress() {alert(这是长按指令)}}}
/script
3.防抖指令 v-debounce
场景项目开发中经常会遇到按钮多次点击后重复请求接口造成数据混乱例如表单提交。实现使用防抖防止按钮在短时间内多次点击设置按钮在1秒内只能点击一次。思路1.定义延时方法在1秒内再调用该方法则重新计算执行时间2.将事件绑定在点击方法上
const debounce {inserted: (el, binding) {// 没有绑定函数抛出错误if (typeof binding.value ! function) {throw debounce callback not a function}
let timerel.addEventListener(click, () {if (timer) clearTimeout(timer)
timer setTimeout(_ {binding.value()}, 1000)})}
}
export default debounce
使用给DOM节点加上v-debounce及回调函数
templatebutton v-debouncehandleDebounce防抖/button
/template
scriptexport default {methods: {handleDebounce() {console.log(防抖触发一次)}}}
/script
4.节流指令 v-throttle
场景同防抖指令场景实现使用节流方法限制1秒内按钮只能点击一次思路1.定义一个开关默认时打开状态2.在点击按钮后关闭开关在1秒内再点击按钮不执行回调函数3.1秒过后开关打开
const throttle {bind: (el, binding) {// 没有绑定函数抛出错误if (typeof binding.value ! function) {throw throttle callback not a function}
// 开关el._flag trueel._timer nullel._handler () {if (!el._flag) return
// 函数执行后关闭开关el._flag binding.value()el._flag false
if (el._timer) clearTimeout(el._timer)
el._timer setTimeout(_ {el._flag true}, 1000)}el.addEventListener(click, el._handler)},unbind: (el, binding) {el.removeEventListener(click, el._handler)}
}
export default throttle
使用给DOM节点加上v-throttle及回调函数
templatebutton v-throttlehandleThrottle节流/button
/template
scriptexport default {methods: {handleThrottle() {console.log(节流触发一次)}}}
/script
5.点击元素外部指令 v-clickOut
场景弹窗点击弹窗外部即蒙版关闭弹窗实现点击指定区域外部执行相应回调函数思路判断点击的元素是否指定元素是则不执行否则执行相应回调函数
const clickOut {bind: (el, binding) {el._handler e {// 判断点击的元素是否本身是则返回if (el.contains(e.target)) return
// 如果绑定了函数则调用函数if (typeof binding.value function) {binding.value()}}
// 添加事件监听setTimeout(_ {document.addEventListener(click, el._handler)}, 0)},unbind(el) {// 解除事件监听document.removeEventListener(click, el._handler)}
}
export default clickOut
使用给指定DOM节点加v-clickOut及回调函数
template!-- v-clickOut、v-click-out都可以使用 --div stylewidth:100px;height:100px;background-color:red; v-click-outhandleClickOuttarget DOM/div
/template
scriptexport default {methods: {handleClickOut() {console.log(外部元素触发)}}}
/script
6.拖拽指令 v-draggable
实现指定元素在可视区域内任意拖拽思路设置指定元素相对定位父元素绝对定位鼠标按下时触发onmousedown事件时记录指定元素当前的left、top值鼠标移动时触发onmousemove事件时计算每次移动的横向距离、纵向距离并改变left、top值鼠标松开时触发onmouseup事件时完成一次拖拽
const draggable {inserted: (el) {el.style.cursor moveel._onmousedown e {// 记录当前的left、top值let disX e.pageX - el.offsetLeftlet disY e.pageY - el.offsetTop
// 鼠标移动document.onmousemove e {let x e.pageX - disXlet y e.pageY - disY
// 临界值处理let maxX document.body.clientWidth - parseInt(window.getComputedStyle(el).width)let maxY document.body.clientHeight - parseInt(window.getComputedStyle(el).height)
if (x 0) {x 0} else if (x maxX) {x maxX}
if (y 0) {y 0} else if (y maxY) {y maxY}
el.style.left ${x}pxel.style.top ${y}px}document.onmouseup _ {document.onmousemove document.onmouseup null}}}
}
export default draggable
使用给指定DOM节点加v-draggable即可
template!-- 需要加上position:absolute --div stylewidth:40px;height:40px;background-color:green;position:absolute; v-draggable/div
/template
7.水印指令 v-Money
实现给指定页面添加背景水印思路使用canvas特性生成base64格式的图片文件设置其字体大小颜色等。将其设置为背景图实现水印效果
function addWaterMarker (str, parentNode, font, textColor) {// 水印文字父元素字体文字颜色var can document.createElement(canvas)parentNode.appendChild(can)can.width 200can.height 150can.style.display nonevar cans can.getContext(2d)cans.rotate((-20 * Math.PI) / 180)cans.font font || 16px Microsoft JhengHeicans.fillStyle textColor || rgba(180, 180, 180, 0.3)cans.textAlign leftcans.textBaseline Middlecans.fillText(str, can.width / 10, can.height / 2)parentNode.style.backgroundImage url( can.toDataURL(image/png) )
}
const waterMarker {bind: function (el, binding) {addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor)}
}
export default waterMarker
使用给DOM节点加上v-waterMarker并设置水印文案字体大小及颜色等
templatediv classwater-marker v-waterMarkerwaterMarker/div
/templatescriptexport default {waterMarker: {text: 版权所有,font: 14px Microsoft Fangc,textColor: rgba(180, 180, 180, 0.4)}}
/scriptstyle langscss scoped
.water-marker {width: 400px;height: 400px;border: 1px solid #eee;
}
/style