单页面应用已经成为了我们前端工程师开发中的常客,我们总是会遇到这样的情况如何从传统的dom操作中走出来,以前我们进行dom操作,用的是js的document.getElementById,document.getElementsByClassName,jquery的$(‘xxx’)来进行操作,所以从传统的web前端转型过来的工程师,我们总是想着如何在MVVM中使用jquery.js,zepto.js来加快我们的开发,这样的开发想法其实并没有什么错误,为了更好更快的开发吗,但是我们既然用MVVM的框架进行开发就要掌握它的使用的正确姿势,做为一个vue.js开发的忠实爱好者和开发者,我就以它为例来进行介绍。
从我接触到的angular和vue,它们都有directive这个概念,正所谓美好的事物总有相通之处。下面我们就来介绍一下directive这个概念在vue框架中所起的作用,指令作为vue框架中很重的一环,在vue中常用的有v-for, v-text, v-model,v-if, v-bind, v-on等,这些框架内置的指令我们在实用的过程中很常见,正是由于它们的存在从而使我们加快了开发中的速度,这根本的原因是我们对dom的操作更加方便,我们只需要通过简单的几行代码就可以实现传统开发中几十行代码实现的效果。
话不多说我们先来一个例子介绍一下vue中的自定义指令。
通过自定义一个指令来对#app容器内的p元素进行颜色设置
dom结构
<div id="app">
theme: {{ themeColor }}
<p v-tcolor="red">this is 1 pargraph</p>
<p v-tcolor="tomato">this is 2 pargraph</p>
<p>this is 3 pargraph</p>
<p v-tcolor="green">this is 4 pargraph</p>
</div>
js 代码
var vm = new Vue({
el: '#app',
data: {
themeColor: 'color',
themeImg: 'img',
red: '#ff00000',
tomato: '#f00000',
green: '#00ff00',
},
directives: {
tcolor: function(el, binding){
el.style.color = binding.value;
}
}
});
效果:
根据使用的作用域的不同我们认为的将指令分为全局指令和局部指令,上面的实例即为局部指令,将它转换为全局指令其实很简单,这和我们自定义组件使用方法一致。处理形式如下:
var vm = new Vue({
el: '#app',
data: {
themeColor: 'color',
themeImg: 'img',
red: '#ff00000',
tomato: '#f00000',
green: '#00ff00',
}
});
Vue.directive('tcolor', function(el, binding){
el.style.color = binding.value;
});
注意:在使用MVVM框架时,们应该注意在使用指令是要先定义指令,在MVVM开发时若我们需要某个插件或某个组件的话我们应该先定义这个插件组件,或指令,以及是说我们要在最后指定元素的容器。
上面所讲只是指令的常规应用,在开发项目时我们可能因为开发需求的不同需要对项目做一些特殊处理。以下四个钩子函数可以解决我们遇到的大部分问题。
bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
update: 所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。指令的值可能发生了改变也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated: 所在组件的 VNode 及其孩子的 VNode 全部更新时调用。
unbind: 只调用一次, 指令与元素解绑时调用。
这些钩子函数都包含了这样几个参数el, binding, vnode, oldVnode,其中binding参数是一个对象包含value, oldvalue,name, expression,arg,modifiers六个属性。
最后一句话,也是个人的心得体会,‘要想MVVM用的好,就远离jquery,zepto’,我这里并不是说jquery不好,但是我们既然用MVVM就要充分发挥这个框架的特性,从而使我们的应用的性能达到最佳。