写完了一个directive指令进入vue源码查看
ASSET_TYPES.forEach(function (type)){
Vue[type]=function(
id,//id="loading"
definition //definition={update:f}
){
if(!definition){//因为我们有definition,所以不进入这个
return this.options[type+'s'][id]
}else{
if(type === 'component'){//我们的type是directive,因此不进入这个
validateComponentName(id)
}
if(type === 'component' && isPlaneObject(definition)){
definition.name = definition.name || id;
definition = this.options._base.extend(definition)
}
//因为我们的definition是对象不是方法,所以不进入下面这个
if(type === 'directive' && typeof definition === 'function'){
definition = {bind:definition,update:definition}
}
//执行下面的代码,加到Vue的options属性下面的directives属性中
this.options[type+'s'][id]=definition;
return definition
}
}
}
Vue.js官网中自定义指令中的钩子函数参数-动态指令参数中有一个函数简写,即
在很多时候,你可能想在bind和update时触发相同行为,而不关心其他的钩子,比如这样写:
Vue.directive('color-watch',function(el,binding){ el.style.backgroundColor=binding.value })
能这样简写,就是因为vue源码中
if(type === 'directive' && typeof definition === 'function'){ definition = {bind:definition,update:definition} }
因此我们可以改写47的代码
<body>
<div id="root">
<div v-loading="isloading">{{data}}</div>
<button @click="update">更新</button>
</div>
<script>
Vue.directive("loading",
update(el,binding,vnode){
console.log(binding)//binding的value值就是isloading
if(binding.value){
//让遮罩出现
const div=document.createElement("div")
div.setAttribute('id','loading')
div.innerHTML="加载中..."
div.style.position='absolute'
div.style.left=0
div.style.top=0
div.style.width='100%'
div.style.height='100%'
div.style.display='flex'
div.style.justifyContent='center'
div.style.alignItems='center'
div.style.color='white'
div.style.background='rgba(0,0,0,.7)'
document.body.append(div)
}else{
//为了避免bind触发执行的时候找不到div而报错,我们这样
const div=document.getElementById('loading')
div && document.body.removeChild(div)
}
})
new Vue({
el:"#root",
data:function(){
return{
data:'',
isloading:false
}
},
methods:{
update(){
this.isloading=true
setTimeout(()=>{
//遮罩消失
this.isLoading=false
//数据要出来
this.data='这是后端请求的数据'
},3000)
}
}
})
</script>
</body>