Vue-基础-前端
本文最后更新于:2021年3月24日 下午
信息
Vue (读音 /vjuː/) 是一套用于构建用户界面的渐进式框架
与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合
- 渐进式
指你可以让已有的项目,一点一点的用来Vue取代实现,不用担心Vue框架的排它性
一些框架可能会强制你使用它的一些东西,使得这个框架与其它框架难以集成到一起- 组件化应用
组件系统是Vue的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用![]()
安装
Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性
直接用 <script>CDN引入
对于制作原型或学习,你可以这样使用最新版本
1 | |
对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:
1 | |
NPM
在用 Vue 构建大型应用时推荐使用 NPM 安装。NPM 能很好地和webpack打包器配合使用
1 | |
对不同构建版本的解释
在 NPM 包的 dist/ 目录会找到很多不同的 Vue.js 构建版本
| UMD | CommonJS | ES Module (基于构建工具使用) |
ES Module (直接用于浏览器) |
|
|---|---|---|---|---|
| 完整版 | vue.js | vue.common.js | vue.esm.js | vue.esm.browser.js |
| 只包含运行时版 | vue.runtime.js | vue.runtime.common.js | vue.runtime.esm.js | |
| 完整版 (生产环境) | vue.min.js | vue.esm.browser.min.js | ||
| 只包含运行时版 (生产环境) | vue.runtime.min.js |
- 完整版:同时包含编译器和运行时的版本。
- 编译器:用来将模板字符串编译成为 JavaScript 渲染函数的代码。
- 运行时:用来创建 Vue 实例、渲染并处理虚拟 DOM 等的代码。基本上就是除去编译器的其它一切。
版本类型说明
- UMD:UMD 版本可以通过
<script>标签直接用在浏览器中- CommonJS:CommonJS 版本用来配合老的打包工具
webpack 1- ES Module:为打包工具提供的 ESM
- 为诸如
webpack 2提供的现代打包工具
ESM 格式被设计为可以被静态分析,所以打包工具可以利用这一点来进行“tree-shaking”并将用不到的代码排除出最终的包。
为这些打包工具提供的默认文件 (pkg.module) 是只有运行时的 ES Module 构建 (vue.runtime.esm.js)- 为浏览器提供的 ESM (2.6+)
用于在现代浏览器中通过<script type="module">直接导入
浏览器调试插件Vue Devtools
Github: https://github.com/vuejs/vue-devtools#vue-devtools
寻找对应自己浏览器版本的调试插件安装即可
Hello World
创建一个HTML文件,在文件中引入Vue的CDN来使用Vue
1 | |
HTML中设置一个标签用于显示数据
编写模板代码
1 | |
Vue.js的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统
这样就已经成功创建了第一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作
现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。
要怎么确认呢?打开你的浏览器的控制台 (就在这个页面打开),并修改 app.message 的值
你将看到上例相应地更新
注意我们不再和 HTML 直接交互了
一个 Vue 应用会将其挂载到一个 DOM 元素上 (对于这个例子是 #app) 然后对其进行完全控制。那个 HTML 是我们的入口,但其余都会发生在新创建的 Vue 实例内部
其它的绑定
除了文本插值,我们还可以像这样来绑定元素 attribute
1 | |
1 | |
这里我们遇到了一点新东西。你看到的 v-bind attribute 被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊 attribute。它们会在渲染的 DOM 上应用特殊的响应式行为
在这里,该指令的意思是:“将这个元素节点的 title attribute 和 Vue 实例的 message property 保持一致”
类似的,这个内容也是响应式的
![]()
条件
控制切换一个元素是否显示
1 | |
1 | |

在控制台输入 app3.seen = false,你会发现之前显示的消息消失了。
这个例子演示了我们不仅可以把数据绑定到 DOM 文本或 attribute,还可以绑定到 DOM 结构
循环
v-for 指令可以绑定数组的数据来渲染一个项目列表
1 | |
1 | |
输入
事件监听器
可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法
1 | |
1 | |

注意在 reverseMessage 方法中,我们更新了应用的状态,但没有触碰 DOM
所有的 DOM 操作都由 Vue 来处理,你编写的代码只需要关注逻辑层面即可
双向绑定
Vue 提供了 v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定
1 | |
1 | |
组件
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用
在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。在 Vue 中注册组件很简单:
1 | |
1 | |
附带的观察整个流程(并非是运行流程),便于理解
<script>初始化
- 声明自定义的组件
<todo-item>- 初始化数据
groceryListHTML里的<todo-item>
v-for遍历groceryList中拿到数据,命名为item- ``v-bind:todo=”item”相当于
组件.todo = itemtodo-item根据定义的template计算出内容回填
尽管这只是一个刻意设计的例子,但是我们已经设法将应用分割成了两个更小的单元。
子单元通过prop接口与父单元进行了良好的解耦
现在可以进一步改进 <todo-item> 组件,提供更为复杂的模板和逻辑,而不会影响到父单元
Vue实例
每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的
1 | |
虽然没有完全遵循 MVVM 模型,但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的缩写) 这个变量名表示 Vue 实例
当创建一个 Vue 实例时,你可以传入一个选项对象。这个篇章主要描述的就是如何使用这些选项来创建你想要的行为。作为参考,你也可以在 API 文档 中浏览完整的选项列表
一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成
举个例子,一个 todo 应用的组件树可以是这样的:
1 | |
所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外)
数据与方法
当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中
当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值
1 | |
当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时就已经存在于 data 中的 property 才是响应式的
也就是说如果你在创建以后再去添加一个新的
property,比如:
1 | |
那么对
b的改动将不会触发任何视图的更新
如果你知道你会在晚些时候需要一个 property,但是一开始它为空或不存在,那么你需要设置一些初始值,以确保它是响应式的
1 | |
冻结
Object.freeze()会阻止修改现有的 property,也意味着响应系统无法再追踪变化
1 | |
1 | |
前缀$
除了数据 property,Vue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 $,以便与用户定义的 property 区分开来
1 | |
可以在 API 中查阅到完整的实例 property 和方法的列表
生命周期
生命周期钩子
每个Vue实例在被创建时都要经过一系列的初始化过程
例如,需要设置数据监听、编译模板、将实例挂载到
DOM并在数据变化时更新DOM等
同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会
比如 created 钩子可以用来在一个实例被创建之后执行代码:
1 | |
也有一些其它的钩子,在实例生命周期的不同阶段被调用。如 mounted、updated 和 destroyed
生命周期钩子的 this 上下文指向调用它的 Vue 实例
注意:不要在选项
property或回调上使用箭头函数比如
created: () => console.log(this.a)
vm.$watch(‘a’, newValue => this.myMethod())。因为箭头函数并没有
this,this会作为变量一直向上级词法作用域查找,直至找到为止
这经常导致Uncaught TypeError: Cannot read property of undefined或Uncaught TypeError: this.myMethod is not a function之类的错误
生命周期图例

