Vue指令详解

思维导图

《Vue指令详解》

指令

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算法实现的角度:

《Vue指令详解》

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

《Vue指令详解》

即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?

所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

《Vue指令详解》

所以一句话,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!”
})

    原文作者:你是七月的雨
    原文地址: https://segmentfault.com/a/1190000018381467
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