指令
指令(Directives)是带有v-
前缀的特殊属性。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM。
v-if条件判断
1 | <template v-if="ok"> |
<template>
元素当做不可见的包裹元素
1 | <div v-if="type === 'A'">A</div> |
v-if是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
v-show显示判断
1 | <h1 v-show="ok">Hello!</h1> |
与v-if
不同,v-show只是进行CSS的变换。
v-bind属性绑定
1 | <a v-bind:href="url">...</a> |
绑定url到href,当url有变化可响应dom重渲染,可缩写成
1 | <a :href="url">...</a> |
v-on事件绑定
1 | <a v-on:click="doSomething">...</a> |
绑定doSomething函数到a标签的点击事件,可缩写成
1 | <a @click="doSomething">...</a> |
v-for循环
可循环渲染动态选项,数组形式
1 | <select v-model="selected"> |
与react不同,react需要使用map方法遍历返回组件,vue直接把循环挂在标签属性上。
对象形式
1 | data: { |
1 | <select v-model="selected"> |
修饰符
修饰符(Modifiers)是以半角句号.
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent
修饰符告诉v-on
指令对于触发的事件调用 event.preventDefault()
:
1 | <form v-on:submit.prevent="onSubmit">...</form> |
事件修饰符
.prevent
=>event.preventDefault()
.stop
=>event.stopPropagation()
.capture
使用事件捕获.self
只当在 event.target 是当前元素自身时触发处理函数,即事件不是从内部元素触发的.once
事件只触发一次
按键修饰符
1 | <!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` --> |
全部的按键别名:
- .enter
- .tab
- .delete (捕获“删除”和“退格”键)
- .esc
- .space
- .up
- .down
- .left
- .right
系统修饰键
- .ctrl
- .alt
- .shift
- .meta
在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。
.exact 修饰符
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
1 | <!-- 即使 Alt 或 Shift 被一同按下时也会触发 --> |
鼠标按钮修饰符
- .left
- .right
- .middle
这些修饰符会限制处理函数仅响应特定的鼠标按钮。
计算属性computed
基础例子如下
1 | <div id="example"> |
1 | var vm = new Vue({ |
computed下的reversedMessage
方法依赖data下的变量message,当message发生变量,reversedMessage会重新计算结果,与mobx中的computed的作用相同。
以上例子也可通过method
属性完成,如下
1 | <p>Reversed message: "{{ reversedMessage() }}"</p> |
1 | // 在组件中 |
不同的是计算属性是基于它们的依赖进行缓存的。
计算属性computed
也可同时设置setter和getter方法取代直接写funciton,如下:
1 | computed: { |
侦听器watch
1 | new Vue({ |
Class与Style
class的对象形式,与classnames模块类似
1 | <div v-bind:class="{ active: isActive }"></div> |
class数组形式
1 | <div v-bind:class="[activeClass, errorClass]"></div> |
1 | data: { |
class对象与数组混合使用
1 | <div v-bind:class="[{ active: isActive }, errorClass]"></div> |
在组件上使用
1 | Vue.component('my-component', { |
1 | <my-component class="baz boo"></my-component> |
结果为:
1 | <p class="foo bar baz boo">Hi</p> |
style对象形式
1 | <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> |
1 | data: { |
style数组形式
1 | <div v-bind:style="[baseStyles, overridingStyles]"></div> |
表单输入绑定
v-model
指令在表单input
及textarea
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。v-model会忽略所有表单元素的value、checked、selected特性的初始值而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值。
如:
1 | <input v-model="message" placeholder="edit me"> |
多行文本
1 | <span>Multiline message is:</span> |
.lazy
在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步。你可以添加 lazy 修饰符,从而转变为使用 change 事件进行同步:
1 | <!-- 在“change”时而非“input”时更新 --> |
.number
如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:
1 | <input v-model.number="age" type="number"> |
.trim
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:
1 | <input v-model.trim="msg"> |
组件
组件 (Component) 是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以表现为用is
特性进行了扩展的原生 HTML 元素。
请注意,对于自定义标签的命名Vue.js不强制遵循W3C规则 (小写,并且包含一个短杠),尽管这被认为是最佳实践。
全局注册组件
1 | Vue.component('my-component', { |
局部注册组件
1 | var Child = { |
由于html元素之间不能随意嵌套,如table、ul、ol,所以在自定义组件中使用这些受限制的元素时会导致一些问题,例如:
1 | <table> |
自定义组件is
特性:
1 | <table> |
但是如果代码来自以下字符串模板,则没有这个限制:
- <script type=”text/x-template”>
- JavaScript 内联模板字符串
- .vue 组件
data
必须是函数
声明的组件data必须为一个函数并返回响应数据,否则会出现警告并停止运行,声明比如类似如下:
1 | var data = { counter: 0 } |
Prop
与react类似,prop为传入组件的参数,属于单向数据流,如果是绑定了父组件的data,变化会引起DOM重渲染,声明组件时候需要声明预期的props,如下:
1 | Vue.component('child', { |
由于HTML不区分大小写,声明prop的时候我们需要声明为camelCase
驼峰命名形式,但是传入的时候必须写成kebab-case
短横线分隔式命名。如下:
1 |
|
1 | <!-- 在 HTML 中使用 kebab-case --> |
动态Prop
可以用 v-bind 来动态地将 prop 绑定到父组件的数据。每当父组件的数据变化时,该变化也会传导给子组件:
1 | <div id="prop-example-2"> |
1 | new Vue({ |
prop声明时可以指定特定规则,规范prop的格式,如:
1 | Vue.component('example', { |
type也可以是一个自定义构造器函数,使用instanceof
检测。
动态组件
通过使用保留的<component> 元素,并对其is
特性进行动态绑定,你可以在同一个挂载点动态切换多个组件:
1 | var vm = new Vue({ |
1 | <component v-bind:is="currentView"> |
也可以直接绑定到组件对象上:
1 | var Home = { |
插槽<slot>
<slot>类似于react中的props.children,可以替换输出父组件中传给子组件标签内的内容,如下:
假定 my-component 组件有如下模板:
1 | <div> |
父组件模板:
1 | <div> |
渲染结果:
1 | <div> |
<slot>元素可以用一个特殊的特性 name 来进一步配置如何分发内容。多个插槽可以有不同的名字。具名插槽将匹配内容片段中有对应slot特性的元素。
例如,假定我们有一个 app-layout 组件,它的模板为:
1 | <div class="container"> |
父组件模板:
1 | <app-layout> |
渲染结果为:
1 | <div class="container"> |
在设计组合使用的组件时,内容分发 API 是非常有用的机制。
子组件引用
但是有时仍然需要在JavaScript中直接访问子组件。与react类似,可以使用ref
为子组件指定一个引用ID。例如:
1 | <div id="parent"> |
1 | var parent = new Vue({ el: '#parent' }) |
当ref和v-for一起使用时,获取到的引用会是一个数组,包含和循环数据源对应的子组件。
自定义事件
使用 v-on 绑定自定义事件
- 使用 $on(eventName) 监听事件
- 使用 $emit(eventName, optionalPayload) 触发事件
例子如下:
1 | <div id="message-event-example" class="demo"> |
1 | Vue.component('button-message', { |
给组件绑定原生事件
可以使用v-on的修饰符.native
。例如:
1 | <my-component v-on:click.native="doTheThing"></my-component> |
.sync修饰符
该修饰符可以让一个prop变成”双向绑定”,如下
1 | <comp :foo.sync="bar"></comp> |
当comp内修改了foo变量时,父组件的foo也会同时被修改,该修饰符Vue2.0后被移除,在Vue2.3又被引入,只是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 监听器。如上例子会被扩展成:
1 | <comp :foo="bar" @update:foo="val => bar = val"></comp> |
当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:
1 | this.$emit('update:foo', newValue) |
自定义组件的v-model
默认情况下,一个组件的 v-model 会使用 value prop 和 input 事件。但是诸如单选框、复选框之类的输入类型可能把 value 用作了别的目的。model 选项可以避免这样的冲突:
1 | Vue.component('my-checkbox', { |
1 | <my-checkbox v-model="foo" value="some value"></my-checkbox> |
上述代码等价于:
1 | <my-checkbox |