Vue指令详解

57次阅读

共计 3290 个字符,预计需要花费 9 分钟才能阅读完成。

思维导图

指令
v-for
关于 key
官方解释:
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by=”$index”。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的唯一 id。这个特殊的属性相当于 Vue 1.x 的 track-by,但它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值 (在这里使用简写):
<div v-for=”item in items” :key=”item.id”>
<!– 内容 –>
</div>

建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。因为它是 Vue 识别节点的一个通用机制。
从虚拟 DOM 的 Diff 算法实现的角度:

比如我们希望可以在 B 和 C 之间加一个 F,Diff 算法默认执行起来是这样的:

即把 C 更新成 F,D 更新成 C,E 更新成 D,最后再插入 E,是不是很没有效率?
所以我们需要使用 key 来给每个节点做一个唯一标识,Diff 算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

所以一句话,key 的作用主要是为了高效的更新虚拟 DOM。
v-on
修饰符
.stop
调用 event.stopPropagation()。阻止冒泡
.prevent
调用 event.preventDefault()。取消事件的默认动作
该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作)。例如,如果 type 属性是 “submit”,在事件传播的任意阶段可以调用任意的事件句柄,通过调用该方法,可以阻止提交表单。注意,如果 Event 对象的 cancelable 属性是 fasle,那么就没有默认动作,或者不能阻止默认动作。无论哪种情况,调用该方法都没有作用。
.capture
添加事件侦听器时使用 capture 模式。(即是给元素添加一个监听器,当元素发生冒泡时,先触发带有该修饰符的元素。若有多个该修饰符,则由外而内触发。
就是谁有该事件修饰符,就先触发谁。)
.self
只当事件是从侦听器绑定的元素本身触发时才触发回调。(相当于忽略了其他元素的冒泡或者捕获事件)
.{keyCode | keyAlias}
只当事件是从特定键触发时才触发回调。
.native
监听组件根元素的原生事件。
.once
只触发一次回调。
.left – (2.2.0)
只当点击鼠标左键时触发。
.right – (2.2.0)
只当点击鼠标右键时触发
.middle – (2.2.0)
只当点击鼠标中键时触发
.passive – (2.3.0)
以 {passive: true} 模式添加侦听器,减少额外的监听,提高性能(表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。)
用于滚动性能优化 - 滚动事件的默认行为 (即滚动行为) 将会立即触发而不会等待 onScroll 完成 https://blog.csdn.net/shenlei…
v-model
<input v-model=”something”>

不过是以下实例的语法糖
<input
v-bind:value=”something”
v-on:input=”something = $event.target.value”>

所以在子组件可以这样写:
props: [‘value’],
data() {
return {
// 新建 props 属性副本
value_p: this.value
}
},
watch: {
// 监听 props 属性值,实时更新副本值
value(val) {
this.value_p = val
}
}
methods: {
valueChange() {
// 触发 Input 事件,将新增传递给父组件,父组件会自动更新
this.$emit(‘input’, this.value_p)
}
}

v-bind
修饰符.sync 可用于简化父子组件双向数据绑定
sync 修饰符在 vue2.0 被移除,在 vue2.3.0 被重新引入。但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 监听器。
<mod-alert :title.sync=”title”></mod-alert>
会被扩展成
<mod-alert :title=”title” @update:title=”title = $event”></mod-alert>
props: [‘title’], data() {
return {
// 新建 props 属性副本
title_p: this.title
}
},watch: {
// 监听 props 属性值,实时更新副本值
title(val) {
this.title_p = val
}
}methods: {
valueChange() {
// 值改变时显式地触发一个更新事件,父组件自动更新
this.$emit(‘update:title’, this.title_p)
}
}
v-once
只渲染元素和组件一次。随后的重新渲染,元素 / 组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
自定义指令
注册
全局注册
Vue.directive(‘focus’, { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el) {
// 聚焦元素
el.focus()
}})
局部注册
directives: {focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}}
钩子函数
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
钩子函数参数
el:指令所绑定的元素,可以用来直接操作 DOM。
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive=”1 + 1″ 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive=”1 + 1″ 中,表达式为 “1 + 1″。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 {foo: true, bar: true}。
vnode:Vue 编译生成的虚拟节点。
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
对象字面量
如果指令需要多个值,可以传入一个 JavaScript 对象字面量。记住,指令函数能够接受所有合法的 JavaScript 表达式。
<div v-demo=”{color: ‘white’, text: ‘hello!’}”></div>
Vue.directive(‘demo’, function (el, binding) {console.log(binding.value.color) // => “white” console.log(binding.value.text) // => “hello!”})

正文完
 0