<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义指令</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3 v-hello>{{msg}}</h3>
<button @click="change()">更新数据</button>
<h3 v-world:wbs888="username">{{msg}}</h3>
<input type="text" v-model="msg" v-focus>
</div>
<script>
/**
* 自定义全局指令
* 注:使用指令时必须在指名名称前加前缀v-,即v-指令名称
*/
//钩子函数的参数 el,binding
Vue.directive('hello',{
bind(el,binding){ //常用!!
// console.log(el); //指令所绑定的元素,DOM对象
el.style.color='red';
console.log(binding); //name
console.log('bind:指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作');
},
inserted(el,binding){
console.log(el)
// binding.arg:传给指令的参数
console.log('inserted:被绑定元素插入到DOM中时调用');
},
update(el,binding){
console.log(el)
console.log('update:被绑定元素所在模板更新时调用,模板还没更新完成');
},
componentUpdated(el,binding){
console.log(el)
console.log('componentUpdated:被绑定元素所在模板完成一次更新周期时调用');
},
unbind(el,binding){
console.log('unbind:指令与元素解绑时调用,只调用一次');
}
});
//动态传参 传入一个简单的函数, bind update 钩子函数可以调用
Vue.directive('world',function(el,binding){
console.log(binding);
})
var vm=new Vue({
el:'#app',
data:{
msg:'welcome to app',
username:'alice'
},
methods:{
change(){
this.msg = '你好';
}
},
directives:{ //自定义局部指令
focus:{
bind(el,binding){
//数据还没渲染
},
//被绑定元素插入到DOM中时调用
inserted(el,binding){
el.focus();
}
}
}
});
</script>
</body>
</html>
下面小案例
封装弹框的函数以及拖拽的功能
function initPopHtml(title,html){
var popOut = document.getElementById('popOut') ;
if(popOut) {
return;
}
var popOut = document.createElement('div');
popOut.id='popOut';
popOut.className = 'pop-out';
var innerText = `
<div class="heaad-title">${title}</div>
<div class="pop-inner">${html}</div>
<div class="footer"><button type="button" class="btn-close" id="btnClose">关闭</button></div>`;
popOut.innerHTML = innerText;
document.querySelector('body').appendChild(popOut);
toMoveDrag(popOut);
document.getElementById('btnClose').addEventListener('click',()=>{
popOut.remove();
});
}
function toMoveDrag(boxDom){
var moveFlag = false;
var dis={};
boxDom.querySelector('.heaad-title').onmousedown = function(e){
moveFlag=true;
// 计算出鼠标落下点与边界的距离
dis.x = e.clientX - boxDom.offsetLeft;
dis.y = e.clientY - boxDom.offsetTop;
}
document.onmousemove = function(e){
if (!moveFlag) {
return;
};
console.log(e.clientX);
// 根据拖拽距离设置当前拖拽元素的位置
boxDom.style.left = (e.clientX - dis.x) + 'px';
boxDom.style.top = (e.clientY - dis.y) + 'px';
};
document.onmouseup = function(e){
moveFlag=false;
}
}
指令的编写
directives:{
popwin:{
bind(el,binding){
el.onclick = function(){
// binding.value :列表的数据
var data = binding.value;
var listUl = [];
listUl.push(`<ul class='user-list'>`)
data.forEach((item,index)=>{
console.log(item);
listUl.push(`<li><span>姓名:${item.name}</span><span>年龄:${item.age}</span></li>`)
})
listUl.push(`</ul>`);
initPopHtml(el.innerText,`<div class="content">${listUl.join('')}</div>`);
}
},
inserted(el,binding){
},
update(){
},
componentUpdated(){
}
}
}
2.4 使用指令
<button type="button" v-popwin="teacherlist">教师信息列表</button>
<button type="button" v-popwin="studentlist">学生信息列表</button>