图例上说明了可以使用的钩子函数(红框红字)与生命周期过程
以后遇到问题可以作为参考
模板语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据
所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少
插值
顾名思义,就是往HTML中插入一些内容,以填充页面
普通文本 - “Mustache”语法 (双大括号)
向HTML中插入变量的值
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值
- 无法对元素属性使用
- 插入的HTML内容不会被当做元素,只会当做普通字符串
1 | |
Mustache 标签将会被替代为对应数据对象上 msg property 的值
无论何时,绑定的数据对象上 msg property 发生了改变,插值处的内容都会更新
插值固定 - v-once 指令
用于影响插值,在此指令范围内的文本插值后不会因其原本变量值改变而改变
1 | |
HTML内容 - v-html 指令
用于插入HTML内容
双大括号会将数据解释为普通文本,要插入HTML内容,需要用这个v-html 指令
1 | |
这个 span 的内容将会被替换成为 property 值 rawHtml,直接作为 HTML(忽略解析 property 值中的数据绑定)
注意,你不能使用 v-html 来复合局部模板,因为 Vue 不是基于字符串的模板引擎。反之,对于用户界面 (UI),组件更适合作为可重用和可组合的基本单位
你的站点上动态渲染的任意
HTML可能会非常危险,因为它很容易导致XSS 攻击。请只对可信内容使用HTML插值,绝不要对用户提供的内容使用插值
元素属性插值 - v-bind 指令
用于绑定内容与目标元素的属性
Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind 指令
1 | |
对于布尔 attribute (它们只要存在就意味着值为 true),v-bind 工作起来略有不同
1 | |
如果isButtonDisabled 的值是 null、undefined 或 false,则 disabled attribute 甚至不会被包含在渲染出来的 <button> 元素中
JavaScript 表达式
实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持
1 | |
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式
下面的例子都不会生效
- 是语句,不是表达式
{{ var a = 1 }}- 流控制也不会生效,请使用三元表达式
{{ if (ok) { return message } }}
模板表达式都被放在沙盒中,只能访问一些特定的全局变量,如 Math 和 Date
你不应该在模板表达式中访问用户定义的全局变量
指令
指令 (Directives) 是带有 v- 前缀的特殊 attribute
指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)
指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
参数
一些指令能够接收一个“参数”,在指令名称之后以冒号表示
例:
v-bind指令可以用于响应式地更新HTML attribute
1 | |
在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定
例:
v-on指令,它用于监听 `DOM 事件
1 | |
在这里参数是监听的事件名
动态参数
可以用方括号括起来的 JavaScript 表达式作为一个指令的参数
例:
1 | |
如果你的 Vue 实例有一个 data property attributeName,其值为 “href”,那么这个绑定将等价于 v-bind:href
这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用
同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:
例:
1 | |
当 eventName 的值为 “focus” 时,v-on:[eventName] 将等价于 v-on:focus
约束
对动态参数的值的约束
- null
动态参数预期会求出一个字符串,异常情况下值为null
这个特殊的null值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。
对动态参数表达式的约束
特殊符号约束
动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在HTML attribute名里是无效的例:
1
2<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式
大小写约束
在DOM中使用模板时 (直接在一个HTML文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把attribute名全部强制转为小写例:
1
2
3
4
5<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
-->
<a v-bind:[someAttr]="value"> ... </a>修饰符
修饰符 (modifier) 是以半角句号
.指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用
event.preventDefault()1
<form v-on:submit.prevent="onSubmit">...</form>缩写
v-前缀作为一种视觉提示,用来识别模板中Vue特定的attributeVue为v-bind和v-on这两个最常用的指令,提供了特定简写
v-bind 缩写
1 | |
v-on 缩写
1 | |
它们看起来可能与普通的 HTML 略有不同,但 : 与 @ 对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析
它们不会出现在最终渲染的标记中
计算属性和侦听器
计算属性
模板表达式 与 计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的
在模板中放入太多的逻辑会让模板过重且难以维护
1 | |
在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量
message的翻转字符串
当你想要在模板中多包含此处的翻转字符串时,就会更加难以处理
对于任何复杂逻辑,你都应当使用计算属性
计算属性
1 | |
1 | |
这里声明了一个 “计算反转的vm.message字符串的函数” 传入到 计算属性 reversedMessage
提供的函数将用作 property vm.reversedMessage 的 getter 函数
计算属性 reversedMessage 的结果是响应式的
reversedMessage的值始终取决于vm.message的值![]()
你可以像绑定普通 property 一样在模板中绑定计算属性Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新
而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解
计算属性的 setter
计算属性默认只有 getter,不过在需要时你也可以提供一个 setter
1 | |
运行 vm.fullName = 'John Doe' 时,setter 会被调用
因此vm.firstName 和 vm.lastName 也会相应地被更新。
计算属性缓存 与 方法
你可能会想到:通过 在表达式中调用方法 来达到和 计算属性 同样的效果
1 | |
1 | |
两种方式的最终结果确实是完全相同的
不同的是 计算属性 是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值
只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而会再次执行函数
可能造成的问题
下面的计算属性将不再更新,因为Date.now()不是响应式依赖
1 | |
| 计算属性 | 方法 | |
|---|---|---|
| 更新结果 | 依赖更新时更新 否则从缓存中得到上次的计算结果 |
每次运行都更新 |
| 资源消耗 | 小 | 大 |
| 速度 | 较快 | 较慢 |
计算属性 vs 侦听属性
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性(watch)
但通常计算属性 能够取代 命令式的 watch回调,并且让代码更优美
例:姓更变 或 名更变 时 自动计算全名
1 | |
此处用
watch实现
1 | |
此处用
计算属性实现
1 | |
对比而言,
计算属性的代码就优美很多
侦听器
Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化
当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
例:异步
Ajax请求
1 | |
使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的
1 | |
除了 watch 选项之外,还可以使用命令式的 vm.$watch API
Class 与 Style绑定
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。它们都是 attribute,所以可以用 v-bind 处理它们
在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组
绑定 HTML Class
对象语法
多字段设置
可以传给 v-bind:class 多个字段,以动态地切换 class
1 | |
v-bind:class 指令也可以与普通的 class attribute 共存,最终得到的结果会是它们拼接在一起的样子
多字段来动态切换Class
1 | |
会得到这样的渲染结果
static activate
类似的,这样设置的样式是响应式的,如果修改isActive与hasError设置的内容也会相应的做出改变
单对象
与上面的多个字段类似,可以在一个对象中设置多个属性(作为字段),来进行class的切换
单个对象来动态切换class
1 | |
会得到和上面的例子一样的的结果
数组语法
可以把一个数组传给 v-bind:class,以应用一个 class 列表
数组来动态切换class
1 | |
最终渲染结果为
class="active text-danger"![]()
你可以在数组中填入表达式,但这会造成内容的不美观,不建议那样做
绑定内联样式 style
v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名
多字段设置style
1 | |
最终得到的
style="color: red; font-size: 30px;"![]()
对象设置Style
类似的,v-bind:style可以在一个或多个对象中设置属性(作为字段),来进行style的设置
单个对象设置 style
1 | |
得到的结果与上个例子一致:
style="color: red; font-size: 30px;"
对于希望设置多个对象到元素上时,需要用数组括起来
多个对象设置 style
1 | |
得到的结果与上个例子一致:
style="color: red; font-size: 30px;"
自动添加前缀
当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transform,Vue.js 会自动侦测并添加相应的前缀
多重值
可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,这样写只会渲染数组中最后一个被浏览器支持的值
包含多个值的 preoperty 数组
1 | |
如果此处浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex
条件渲染
v-if 与 v-else
v-if 指令用于条件性地渲染一块内容
这块内容只会在指令的表达式返回 truthy 值的时候被渲染
v-else 指令来表示 v-if 的 “else 块”v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别
v-if与v-else的基本使用方式
1 | |
依旧,这个渲染是响应式的,而且在状态发生改变之前,页面上不会有多余的元素(并不是hide,而是完全没有)
v-if 与 v-for 一起使用
不推荐同时使用 v-if 和 v-for。请查阅风格指南以获取更多信息
当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。请查阅列表渲染指南以获取详细信息。
v-else-if
v-else-if,顾名思义,其作用就相当于马上在else后接一个if判断
类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后
v-else-if的使用方式
1 | |
用 key 管理可复用的元素
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染 这么做除了使 Vue 变得非常快之外,还有其它一些现象
尽可能复用:用户在不同的登录方式之间切换
1 | |

切换 loginType 将不会清除用户已经输入的内容
两个模板都使用了相同的元素<input>。因为vue总是希望尽可能复用,这个元素不会被替换掉(此处仅替换了它的 placeholder属性)
这会造成一些问题,一般切换输入类型都需要将已输入内容清空,而这里没清
如果不希望vue最大程度复用,那么可以为元素添加key属性
需要注意,key属性需要一个唯一值
独立的key:用户在不同的登录方式之间切换
1 | |
在设置了key后,模板内容会被重新渲染后才放到页面上。所以输入的内容消失了
v-show
另一个用于根据条件展示元素的选项是 v-show 指令
用法与 v-if 类似,都是表达式返回 truthy 值的时候被渲染
不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中v-show 只是简单地切换元素的 CSS property display
注意,v-show 不支持 <template> 元素,也不支持 v-else
v-show的使用
1 | |
v-if 对比 v-show
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销 因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好
列表渲染
v-for 对应数组
可以用 v-for 指令基于一个数组来渲染一个列表v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名
v-for对应数组到元素v-for还支持一个可选的第二个参数,即当前项的索引
1 | |
v-for 对应对象
可以用 v-for 来遍历一个对象的 property
1 | |
维护状态
当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略
如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染
这个默认的模式是高效的,但是只适用于 不依赖子组件状态 或 临时 DOM 状态 (例如:表单输入值) 的列表渲染输出
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute:
1 | |
建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升
因为它是 Vue 识别节点的一个通用机制,key 并不仅与 v-for 特别关联。后面我们将在指南中看到,它还具有其它用途
不要使用对象或数组之类的非基本类型值作为
v-for的key。请用字符串或数值类型的值
更多 key attribute 的细节用法请移步至 key 的 API 文档
数组更新检测
变更方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新
这些被包裹过的方法包括:
- push()、pop()
- shift()、unshift()
- splice()
- sort()
- reverse()
你可以打开控制台,然后对前面例子的 items 数组尝试调用变更方法。比如 example1.items.push({ message: 'Baz' })
替换数组
变更方法,顾名思义,会变更调用了这些方法的原始数组
相比之下,也有非变更方法,例如 filter()、concat() 和 slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:
1 | |
这并不会导致 Vue 丢弃现有 DOM 并重新渲染整个列表。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作
注意事项
由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。深入响应式原理 中有相关的讨论
显示过滤/排序后的结果
有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组
例如:
1 | |
在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个方法:
1 | |
在 v-for 中使用值范围
v-for 可以接受整数,这种情况下,它会把模板重复对应次数
1 | |
在 <template> 上使用 v-for
类似于 v-if,你也可以利用带有 v-for 的 <template> 来循环渲染一段包含多个元素的内容。比如:
1 | |
v-for 与 v-if 一同使用
注意:不推荐在同一元素上使用 v-if 和 v-for
当它们处于同一节点,v-for 的优先级比 v-if 更高
这意味着 v-if 将分别重复运行于每个 v-for 循环中
当你只想为部分项渲染节点时,这种优先级的机制会十分有用
例:只渲染未完成的 todo
1 | |
事件处理
监听事件
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码
1 | |
事件处理方法
许多事件处理逻辑会更为复杂,把 JavaScript 代码直接写在 v-on 指令中是不可行的v-on 可以接收一个需要调用的方法名称
示例:
1 | |
内联处理器中的方法
除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法
1 | |
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法
1 | |
事件修饰符
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求
尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节
为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的
.stop.prevent.capture.self.once.passive
1 | |
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生
因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击
注意:不要把
.passive和.prevent一起使用,因为.prevent将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive会告诉浏览器你不想阻止事件的默认行为
按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
1 | |
你可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符
1 | |
在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用
表单输入绑定
基础用法
你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素
尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理
注意:
v-model会忽略所有表单元素的value、checked、selectedattribute 的初始值而总是将 Vue 实例的数据作为数据来源
你应该通过 JavaScript 在组件的 data 选项中声明初始值
v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
text 和 textarea 元素使用 value property 和 input 事件
checkbox 和 radio 使用 checked property 和 change 事件
select 字段将 value 作为 prop 并将 change 作为事件
注:对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model 不会在输入法组合文字过程中得到更新。如果你也想处理这个过程,请使用 input 事件
文本
1 | |
多行文本
1 | |
在文本区域插值 (
<textarea>{{text}}</textarea>) 并不会生效,应用v-model来代替
复选框
对于单个复选框,可以绑定到布尔值中
1 | |
对于多个复选框,可以绑定到同一个数组中
1 | |
1 | |
单选按钮
1 | |
1 | |
选择框
单选时
1 | |
1 | |
注意:如果
v-model表达式的初始值未能匹配任何选项,<select>元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发change事件。因此,更推荐像上面这样提供一个值为空的禁用选项
多选时 (绑定到一个数组):
1 | |
1 | |
值绑定
对于单选按钮,复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值)
1 | |
但是有时我们可能想把值绑定到 Vue 实例的一个动态 property 上,这时可以用 v-bind 实现,并且这个 property 的值可以不是字符串
1 | |
1 | |
这里的
true-value和false-valueattribute 并不会影响输入控件的valueattribute,因为浏览器在提交表单时并不会包含未被选中的复选框
如果要确保表单中这两个值中的一个能够被提交,(即“yes”或“no”),请换用单选按钮
单选按钮绑定
1 | |
1 | |
选择框选项绑定
1 | |
1 | |
修饰符
.lazy
默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加lazy修饰符,从而转为在change事件_之后_进行同步:1
2<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">.number
如果想自动将用户的输入值转为数值类型,可以给v-model添加number修饰符:1
<input v-model.number="age" type="number">这通常很有用,因为即使在
type="number"时,HTML 输入元素的值也总会返回字符串。如果这个值无法被parseFloat()解析,则会返回原始的值.trim
如果要自动过滤用户输入的首尾空白字符,可以给v-model添加trim修饰符:1
<input v-model.trim="msg">
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!



