descripation:当点击父元素的时候,执行 doThis ,当点击子元素 a 的时候,这个点击动作不单单触发了 a 标签,同时也触发了div标签,这就是事件冒泡,所以假设上述例子中 a 标签为v-on:click='doThis',则 doThis 会被执行两次,父元素和子元素都执行了一次 click 事件,而 .stop 则是阻止事件冒泡,再次点击 a 标签,click 事件只会执行一次.
<script>
// 注册一个全局自定义指令v-focus
Vue.directive('focus', {
// 当绑定元素插入到DOM中
inserted: function (el) {
// 聚焦元素
el.focus()
}
//聚焦不到元素
bind: function(el){
el.focus()
}
});
var app = new Vue({
el: '#app'
});
</script>
description: 以上例子中,如果将代码写在 bind 钩子函数内,el.focus() 并未生效,这是因为在 bind 钩子函数被调用时,虽然能够通过 bind 的第一个参数 el 拿到对应的 DOM 元素,但是此刻该 DOM 元素还未被插入进 DOM 树中,因此在这个时候执行 el.focus() 是无效的。
当 DOM 元素被插入进 DOM 树中时,inserted 钩子就会被调用,因此在 inserted 中执行 el.focus() 是可以生效的。
update 和 componentUpdated 的区别
update: function (el, binding, vnode) {
console.log('update')
console.log(el.innerHTML) // Hello
},
componentUpdated: function (el, binding, vnode) {
console.log('componentUpdated')
console.log(el.innerHTML) // Hi
}
update 钩子函数触发时机是自定义指令所在组件的 VNode 更新时, componentUpdated 触发时机是指令所在组件的 VNode 及其子 VNode 全部更新后。此处使用 el.innerHTML 获取 data 值,从运行结果上看 update 和 componentUpdated 是 DOM 更新前和更新后的区别。
谈到 Vue 指令,我们脑海里浮现的第一个疑问便是 指令 是什么:
指令是告诉计算机从事某一特殊运算的代码。如:数据传送指令、算术运算指令、位运算指令、程序流程控制指令、串操作指令、处理器控制指令。
那么 Vue 指令又是什么呢?是用来干什么的?作为一名攻城狮的我们又如何去使用它?
Vue 内置指令
1. 内置指令的使用
v-if
:根据其后表达式的 bool 值进行判断是否渲染该元素v-show
:其后表达式的 bool 值为 false 时,对渲染的出标签添加display:none;
的样式v-else
:紧跟着v-if或者v-show一起使用v-for
:v-for的用法 person in people ,前者是后者的元素,类似于数组的用法v-bind:(:)
:用于响应地更新 html 特性v-on:(@)
:用于监听指定元素的 DOM 事件v-once
:一次性插入文本,随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。v-html
:输出 {{ message }} 内包含 html 代码的数据tips: 不能使用 v-html 来复合局部模板,因为 Vue 不是基于字符串的模板引擎,反之,对于用户界面(UI),组件更适合作为可重用和可组合的基本单位。另外,只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值,避免xss攻击。
2. 修饰符
一般用于指出 v-on 指令以特殊方式绑定
事件修饰符
descripation:当点击父元素的时候,执行 doThis ,当点击子元素 a 的时候,这个点击动作不单单触发了 a 标签,同时也触发了div标签,这就是事件冒泡,所以假设上述例子中 a 标签为
v-on:click='doThis'
,则 doThis 会被执行两次,父元素和子元素都执行了一次 click 事件,而 .stop 则是阻止事件冒泡,再次点击 a 标签,click 事件只会执行一次.按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:
按键别名包括:
.enter
.tab
.delete
(捕获 “删除” 和 “退格” 键).esc
.space
.up
.down
.left
.right
.ctrl
.shift
.meta
(windows 键,mac-command 键,)Vue自定义指令
Vue 推崇数据驱动视图的理念(数据交互,状态管理),但并非所有情况都适合数据驱动( DOM 的操作)。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的 DOM 操作,并且是可复用的。
1. 定义Vue指令的方法
description: 传入两个参数,指令ID和定义对象,定义对象提供了一些钩子函数。
2. 钩子函数
当只是用到 update 函数的时候,可以简化写法
目前,对 5个钩子函数的触发时机有了初步的认识。存疑的是 bind 和 inserted、update 和 componentUpdated 的区别了。
description: 以上例子中,如果将代码写在
bind
钩子函数内,el.focus()
并未生效,这是因为在bind
钩子函数被调用时,虽然能够通过 bind 的第一个参数 el 拿到对应的 DOM 元素,但是此刻该 DOM 元素还未被插入进 DOM 树中,因此在这个时候执行el.focus()
是无效的。当 DOM 元素被插入进 DOM 树中时,
inserted
钩子就会被调用,因此在 inserted 中执行el.focus()
是可以生效的。update
钩子函数触发时机是自定义指令所在组件的 VNode 更新时,componentUpdated
触发时机是指令所在组件的 VNode 及其子 VNode 全部更新后。此处使用el.innerHTML
获取 data 值,从运行结果上看 update 和 componentUpdated 是 DOM 更新前和更新后的区别。3. 参数所包含属性的意义
所有的钩子函数会被复制到实际的指令对象中,而这个指令对象将会是所有钩子函数的this上下文环境。指令对象上暴露了一些有用的公开属性。
v-directive="1 + 1"
,value 的值是2
。v-directive="1 + 1"
, expression 的值是"1 + 1"
。v-directive:foo, arg
的值是"foo"
。v-directive.foo.bar
, 修饰符对象 modifiers 的值是{ foo: true, bar: true }
。tips: 这些属性是只读的,不要修改它们。你也可以给指令对象附加自定义的属性,但是注意不要覆盖已有的内部属性。
eg: 定义一个使用了 binding 参数的指令,以下的是都是生成的虚拟的节点,插入到
div:#example3
节点中:Vue自定义指令优先级顺序
系统默认指令会先于自定义指令执行
自定义指令在标签上的位置越靠前就越早执行
定义这两个简单的指令
Vue指令的用途
1. 用来操作DOM
尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的 DOM 操作,并且是可复用的。
eg: 很多时候我们会遇到图片加载慢的问题,那么,在图片未完成加载前,可以用随机的背景色占位,图片加载完成后才直接渲染出来。˙这里,用自定义指令可以非常方便的实现这个功能。
tips: 本例的调试需要在控制台上如下操作:
Network
->Offline Oline
->Slow 3G
,在网络延迟的情况下更容易看出占位效果来。2. 用于集成第三方插件
eg: 写文档通常会用到 highlight.js,我们可以直接将其封装为一个自定义指令,这样 highlight.js 就变成了 Vue 的一个新功能。
运行结果:
输出
<alert-menu>
标签里的所有内容,而且按照 html 的高亮显示规则显示。tips: 所以但凡遇到第三方插件如何与 Vue.js 集成的问题,都可以尝试用自定义指令实现。
Vue指令和Vue组件之间的关系
很多时候,对于初学者来说,看完指令的使用会发现组件的使用和指令的自定义有几分相似之处。其实,并非如此,组件和指令完全不是一个层级上的概念。打个比方:组件是一个房子,它可以嵌套使用,房子里边又有窗户,门,桌子,床,柜子等这些子组件。而指令是附着在组件上的某种行为或者功能,门和窗户可以打开关闭,桌子可以折叠,柜子可以打开关上等等。以下是对于组件和指令的定义,希望能够让大家更清晰的理解:
组件:一般是指一个独立实体,组件之间的关系通常都是树状。
Vue指令:用以改写某个组件的默认行为,或者增强使其获得额外功能,一般来说可以在同一个组件上叠加若干个指令,使其获得多种功能。比如 v-if,它可以安装或者卸载组件。
最佳实践
根据需求的不同,我们要选择恰当的时机去初始化指令、更新指令调用参数以及释放指令存在时的内存占用等。一个健壮的库通常会包含:初始化实例、参数更新和释放实例资源占用等操作。
总结回顾
通过以上 Vue 指令的学习,以及诸多 demo 的实现,我们便可清晰的认识 Vue 指令了,并且能逐一解答我们最开始内心的疑虑了:
Vue 指令就是以 “v-” 开头,作用于 DOM ,为 DOM 添加特殊行为的一种指令。
自定义指令则是对 Vue 指令的一种有效的补充和扩展,不仅可用于定义任何的 DOM 操作,并且是可复用的。
Vue 指令使用大部分是和组件结合着使用,从而增强组件的功能。甚至部分 Vue 指令能够直接安装卸载组件,例如
v-if
。Vue 自定义指令最重要的是我们对
bind
inserted
update
componentUpdated
unbind
五个钩子函数的理解,以及对钩子函数中el
binding
(属性值)vnode
oldVnode
四个参数的使用,只要这些内容能够熟练使用,我们便可以自己去定义适合各种开发场景的 Vue 指令了。