Vue2.x指令
指令(Directives),指带有
v-前缀的特殊属性。当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM,是Vue双向绑定最基础的表现。
内置指令
v-text
<div v-text="text"></div>绑定的参数与将作为元素内部的
textContent,等价于<div>{{text}}</div>v-html
<div v-html="html"></div>绑定的参数将作为元素的
innerHTML内容,要注意防止xss攻击v-bind
<div v-bind:class="className"></div>Vue中最基本的参数双向绑定,当用于原生的元素标签时,可以将参数绑定至标签的原生属性上,当用于封装的组件时,将作为
props传入组件内。通常会使用以下的写法<div :class="className"></div>v-on
<button v-on:click="handleClick(args, $event)">click me!</button>用于绑定事件,事件方法定义在
methods内。对于有原生事件的标签来说,v-on能够直接支持。而对于封装的组件而言,可以在组件内使用$emit()来定义事件触发的条件。入参参数在没必要的情况下能够省略。通常会使用以下写法<button @click="handleClick(args, $event)"></button>事件修饰符:
<!-- 使用方法 --> <button v-on:click.stop="handleClick">click me!</button>.stop: 阻止冒泡,调用event.stopPropagation().prevent: 阻止默认事件,调用event.preventDefault(),如用于表单提交事件.capture: 添加事件侦听器时使用事件捕获模式,即元素自身触发的事件先在事件方法内处理,然后才交由内部元素进行处理.self: 只当事件在该元素本身(比如不是子元素)触发时触发回调.once: 事件只触发一次.passive: 用于滚动事件,滚动事件的默认行为 (即滚动行为) 将会立即触发v-model
<input v-model="inputValue">元素双向绑定的数据,与
v-bind类似,相比于前者,在组件封装中,使用v-model绑定的数据更偏向于组件的核心数据,如表单绑定的数据,输入框内的内容等。注意
v-model前不要加:,否则其实际意义将会变成v-bind:v-model,与一个普通的props无异。在组件内部进行接收或者监听时,都使用
value。另外,由于prop本身的单向传输性,当组件内部数据更新且需要返回给外部时,得使用$emit('input', value),以下为一个简单的v-model在组件内外双向绑定的写法export default { data() { return { innerValue: '', } } props: { value: [String, Number] }, watch: { value(newVal) { this.innerValue = newVal; }, innerValue(newVal) { this.$emit('input', newVal); } } }v-for
<div v-for="item in items" :key="item">{{item.content}}</div>export default { data() { return { items: [1,2,3] } } }操作dom的Vue指令,通过遍历一个数组来达到重复渲染当前元素的效果,如上述代码的实际渲染效果为
<div>1</div> <div>2</div> <div>3</div>在Vue2.x中,要注意想要触发dom的变化,就需要触发监听数组变化的钩子,而当数组内对象层级过深时,钩子将不会触发,于是会导致model层更新,而view层没有响应的情况,此时可以使用
$forceUpdate强制触发钩子。v-for的key属性,可以理解为一个主键,可用于提升dom重载时的性能。v-if与v-show
<div v-if="isDicShow">1</div> <span v-show="isSpanShow">2</span>与
v-if相伴的还有v-else-if与v-else,将作为v-if的一类一起讨论。v-if和v-show都通过赋值其的表达式的真假来控制所在元素的是否显示。两者的区别在于v-if绑定的表达式的真假性变化时,会导致元素的渲染或者销毁。而v-show仅仅是控制元素的display属性是否为none,绑定值为false时,我们依然可以通过审查元素找到该元素。关于两者的区别,其实是个老生常谈的问题,本质上,还是一个考虑性能的问题。v-if无初始渲染消耗,但有较高的切换消耗,v-show则相反。两者的使用要根据实际业务场景进行考量,对首次打开性能要求较高的界面,可以考虑使用
v-if,对于需要频繁切换的元素,则可以考虑使用v-show
v-cloak
<div class="demo-class" v-cloak>{{msg}}</div>[v-cloak] { display: none; }
在开启禁止浏览器缓存或者网络比较慢的时候,即vue.js 加载较慢的时候,由于Vue实例并没有编译完成,所以对于类似 {{msg}} 的 Mustache 标签会被直接展示出来。只有当 Vue 编译加载完成后,参数的真正内容才会被展示出来。这就导致了界面渲染时会有一小段时间的闪动问题。
而 v-cloak 主要就是用于优化这个用户体验的问题,用CSS选择器来操作拥有该指令的样式,设置其为 display:none ,那么在vue.js加载期间,该元素就不会被展示出来,直到 Vue 实例加载完毕。
事实上 v-cloak 指令在实际编码过程中,用到的机会还是比较少的。在较为大型、工程化的项目当中,都会使用 vue-router 实现路由挂载,所以在非首页加载的情况下,Vue实例都早已加载完成,此时就不再有使用该指令的必要。
v-pre
<div v-pre>{{msg}}</div>
拥有 v-pre 指令的元素与其子元素会直接跳过 Vue 的编译过程,当作普通的dom进行渲染。跳过编译过程一来可用于在必要的时候展示 {{msg}} 这类 Mustache 标签。二来可用于缩短一些不含需要编译内容的dom的加载时间,从而提高整个界面的加载效率。从实际使用情况来说,对性能的提升还是较为有限的,不过可以作为界面性能优化的一个方面加以实施。
v-once
<div v-once>{{msg}}</div>
同样是一个用于提高界面性能的指令,可以从字面意思来理解,使用v-once指令的元素只会被编译一次,也就是说类似于{{msg}}的标签内的参数会被正确展示出来,但有且仅有这一次渲染,若界面出现重新渲染,该元素就不再会进行编译,只会展示第一次编译的内容。该指令一般用于有需要编译的Vue语法,但其依旧为静态内容,所以仅需编译一次,可以与v-pre相区分。
自定义指令
Vue除去以上内置指令外,还可以让开发人员根据生产需要开发自定义指令。通过对内置指令的介绍,很容易可以认识到,指令的作用其实主要用于对于DOM元素的操作上。比如官方文档里给的一个例子,就是用于做输入框获取焦点的。
自定义指令与Vue-components类似,可以进行全局挂载。比如获取输入框焦点这类比较常见的交互场景,就可以作为一个全局的自定义指令进行挂载。
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})同样的,也可以仅在某个界面内进行局部挂载。
new Vue({
el: "#app",
directives: {
focus: {
inserted: function(el){
el.focus();
}
}
}
})对于指令功能的实现,与Vue实例类似,都具有一个完整的生命周期及其对应的钩子函数,指令的生命周期整体如下。
bind => inserted => update => componentUpdated => unbind对于生命周期的具体解释,以及钩子函数各个入参的含义,官方文档都已经给出了很明朗的解释,就不赘述。
另外,对于官方文档中提及的动态参数指令 v-mydirective:[argument]="value",即可以在指令上绑定一个[arguement]来作为组件实例更新的一个入参,由于入参是一个动态的参数,所以可使指令的定义更加灵活。以下例子中的dir就是一个传入的入参,对应于指令方法中的arg。
<div v-pin:[dir]="200"></div>Vue.directive('pin', {
bind: function (el, binding, vnode) {
el.style.position = 'fixed'
var s = (binding.arg == 'left' ? 'left' : 'top')
el.style[s] = binding.value + 'px'
}
})而其实指令等号后面的部分同样也可以作为一个动态的参数传入,所以当等号后面部分的参数更新时,在update钩子内进行更新,同样也可以实现动态参数指令的效果。
最后更新于
这有帮助吗?