目录1. 一个指令定义对象可以提供如下几个钩子函数(均为可选)2.指令钩子函数会被传入以下参数3.使用自定义指令场景的示例1. 一个指令定义对象可以提供如下几个钩子函数(均为可选)
Vue.directive 内置了五个钩子函数 :
bind(绑定触发)、inserted(插入触发)、update(更新触发)、componentUpdated(组件更新触发)和unbind(解绑触发)函
// 注册
Vue.directive('my-directive',{
bind: function () {},
inserted: function () {},
update: function () {},
componentUpdated: function () {},
unbind: function() {}
})
除了el之外,其他参数都应该是只读的,不能修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。
drag.js
import Vue from 'vue'
import { Message } from 'element-ui';
// 自定义指令示例1:弹窗拖拽
Vue.directive('dialogDrag',{
bind(el,binding,vnode,oldVnode){
const dialogHeader = el.querySelector('.el-dialog__header');
const dialogDom = el.querySelector('.el-dialog');
dialogHeader.style.cursor = 'move'
const sty = dialogDom.currentStyle || window.getComputedStyle(dialogDom, null)
dialogHeader.onmousedown = (e) => {
//按下鼠标,获取点击的位置 距离 弹窗的左边和上边的距离
//点击的点距离左边窗口的距离 - 弹窗距离左边窗口的距离
const distX = e.clientX - dialogHeader.offsetLeft;
const distY = e.clientY - dialogHeader.offsetTop;
//弹窗的left属性值和top属性值
let styL, styT
//注意在ie中,第一次获取到的值为组件自带50%,移动之后赋值为Px
if(sty.left.includes('%')){
styL = +document.body.clientWidth * (+sty.left.replace(/%/g,'') / 100)
styT = +document,body.clientHeight * (+sty.top.replace(/%/g,'') / 100)
}else{
styL = +sty.left.replace(/px/g,'');
styT = +sty.top.replace(/px/g,'');
}
document.onmousemove = function(e) {
//通过事件委托,计算移动距离
const l = e.clientX - distX
const t = e.clientY - distY
//移动当前的元素
dialogDom.style.left = `${l + styL}px`
dialogDom.style.top = `${t + styT}px`
}
document.onmouseup = function(e){
document.onmousemove = null
document.onmouseup = null
}
}
}
})
//自定义指令示例2:v-dialogDragWidth 可拖动弹窗宽度(右侧边)
Vue.directive('dragWidth',{
bind(el) {
const dragDom = el.querySelector('.el-dialog');
const lineEl = document.createElement('div');
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
lineEl.addEventListener('mousedown',
function (e) {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - el.offsetLeft;
// 当前宽度
const curWidth = dragDom.offsetWidth;
document.onmousemove = function (e) {
e.preventDefault(); // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
const l = e.clientX - disX;
if(l > 0){
dragDom.style.width = `${curWidth + l}px`;
}
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}, false);
dragDom.appendChild(lineEl);
}
})
// 自定义指令示例3:v-dialogDragWidth 可拖动弹窗高度(右下角)
Vue.directive('dragHeight',{
bind(el) {
const dragDom = el.querySelector('.el-dialog');
const lineEl = document.createElement('div');
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
lineEl.addEventListener('mousedown',
function(e) {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - el.offsetLeft;
const disY = e.clientY - el.offsetTop;
// 当前宽度 高度
const curWidth = dragDom.offsetWidth;
const curHeight = dragDom.offsetHeight;
document.onmousemove = function(e) {
e.preventDefault(); // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
const xl = e.clientX - disX;
const yl = e.clientY - disY
dragDom.style.width = `${curWidth + xl}px`;
dragDom.style.height = `${curHeight + yl}px`;
};
document.onmouseup = function(e) {
document.onmousemove = null;
document.onmouseup = null;
};
}, false);
dragDom.appendChild(lineEl);
}
})
// 自定义指令示例4:图片加载前填充背景色
Vue.directive('imgUrl',function(el,binding){
var color=Math.floor(Math.random()*1000000);//设置随机颜色
el.style.backgroundColor='#'+color;
var img=new Image();
img.src=binding.value;// -->binding.value指的是指令后的参数
img.onload=function(){
el.style.backgroundColor='';
el.src=binding.value;
}
})
// 自定义指令示例5:输入框聚焦
Vue.directive("focus", {
// 当被绑定的元素插入到 DOM 中时……
inserted (el) {
// 聚焦元素
el.querySelector('input').focus()
},
});
// 自定义指令示例6:设置防抖自定义指令
Vue.directive('throttle', {
bind: (el, binding) => {
let setTime = binding.value; // 可设置防抖时间
if (!setTime) { // 用户若不设置防抖时间,则默认2s
setTime = 1000;
}
let cbFun;
el.addEventListener('click', event => {
if (!cbFun) { // 第一次执行
cbFun = setTimeout(() => {
cbFun = null;
}, setTime);
} else {
event && event.stopImmediatePropagation();
}
}, true);
},
});
// 自定义指令示例7:点击按钮操作频繁给出提示
Vue.directive('preventReClick', {
inserted: function (el, binding) {
el.addEventListener('click', () => {
if (!el.disabled) {
el.disabled = true
Message.warning('操作频繁')
setTimeout(() => {
el.disabled = false
//可设置时间
}, binding.value || 3000)
}
})
}
})
main.js中引入文件:
import '@/assets/js/drag.js'
页面使用:
<template>
<div>
<el-button type="text" @click="dialogVisible = true">点击打开 Dialog</el-button>
<div style="display:flex">
<img v-imgUrl="url"></img>
<img v-imgUrl="url"></img>
<img v-imgUrl="url"></img>
<img v-imgUrl="url"></img>
<img v-imgUrl="url"></img>
<img v-imgUrl="url"></img>
<img v-imgUrl="url"></img>
<img v-imgUrl="url"></img>
</div>
<div>
<el-input placeholder="请选择日期" suffix-icon="el-icon-date" v-model="input1"></el-input>
<el-input v-focus placeholder="请输入内容" prefix-icon="el-icon-search" v-model="input2"></el-input>
</div>
<div>
<el-button type="danger" v-throttle @click="throttleBtn">危险按钮</el-button>
<el-button @click="submitFORM()">创建</el-button>
</div>
<el-dialog title="提示" v-dialogDrag v-dragWidth v-dragHeight :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
<span>这是一段信息</span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
dialogVisible: false,
url:'//www.baidu.com/img/flexible/loGo/pc/result.png',
input1: '',
input2: '',
}
},
methods: {
handleClose(done) {
console.log('弹窗打开')
},
throttleBtn(){
console.log('我的用来测试防抖的按钮')
},
submitForm(){
this.$message.error('Message 消息提示每次只能1个');
}
},
}
</script>
<style>
img{
width: 100px;
height: 100px;
}
</style>
看下效果吧:
首先进入页面,
到此这篇关于vue 自定义指令directive的使用场景的文章就介绍到这了,更多相关vue 自定义指令directive内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: vue自定义指令directive的使用场景
本文链接: https://lsjlt.com/news/209612.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0