Vue自定义指令和自定义过滤器

一、自定义指令:

自定义指令分为两种:全局自定义指令和局部自定义指令

全局指令指所有组件都可以使用,局部指令是只有在当前组件中才可以使用。

如,我们现在有个需求,当一个输入框获取焦点时,显示出一个div框,且可点击使之变色,当我们点击div框之外的地方,隐藏弹出的div框

<div v-click-outside="hide">
<input type="text" @focus="show">
<div v-if="isShow" style="width: 100px; height:100px;background: red;" @click="changeColor"></div>
</div>

vue实现方式如下:

let vm = new Vue({
el:"#app",
data(){
return{
isShow:false,
}
},
methods:{
show(){
this.isShow = true;
},
changeColor(e){
let c = [0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'];
let r = "#";
for(let i=0;i<c.length;i++){
r += c[Math.floor(Math.random()*c.length)];
}
e.target.style.background=r;
}
},
directives:{
'click-outside'(el,bindings,vnode){
document.addEventListener("click",function test(e){
if(!el.contains(e.target)){
vnode.context[bindings.expression]();
document.removeEventListener("click",test);
}
})
}
}
});

上面自定义了一个简单的局部指令,指令函数有三个参数

el:当前dom节点,初始化div默认是不展示的:

Vue自定义指令和自定义过滤器

bingings:当前节点所有绑定的属性:

  name:指令名字

  value:指令的绑定值

  expression:字符串形式的指令表达式

  oldValue:指令绑定的前一个值(仅在update 和 componentUpdated 钩子中可用)

  arg:传给指令的参数(可选)

Vue自定义指令和自定义过滤器

vnode:虚拟节点,它的上下文context里面有所有当前Vue对象上绑定的属性和方法

Vue自定义指令和自定义过滤器

再看一个需求:有一个输入框,界面一刷新,输入框就会自动获得焦点。这个需求看起来很简单,但是这里涉及到了一个钩子的生命周期问题

<input type="text" v-focus="focus" />

Vue.directive("focus",function(el, bindings, vnode){
el.focus()
})

上面是最直观想到的方案,但是在实际执行过程中发现,这种做法是无效的。为什么呢?先看下自定义指令的生命周期:

自定义指令默认有5个生命周期:bind, inserted, update, componentUpdated, unbind

  bind::在指令第一次绑定到元素时调用。只会执行一次,且此时dom元素还没有插入页面父节点

  inserted:被绑定元素插入到父节点时调用

  update:被绑定元素所在模板更新时调用,无论绑定值是否变化

  componentUpdated:被绑定元素所在模板完成一次更新时调用

  unbind:指令解绑时调用,也只会执行一次

看了上面的指令生命周期,再看说我们上面的自定义指令为何不能成功?原因是组件在初始化调用指令时,是在bind中调用的,而这时dom元素还没有插入到父节点。

正确的应该怎么实现呢?

<input type='text' v-focus="focus">

new Vue({
el:"app",
directives:{
'focus'(el, bindings, vnode){
bind(){
console.log("bind");
},
inserted(){
el.focus()
},
}
}
})

注意:自定义指令中钩子里面没有Vue实例,this指向window

二、自定义过滤器

如,我们需要将用户英文名第一个字母大写,其他小写

使用方式 :{{ name | toUpper(1)  }}  // | :管道符

Vue.filter("toUpper",function(value, count){
count = count?count:value.length-1
return value.substr(0,count).toUpperCase()+value.substr(count);
});
上一篇:wince下sources\sources.cmn\Makefile.def的相关作用


下一篇:centos6安装lamp