2083 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			2083 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
Vue 2 备忘清单
 | 
						||
===
 | 
						||
 | 
						||
渐进式 JavaScript 框架 [Vue 2](https://v2.cn.vuejs.org/) 备忘清单的快速参考列表,包含常用 API 和示例。
 | 
						||
 | 
						||
入门
 | 
						||
---
 | 
						||
 | 
						||
### 介绍
 | 
						||
 | 
						||
Vue 是一套用于构建用户界面的渐进式框架
 | 
						||
 | 
						||
- [Vue 2.x 官方文档](https://v2.cn.vuejs.org/) _(v2.cn.vuejs.org)_
 | 
						||
- [Vue Router 3.x 官方文档](https://v3.router.vuejs.org/) _(v3.router.vuejs.org)_
 | 
						||
- [Vue 3 备忘清单](./vue.md)
 | 
						||
<!--rehype:className=style-round-->
 | 
						||
 | 
						||
注意:Vue 2.x 版本对应 Vue Router 3.x 路由版本
 | 
						||
 | 
						||
#### 快速创建 **Vue** 项目
 | 
						||
 | 
						||
```bash
 | 
						||
npx @vue/cli create hello-world
 | 
						||
```
 | 
						||
 | 
						||
参考: [Vue CLI](https://cli.vuejs.org/zh/guide/creating-a-project.html) 创建一个项目
 | 
						||
 | 
						||
### 声明式渲染
 | 
						||
 | 
						||
```html
 | 
						||
<div id="app">
 | 
						||
  {{ message }}
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
var app = new Vue({
 | 
						||
  el: '#app',
 | 
						||
  data: {
 | 
						||
    message: 'Hello Vue!'
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 基础例子
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<div id="example">
 | 
						||
  <p>原始信息: "{{ message }}"</p>
 | 
						||
  <p>
 | 
						||
    计算的反向信息: "{{ reversedMessage }}"
 | 
						||
  </p>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
var vm = new Vue({
 | 
						||
  el: '#example',
 | 
						||
  data: {
 | 
						||
    message: 'Hello'
 | 
						||
  },
 | 
						||
  computed: {
 | 
						||
    // 计算属性的 getter
 | 
						||
    reversedMessage: function () {
 | 
						||
      // `this` 指向 vm 实例
 | 
						||
      return this.message.split('')
 | 
						||
          .reverse().join('')
 | 
						||
    }
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
结果
 | 
						||
 | 
						||
```
 | 
						||
原始信息:  "Hello"
 | 
						||
计算的反向信息:  "olleH"
 | 
						||
```
 | 
						||
 | 
						||
### 绑定元素属性
 | 
						||
 | 
						||
```html
 | 
						||
<div id="app-2">
 | 
						||
  <span v-bind:title="message">
 | 
						||
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
 | 
						||
  </span>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
var app2 = new Vue({
 | 
						||
  el: '#app-2',
 | 
						||
  data: {
 | 
						||
    message: '页面加载于 ' + new Date()
 | 
						||
        .toLocaleString()
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 条件
 | 
						||
 | 
						||
```html
 | 
						||
<div id="app-3">
 | 
						||
  <p v-if="seen">现在你看到我了</p>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
var app3 = new Vue({
 | 
						||
  el: '#app-3',
 | 
						||
  data: {
 | 
						||
    seen: true
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
控制切换一个元素是否显示
 | 
						||
 | 
						||
### 循环
 | 
						||
 | 
						||
```html
 | 
						||
<div id="app-4">
 | 
						||
  <ol>
 | 
						||
    <li v-for="todo in todos">
 | 
						||
      {{ todo.text }}
 | 
						||
    </li>
 | 
						||
  </ol>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
var app4 = new Vue({
 | 
						||
  el: '#app-4',
 | 
						||
  data: {
 | 
						||
    todos: [
 | 
						||
      { text: '学习 JavaScript' },
 | 
						||
      { text: '学习 Vue' },
 | 
						||
      { text: '整个牛项目' }
 | 
						||
    ]
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 点击事件处理
 | 
						||
 | 
						||
```html
 | 
						||
<div id="app-5">
 | 
						||
  <p>{{ message }}</p>
 | 
						||
  <button v-on:click="reverseMessage">
 | 
						||
    反转消息
 | 
						||
  </button>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
var app5 = new Vue({
 | 
						||
  el: '#app-5',
 | 
						||
  data: {
 | 
						||
    message: 'Hello Vue.js!'
 | 
						||
  },
 | 
						||
  methods: {
 | 
						||
    reverseMessage: function () {
 | 
						||
      this.message = this.message.split('')
 | 
						||
            .reverse().join('')
 | 
						||
    }
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 输入事件处理
 | 
						||
 | 
						||
```html
 | 
						||
<div id="app-6">
 | 
						||
  <p>{{ message }}</p>
 | 
						||
  <input v-model="message">
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
`v-model` 指令,它能轻松实现表单输入和应用状态之间的双向绑定
 | 
						||
 | 
						||
```js
 | 
						||
var app6 = new Vue({
 | 
						||
  el: '#app-6',
 | 
						||
  data: {
 | 
						||
    message: 'Hello Vue!'
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
模板语法
 | 
						||
---
 | 
						||
 | 
						||
### 文本
 | 
						||
 | 
						||
```html
 | 
						||
<span>Message: {{ msg }}</span>
 | 
						||
<span v-once>
 | 
						||
  这个将不会改变: {{ msg }}
 | 
						||
</span>
 | 
						||
```
 | 
						||
 | 
						||
使用 `v-once` 指令,执行一次性地插值,当数据改变时,插值处的内容不会更新
 | 
						||
 | 
						||
### 原始 HTML
 | 
						||
 | 
						||
```html
 | 
						||
<p>解释为普通文本: {{ rawHtml }}</p>
 | 
						||
<p>
 | 
						||
  使用 v-html 指令: 
 | 
						||
  <span v-html="rawHtml"></span>
 | 
						||
</p>
 | 
						||
```
 | 
						||
 | 
						||
使用 `v-html` 指令,输出真正的 `HTML`
 | 
						||
 | 
						||
### 属性
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:id="dynamicId"></div>
 | 
						||
<button v-bind:disabled="isDisabled">
 | 
						||
  Button
 | 
						||
</button>
 | 
						||
```
 | 
						||
 | 
						||
如果 `isDisabled` 的值是 null/undefined/false 则 `disabled` 不会被渲染出来
 | 
						||
 | 
						||
### JavaScript 表达式
 | 
						||
 | 
						||
```html
 | 
						||
<div id="app">
 | 
						||
  <span>消息: {{ msg }}</span>
 | 
						||
  <span>{{ msg + '这是字符串' }}</span>
 | 
						||
  <span>{{ isWorking ? '是':'否' }}</span>
 | 
						||
  <span>{{ msg.getDetials() }}</span>
 | 
						||
  <div v-bind:id="'list-' + id"></div>
 | 
						||
<div>
 | 
						||
```
 | 
						||
 | 
						||
### 指令
 | 
						||
 | 
						||
```html
 | 
						||
<p v-if="seen">
 | 
						||
  现在你看到我了
 | 
						||
</p>
 | 
						||
```
 | 
						||
 | 
						||
`v-if` 指令将根据表达式 `seen` 的值的真假来插入/移除 \<p> 元素
 | 
						||
 | 
						||
### 指令参数
 | 
						||
 | 
						||
```html
 | 
						||
<a v-bind:href="url">...</a>
 | 
						||
```
 | 
						||
 | 
						||
`v-bind` 指令将该元素 `href` 属性与表达式 `url` 的值绑定
 | 
						||
 | 
						||
```html
 | 
						||
<a v-on:click="doSomething">...</a>
 | 
						||
```
 | 
						||
 | 
						||
`v-on` 指令,用于监听 DOM 事件,oSomething 是事件名
 | 
						||
 | 
						||
### 指令动态参数 **v2.6**
 | 
						||
 | 
						||
```html
 | 
						||
<a v-on:[eventName]="doSomething">...</a>
 | 
						||
```
 | 
						||
 | 
						||
当 `eventName` 的值为 `focus` 时,`v-on:[eventName]` 将等价于 `v-on:focus`
 | 
						||
 | 
						||
### 指令修饰符
 | 
						||
 | 
						||
```html
 | 
						||
<form v-on:submit.prevent="onSubmit">
 | 
						||
  ...
 | 
						||
</form>
 | 
						||
```
 | 
						||
 | 
						||
`.prevent` 修饰符告诉 `v-on` 指令对于触发的事件调用 `event.preventDefault()`
 | 
						||
 | 
						||
### 指令缩写
 | 
						||
 | 
						||
```html
 | 
						||
<!-- 完整语法 -->
 | 
						||
<a v-bind:href="url">...</a>
 | 
						||
<!-- 缩写 -->
 | 
						||
<a :href="url">...</a>
 | 
						||
<!-- 动态参数的缩写 (2.6.0+) -->
 | 
						||
<a :[key]="url"> ... </a>
 | 
						||
```
 | 
						||
 | 
						||
Class 与 Style 绑定
 | 
						||
---
 | 
						||
 | 
						||
### 对象语法
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:class="{ active: isActive }">
 | 
						||
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
传给 `v-bind:class` 一个对象,以动态地切换 `class`
 | 
						||
 | 
						||
### 与普通的 class 属性共存
 | 
						||
<!--rehype:wrap-class=row-span-3-->
 | 
						||
 | 
						||
```html {2}
 | 
						||
<div
 | 
						||
  class="static"
 | 
						||
  v-bind:class="{
 | 
						||
    active: isActive,
 | 
						||
    'text-danger': hasError
 | 
						||
  }"
 | 
						||
></div>
 | 
						||
```
 | 
						||
 | 
						||
如下 data
 | 
						||
 | 
						||
```js
 | 
						||
data: {
 | 
						||
  isActive: true,
 | 
						||
  hasError: false
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
结果渲染为
 | 
						||
 | 
						||
```html
 | 
						||
<div class="static active"></div>
 | 
						||
```
 | 
						||
 | 
						||
### 绑定的数据对象不必内联定义在模板里
 | 
						||
<!--rehype:wrap-class=row-span-3-->
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:class="classObject"></div>
 | 
						||
```
 | 
						||
 | 
						||
如下 data
 | 
						||
 | 
						||
```js
 | 
						||
data: {
 | 
						||
  classObject: {
 | 
						||
    active: true,
 | 
						||
    'text-danger': false
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
结果渲染为
 | 
						||
 | 
						||
```html
 | 
						||
<div class="static active"></div>
 | 
						||
```
 | 
						||
 | 
						||
### 三元表达式
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:class="[
 | 
						||
  isActive ? activeClass : ''
 | 
						||
]">
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
### 数组
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:class="[
 | 
						||
  { active: isActive }, errorClass
 | 
						||
]"></div>
 | 
						||
```
 | 
						||
 | 
						||
### 数组语法
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:class="[
 | 
						||
  activeClass, errorClass
 | 
						||
]">
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
如下 data
 | 
						||
 | 
						||
```js
 | 
						||
data: {
 | 
						||
  activeClass: 'active',
 | 
						||
  errorClass: 'text-danger'
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
结果渲染为
 | 
						||
 | 
						||
```html
 | 
						||
<div class="active text-danger"></div>
 | 
						||
```
 | 
						||
 | 
						||
### 内联样式
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:style="{
 | 
						||
    color: activeColor,
 | 
						||
    fontSize: fontSize + 'px'
 | 
						||
}"></div>
 | 
						||
```
 | 
						||
 | 
						||
如下 data
 | 
						||
 | 
						||
```js
 | 
						||
data: {
 | 
						||
  activeColor: 'red',
 | 
						||
  fontSize: 30
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
结果渲染为
 | 
						||
 | 
						||
```html
 | 
						||
<div style="color: red; font-size: 30px;"></div>
 | 
						||
```
 | 
						||
 | 
						||
### 内联样式对象通常更好
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:style="styleObject"></div>
 | 
						||
```
 | 
						||
 | 
						||
如下 data
 | 
						||
 | 
						||
```js
 | 
						||
data: {
 | 
						||
  styleObject: {
 | 
						||
    color: 'red',
 | 
						||
    fontSize: '13px'
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
同样的,对象语法常常结合返回对象的计算属性使用
 | 
						||
 | 
						||
### 内联样式数组语法
 | 
						||
 | 
						||
```html
 | 
						||
<div v-bind:style="[
 | 
						||
  baseStyles, overridingStyles
 | 
						||
]"></div>
 | 
						||
```
 | 
						||
 | 
						||
### 内联样式多重值
 | 
						||
 | 
						||
```html
 | 
						||
<div :style="{
 | 
						||
  display: ['-webkit-box', 'flex']
 | 
						||
}"></div>
 | 
						||
```
 | 
						||
 | 
						||
条件渲染
 | 
						||
---
 | 
						||
 | 
						||
### v-if
 | 
						||
 | 
						||
```html
 | 
						||
<h1 v-if="awesome">Vue is awesome!</h1>
 | 
						||
<h1 v-else>Oh no 😢</h1>
 | 
						||
```
 | 
						||
 | 
						||
### v-else-if
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<div v-if="type === 'A'">A</div>
 | 
						||
<div v-else-if="type === 'B'">B</div>
 | 
						||
<div v-else-if="type === 'C'">C</div>
 | 
						||
<div v-else>
 | 
						||
  Not A/B/C
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
`@2.1.0` 新增,必须紧跟在带 `v-if` 或者 `v-else-if` 的元素之后
 | 
						||
 | 
						||
### v-else
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<div v-if="Math.random() > 0.5">
 | 
						||
  现在你看到我了
 | 
						||
</div>
 | 
						||
<div v-else>
 | 
						||
  现在你看不见我了
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
`v-else` 元素必须紧跟在带 `v-if` 或者 `v-else-if` 的元素的后面
 | 
						||
 | 
						||
### \<template> 上使用 v-if 条件渲染分组
 | 
						||
 | 
						||
```html
 | 
						||
<template v-if="ok">
 | 
						||
  <p>Paragraph 1</p>
 | 
						||
</template>
 | 
						||
```
 | 
						||
 | 
						||
### 用 key 管理可复用的元素
 | 
						||
<!--rehype:wrap-class=col-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<template v-if="loginType === 'username'">
 | 
						||
  <label>Username</label>
 | 
						||
  <input placeholder="输入用户名" key="username-input">
 | 
						||
</template>
 | 
						||
<template v-else>
 | 
						||
  <label>Email</label>
 | 
						||
  <input placeholder="输入邮箱" key="email-input">
 | 
						||
</template>
 | 
						||
```
 | 
						||
 | 
						||
### v-show
 | 
						||
 | 
						||
```html
 | 
						||
<h1 v-show="ok">
 | 
						||
  Hello!
 | 
						||
</h1>
 | 
						||
```
 | 
						||
 | 
						||
带有 `v-show` 的元素始终会被渲染并保留在 DOM 中,只是简单地切换元素的 `CSS` 属性 `display`
 | 
						||
 | 
						||
列表渲染
 | 
						||
---
 | 
						||
 | 
						||
### v-for
 | 
						||
 | 
						||
```html {3}
 | 
						||
<ul id="example-1">
 | 
						||
  <li
 | 
						||
    v-for="item in items"
 | 
						||
    :key="item.message">
 | 
						||
    {{ item.message }}
 | 
						||
  </li>
 | 
						||
</ul>
 | 
						||
```
 | 
						||
 | 
						||
```js
 | 
						||
var example1 = new Vue({
 | 
						||
  el: '#example-1',
 | 
						||
  data: {
 | 
						||
    items: [
 | 
						||
      { message: 'Foo' },
 | 
						||
      { message: 'Bar' }
 | 
						||
    ]
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### v-for 可选的第二个参数(索引)
 | 
						||
 | 
						||
```html {2}
 | 
						||
<li v-for="(item, index) in items">
 | 
						||
  {{ index }}
 | 
						||
  {{ item.message }}
 | 
						||
</li>
 | 
						||
```
 | 
						||
 | 
						||
如下 `data`
 | 
						||
 | 
						||
```js
 | 
						||
data: {
 | 
						||
  items: [
 | 
						||
    { message: 'Foo' },
 | 
						||
    { message: 'Bar' }
 | 
						||
  ]
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
也可以用 `of` 替代 `in` 作为分隔符
 | 
						||
 | 
						||
```html
 | 
						||
<div v-for="item of items"></div>
 | 
						||
```
 | 
						||
 | 
						||
### v-for 使用对象
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<li v-for="value in object">
 | 
						||
  {{ value }}
 | 
						||
</li>
 | 
						||
```
 | 
						||
 | 
						||
如下 data
 | 
						||
 | 
						||
```js
 | 
						||
data: {
 | 
						||
  object: {
 | 
						||
    title: 'How to do lists in Vue',
 | 
						||
    author: 'Jane Doe',
 | 
						||
    publishedAt: '2016-04-10'
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
渲染结果
 | 
						||
 | 
						||
```
 | 
						||
How to do lists in Vue
 | 
						||
Jane Doe
 | 
						||
2016-04-10
 | 
						||
```
 | 
						||
 | 
						||
提供第二个的参数为 property 名称 (也就是键名)
 | 
						||
 | 
						||
```html
 | 
						||
<div v-for="(value, name) in object">
 | 
						||
  {{ name }}: {{ value }}
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
还可以用第三个参数作为索引
 | 
						||
 | 
						||
```html
 | 
						||
<div v-for="(value,name,index) in object">
 | 
						||
  {{ index }}. {{ name }}: {{ value }}
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
### v-for/v-if
 | 
						||
 | 
						||
```html {2,3}
 | 
						||
<li
 | 
						||
  v-for="todo in todos"
 | 
						||
  v-if="!todo.isComplete"
 | 
						||
>
 | 
						||
  {{ todo }}
 | 
						||
</li>
 | 
						||
```
 | 
						||
 | 
						||
只渲染未完成的 todo,下面加上 `v-else` 示例
 | 
						||
 | 
						||
```html
 | 
						||
<ul v-if="todos.length">
 | 
						||
  <li v-for="todo in todos">
 | 
						||
    {{ todo }}
 | 
						||
  </li>
 | 
						||
</ul>
 | 
						||
<p v-else>No todos left!</p>
 | 
						||
```
 | 
						||
 | 
						||
注意: `v-for` 和 `v-if` 不推荐一起使用[参考官方文档](https://v2.cn.vuejs.org/v2/guide/conditional.html#v-if-与-v-for-一起使用)
 | 
						||
 | 
						||
### 组件上使用 v-for
 | 
						||
 | 
						||
```html
 | 
						||
<my-component
 | 
						||
  v-for="(item, index) in items"
 | 
						||
  v-bind:item="item"
 | 
						||
  v-bind:index="index"
 | 
						||
  v-bind:key="item.id"
 | 
						||
></my-component>
 | 
						||
```
 | 
						||
 | 
						||
`2.2.0+` 的版本里,当在组件上使用 `v-for` 时,`key` 现在是必须的
 | 
						||
 | 
						||
事件处理
 | 
						||
---
 | 
						||
 | 
						||
### 监听事件
 | 
						||
 | 
						||
```html {2}
 | 
						||
<div id="example-1">
 | 
						||
  <button v-on:click="counter += 1">
 | 
						||
    +1
 | 
						||
  </button>
 | 
						||
  <p>按钮已被点击 {{ counter }} 次。</p>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
```js
 | 
						||
var example1 = new Vue({
 | 
						||
  el: '#example-1',
 | 
						||
  data: {
 | 
						||
    counter: 0
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 事件处理方法
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html {3}
 | 
						||
<div id="example-2">
 | 
						||
  <!-- `greet` 是在下面定义的方法名 -->
 | 
						||
  <button v-on:click="greet">
 | 
						||
    你好
 | 
						||
  </button>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
```js
 | 
						||
var example2 = new Vue({
 | 
						||
  el: '#example-2',
 | 
						||
  data: {
 | 
						||
    name: 'Vue.js'
 | 
						||
  },
 | 
						||
  // 在 `methods` 对象中定义方法
 | 
						||
  methods: {
 | 
						||
    greet: function (event) {
 | 
						||
      // `this` 在方法里指向当前 Vue 实例
 | 
						||
      alert('Hello ' + this.name + '!')
 | 
						||
      // `event` 是原生 DOM 事件
 | 
						||
      if (event) {
 | 
						||
        alert(event.target.tagName)
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
也可以用 JavaScript 直接调用方法
 | 
						||
 | 
						||
```js
 | 
						||
example2.greet() // => 'Hello Vue.js!'
 | 
						||
```
 | 
						||
 | 
						||
### 内联处理器中的方法
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html {2,5}
 | 
						||
<div id="example-3">
 | 
						||
  <button v-on:click="say('hi')">
 | 
						||
    弹出 hi
 | 
						||
  </button>
 | 
						||
  <button v-on:click="say('what')">
 | 
						||
    弹出 what
 | 
						||
  </button>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
```js {4}
 | 
						||
new Vue({
 | 
						||
  el: '#example-3',
 | 
						||
  methods: {
 | 
						||
    say: function (message) {
 | 
						||
      alert(message)
 | 
						||
    }
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
访问原始的 DOM 事件,用特殊变量 $event
 | 
						||
 | 
						||
```html
 | 
						||
<button v-on:click="say('what', $event)">
 | 
						||
  提交
 | 
						||
</button>
 | 
						||
```
 | 
						||
 | 
						||
```js
 | 
						||
methods: {
 | 
						||
  say: function (message, event) {
 | 
						||
    // 现在我们可以访问原生事件对象
 | 
						||
    if (event) {
 | 
						||
      event.preventDefault()
 | 
						||
    }
 | 
						||
    alert(message)
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
### 事件修饰符
 | 
						||
 | 
						||
```html
 | 
						||
<!-- 阻止单击事件继续传播 -->
 | 
						||
<a v-on:click.stop="doThis"></a>
 | 
						||
<!-- 提交事件不再重载页面 -->
 | 
						||
<form v-on:submit.prevent="submit"></form>
 | 
						||
<!-- 修饰符可以串联 -->
 | 
						||
<a v-on:click.stop.prevent="doThat"></a>
 | 
						||
<!-- 只有修饰符 -->
 | 
						||
<form v-on:submit.prevent></form>
 | 
						||
<!-- 添加事件监听器时使用事件捕获模式 -->
 | 
						||
<!-- 即内部元素触发的事件先在此处理 -->
 | 
						||
<!-- 然后交由内部元素进行处理 -->
 | 
						||
<div v-on:click.capture="doThis">...</div>
 | 
						||
<!-- 当 event.target 是当前元素自身时触发 -->
 | 
						||
<!-- 即事件不是从内部元素触发的 -->
 | 
						||
<div v-on:click.self="doThat">...</div>
 | 
						||
<!-- 点击事件将只会触发一次 -->
 | 
						||
<a v-on:click.once="doThis"></a>
 | 
						||
```
 | 
						||
 | 
						||
### 事件修饰符 passive
 | 
						||
 | 
						||
```html
 | 
						||
<!-- 滚动事件的默认行为(即滚动行为)会立即触发 -->
 | 
						||
<!-- 而不会等待 `onScroll` 完成  -->
 | 
						||
<!-- 包含 event.preventDefault() 的情况 -->
 | 
						||
<p v-on:scroll.passive="onScroll">
 | 
						||
  ...
 | 
						||
</p>
 | 
						||
```
 | 
						||
 | 
						||
这个 `.passive` [修饰符](#v-on-事件修饰符)尤其能够提升移动端的性能。
 | 
						||
 | 
						||
### 按键修饰符
 | 
						||
 | 
						||
```html
 | 
						||
<!-- 在 key 是 Enter 时调用 vm.submit() -->
 | 
						||
<input v-on:keyup.enter="submit">
 | 
						||
<!-- 在 key 是 PageDown 时被调用 -->
 | 
						||
<input v-on:keyup.page-down="onPageDown">
 | 
						||
<!-- Alt + C -->
 | 
						||
<input v-on:keyup.alt.67="clear">
 | 
						||
<!-- Ctrl + Click -->
 | 
						||
<div v-on:click.ctrl="doSomething">
 | 
						||
```
 | 
						||
 | 
						||
### .exact 修饰符
 | 
						||
 | 
						||
```html
 | 
						||
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
 | 
						||
<button v-on:click.ctrl="onClick">
 | 
						||
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
 | 
						||
<button v-on:click.ctrl.exact="ctrlClick">
 | 
						||
<!-- 没有任何系统修饰符被按下的时候才触发 -->
 | 
						||
<button v-on:click.exact="onClick">
 | 
						||
```
 | 
						||
 | 
						||
计算属性和侦听器
 | 
						||
---
 | 
						||
 | 
						||
### 基础例子
 | 
						||
 | 
						||
```html
 | 
						||
<div id="example">
 | 
						||
  <p>Original message: "{{ message }}"</p>
 | 
						||
  <p>
 | 
						||
    计算的反向消息: "{{ reversedMessage }}"
 | 
						||
  </p>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
```js
 | 
						||
var vm = new Vue({
 | 
						||
  el: '#example',
 | 
						||
  data: {
 | 
						||
    message: 'Hello'
 | 
						||
  },
 | 
						||
  computed: {
 | 
						||
    // 计算属性的 getter
 | 
						||
    reversedMessage: function () {
 | 
						||
      // `this` 指向 vm 实例
 | 
						||
      return this.message.split('')
 | 
						||
                  .reverse().join('')
 | 
						||
    }
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 计算属性缓存 vs 方法
 | 
						||
 | 
						||
```html
 | 
						||
<p>
 | 
						||
  计算的反向消息:"{{ reversedMessage() }}"
 | 
						||
</p>
 | 
						||
```
 | 
						||
 | 
						||
在组件中,我们可以将同一函数定义为一个方法而不是一个计算属性
 | 
						||
 | 
						||
```js
 | 
						||
methods: {
 | 
						||
  reversedMessage: function () {
 | 
						||
    return this.message.split('')
 | 
						||
                .reverse().join('')
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
两种方式的最终结果确实是完全相同的。然而,不同的是**计算属性是基于它们的响应式依赖进行缓存的**。
 | 
						||
 | 
						||
### 计算属性 vs 侦听属性
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<div id="demo">{{ fullName }}</div>
 | 
						||
```
 | 
						||
 | 
						||
```js
 | 
						||
var vm = new Vue({
 | 
						||
  el: '#demo',
 | 
						||
  data: {
 | 
						||
    firstName: 'Foo',
 | 
						||
    lastName: 'Bar',
 | 
						||
    fullName: 'Foo Bar'
 | 
						||
  },
 | 
						||
  watch: {
 | 
						||
    firstName: function (val) {
 | 
						||
      this.fullName = 
 | 
						||
          val + ' ' + this.lastName
 | 
						||
    },
 | 
						||
    lastName: function (val) {
 | 
						||
      this.fullName =
 | 
						||
          this.firstName + ' ' + val
 | 
						||
    }
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
上面代码是命令式且重复的。将它与计算属性的版本进行比较:
 | 
						||
 | 
						||
```js
 | 
						||
var vm = new Vue({
 | 
						||
  el: '#demo',
 | 
						||
  data: {
 | 
						||
    firstName: 'Foo',
 | 
						||
    lastName: 'Bar'
 | 
						||
  },
 | 
						||
  computed: {
 | 
						||
    fullName: function () {
 | 
						||
      return this.firstName 
 | 
						||
        + ' ' + this.lastName
 | 
						||
    }
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 计算属性的 setter
 | 
						||
<!--rehype:wrap-class=col-span-2-->
 | 
						||
 | 
						||
```js
 | 
						||
computed: {
 | 
						||
  fullName: {
 | 
						||
    get: function () {         // getter
 | 
						||
      return this.firstName + ' ' + this.lastName
 | 
						||
    },
 | 
						||
    set: function (newValue) { // setter
 | 
						||
      var names = newValue.split(' ')
 | 
						||
      this.firstName = names[0]
 | 
						||
      this.lastName = names[names.length - 1]
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
表单输入绑定
 | 
						||
---
 | 
						||
 | 
						||
### 文本
 | 
						||
 | 
						||
```html
 | 
						||
<input v-model="msg" placeholder="编辑我">
 | 
						||
<p>msg is: {{ msg }}</p>
 | 
						||
```
 | 
						||
 | 
						||
### 多行文本
 | 
						||
 | 
						||
```html {3}
 | 
						||
<span>Multiline message is:</span>
 | 
						||
<textarea
 | 
						||
  v-model="message"
 | 
						||
  placeholder="添加多行"></textarea>
 | 
						||
<p>{{ message }}</p>
 | 
						||
```
 | 
						||
 | 
						||
### 复选框
 | 
						||
 | 
						||
```html {4}
 | 
						||
<input
 | 
						||
  type="checkbox"
 | 
						||
  id="checkbox"
 | 
						||
  v-model="checked"
 | 
						||
>
 | 
						||
<label for="checkbox">{{ checked}}</label>
 | 
						||
```
 | 
						||
 | 
						||
### 多个复选框
 | 
						||
<!--rehype:wrap-class=col-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
 | 
						||
<label for="jack">Jack</label>
 | 
						||
<input type="checkbox" id="john" value="John" v-model="checkedNames">
 | 
						||
<label for="john">John</label>
 | 
						||
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
 | 
						||
<label for="mike">Mike</label>
 | 
						||
<br>
 | 
						||
<span>Checked names: {{ checkedNames }}</span>
 | 
						||
```
 | 
						||
 | 
						||
如下 data
 | 
						||
 | 
						||
```js
 | 
						||
new Vue({
 | 
						||
  el: '...',
 | 
						||
  data: {
 | 
						||
    checkedNames: []
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 单选按钮
 | 
						||
 | 
						||
```html
 | 
						||
<div id="example-4">
 | 
						||
  <input type="radio" id="one" value="One"
 | 
						||
    v-model="picked">
 | 
						||
  <label for="one">One</label>
 | 
						||
  <br>
 | 
						||
  <input type="radio" id="two" value="Two"
 | 
						||
    v-model="picked">
 | 
						||
  <label for="two">Two</label>
 | 
						||
  <div>Picked: {{ picked }}</div>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
new Vue({
 | 
						||
  el: '#example-4',
 | 
						||
  data: {
 | 
						||
    picked: ''
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 选择框
 | 
						||
 | 
						||
```html
 | 
						||
<select v-model="selected">
 | 
						||
  <option disabled value="">请选择</option>
 | 
						||
  <option>A</option>
 | 
						||
  <option>B</option>
 | 
						||
  <option>C</option>
 | 
						||
</select>
 | 
						||
<span>Selected: {{ selected }}</span>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
new Vue({
 | 
						||
  el: '...',
 | 
						||
  data: {
 | 
						||
    selected: ''
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 选择框(数组)
 | 
						||
 | 
						||
```html
 | 
						||
<select v-model="selected" multiple>
 | 
						||
  <option>A</option>
 | 
						||
  <option>B</option>
 | 
						||
  <option>C</option>
 | 
						||
</select>
 | 
						||
<div>Selected: {{ selected }}</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
new Vue({
 | 
						||
  el: '...',
 | 
						||
  data: {
 | 
						||
    selected: []
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### v-for 渲染的动态选项
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html {3-4}
 | 
						||
<select v-model="selected">
 | 
						||
  <option
 | 
						||
    v-for="option in options"
 | 
						||
    v-bind:value="option.value"
 | 
						||
  >
 | 
						||
    {{ option.text }}
 | 
						||
  </option>
 | 
						||
</select>
 | 
						||
<span>Selected: {{ selected }}</span>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js {6-8}
 | 
						||
new Vue({
 | 
						||
  el: '...',
 | 
						||
  data: {
 | 
						||
    selected: 'A',
 | 
						||
    options: [
 | 
						||
      { text: 'One', value: 'A' },
 | 
						||
      { text: 'Two', value: 'B' },
 | 
						||
      { text: 'Three', value: 'C' }
 | 
						||
    ]
 | 
						||
  }
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 值绑定
 | 
						||
 | 
						||
```html
 | 
						||
<!-- 当选中时,pc 为字符串 "a" -->
 | 
						||
<input type="radio" v-model="pc" value="a">
 | 
						||
 | 
						||
<!-- toggle 为 true 或 false -->
 | 
						||
<input type="checkbox" v-model="toggle">
 | 
						||
<!-- 选中第一个选项时selected为字符串 abc -->
 | 
						||
<select v-model="selected">
 | 
						||
  <option value="abc">ABC</option>
 | 
						||
</select>
 | 
						||
```
 | 
						||
 | 
						||
### 单选按钮
 | 
						||
 | 
						||
```html
 | 
						||
<input
 | 
						||
  type="radio"
 | 
						||
  v-model="pick"
 | 
						||
  v-bind:value="a">
 | 
						||
```
 | 
						||
 | 
						||
当选中时
 | 
						||
 | 
						||
```js
 | 
						||
vm.pick === vm.a
 | 
						||
```
 | 
						||
 | 
						||
### 复选框
 | 
						||
 | 
						||
```html {3}
 | 
						||
<input
 | 
						||
  type="checkbox"
 | 
						||
  v-model="toggle"
 | 
						||
  true-value="yes"
 | 
						||
  false-value="no"
 | 
						||
>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
// 当选中时
 | 
						||
vm.toggle === 'yes'
 | 
						||
// 当没有选中时
 | 
						||
vm.toggle === 'no'
 | 
						||
```
 | 
						||
 | 
						||
### 选择框的选项
 | 
						||
 | 
						||
```html
 | 
						||
<select v-model="selected">
 | 
						||
  <!-- 内联对象字面量 -->
 | 
						||
  <option v-bind:value="{ number: 123 }">
 | 
						||
    123
 | 
						||
  </option>
 | 
						||
</select>
 | 
						||
```
 | 
						||
 | 
						||
当选中时
 | 
						||
 | 
						||
```js
 | 
						||
typeof vm.selected // => 'object'
 | 
						||
vm.selected.number // => 123
 | 
						||
```
 | 
						||
 | 
						||
### 修饰符
 | 
						||
 | 
						||
```html
 | 
						||
<!-- lazy:在“change”时而非“input”时更新 -->
 | 
						||
<input v-model.lazy="msg">
 | 
						||
 | 
						||
<!-- number:自动将用户的输入值转为数值类型 -->
 | 
						||
<input v-model.number="age" type="number">
 | 
						||
 | 
						||
<!-- trim:自动过滤用户输入的首尾空白字符 -->
 | 
						||
<input v-model.trim="msg">
 | 
						||
```
 | 
						||
 | 
						||
组件基础
 | 
						||
---
 | 
						||
 | 
						||
### 单文件组件
 | 
						||
<!--rehype:wrap-class=row-span-3-->
 | 
						||
 | 
						||
- 将 `HTML`/`CSS`/`JS` 三部分存放到一个 `Hello.vue` 文件中
 | 
						||
 | 
						||
  ```html
 | 
						||
  <template>
 | 
						||
    <p>{{ title }} World!</p>
 | 
						||
  </template>
 | 
						||
  <script>
 | 
						||
    export default {
 | 
						||
      name: 'Hello',
 | 
						||
      props: {
 | 
						||
        title: {
 | 
						||
          type: String,
 | 
						||
          default: 'Hello'
 | 
						||
        }
 | 
						||
      },
 | 
						||
      data: function() {
 | 
						||
        return {
 | 
						||
          greeting: "Hello"
 | 
						||
        };
 | 
						||
      }
 | 
						||
    };
 | 
						||
  </script>
 | 
						||
  <style scoped>
 | 
						||
    p {
 | 
						||
      font-size: 2em;
 | 
						||
      text-align: center;
 | 
						||
    }
 | 
						||
  </style>
 | 
						||
  ```
 | 
						||
 | 
						||
- 使用 `Hello.vue` 组件
 | 
						||
 | 
						||
  ```html
 | 
						||
  <script>
 | 
						||
    import Vue from "vue";
 | 
						||
    import Hello from "./Hello";
 | 
						||
 | 
						||
    export default {
 | 
						||
      components: { Hello }
 | 
						||
    }
 | 
						||
  </script>
 | 
						||
  <template>
 | 
						||
    <div>
 | 
						||
      <Hello :title="'aaaa'"></Hello>
 | 
						||
    </div>
 | 
						||
  </template>
 | 
						||
  ```
 | 
						||
<!--rehype:className=style-timeline-->
 | 
						||
 | 
						||
### 基本示例
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```js
 | 
						||
Vue.component('button-counter', {
 | 
						||
  data: function () {
 | 
						||
    return {
 | 
						||
      count: 0
 | 
						||
    }
 | 
						||
  },
 | 
						||
  template: `
 | 
						||
    <button v-on:click="count++">
 | 
						||
      你点击了我 {{ count }} 次
 | 
						||
    </button>
 | 
						||
  `
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
组件是可复用的 `Vue` 实例
 | 
						||
 | 
						||
```html
 | 
						||
<div id="components-demo">
 | 
						||
  <button-counter></button-counter>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
new Vue({
 | 
						||
  el: '#components-demo'
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
组件的复用
 | 
						||
 | 
						||
```html
 | 
						||
<div id="components-demo">
 | 
						||
  <button-counter></button-counter>
 | 
						||
  <button-counter></button-counter>
 | 
						||
  <button-counter></button-counter>
 | 
						||
</div>
 | 
						||
```
 | 
						||
 | 
						||
### 单个根元素
 | 
						||
 | 
						||
```js {4}
 | 
						||
Vue.component('blog-post', {
 | 
						||
  props: ['post'],
 | 
						||
  template: `
 | 
						||
    <div class="blog-post">
 | 
						||
      <h3>{{ post.title }}</h3>
 | 
						||
      <div v-html="post.content"></div>
 | 
						||
    </div>
 | 
						||
  `
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```html
 | 
						||
<blog-post
 | 
						||
  v-for="post in posts"
 | 
						||
  v-bind:key="post.id"
 | 
						||
  v-bind:post="post"
 | 
						||
>
 | 
						||
</blog-post>
 | 
						||
```
 | 
						||
 | 
						||
### 向子组件传递数据
 | 
						||
 | 
						||
```js
 | 
						||
Vue.component('blog-post', {
 | 
						||
  props: ['title'],
 | 
						||
  template: '<h3>{{ title }}</h3>'
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
当值传递给一个 `prop` `attribute` 的时候,变成了组件实例的一个 `property`
 | 
						||
 | 
						||
```html
 | 
						||
<blog-post title="写博客"></blog-post>
 | 
						||
<blog-post title="如此有趣"></blog-post>
 | 
						||
```
 | 
						||
 | 
						||
### `data` 必须是一个函数
 | 
						||
 | 
						||
```js
 | 
						||
data: function () {
 | 
						||
  return {
 | 
						||
    count: 0
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
组件的 `data` 选项必须是一个函数
 | 
						||
 | 
						||
### 监听子组件事件
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```js {7}
 | 
						||
Vue.component('blog-post', {
 | 
						||
  props: ['post'],
 | 
						||
  template: `
 | 
						||
    <div class="blog-post">
 | 
						||
      <h3>{{ post.title }}</h3>
 | 
						||
      <button
 | 
						||
        v-on:click="$emit('enlarge-txt')"
 | 
						||
      >放大文字
 | 
						||
      </button>
 | 
						||
      <div v-html="post.content"></div>
 | 
						||
    </div>
 | 
						||
  `
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```html {3}
 | 
						||
<blog-post
 | 
						||
  ...
 | 
						||
  v-on:enlarge-text="postFontSize += 0.1"
 | 
						||
></blog-post>
 | 
						||
```
 | 
						||
 | 
						||
可以使用 `$emit` 的第二个参数来提供这个值
 | 
						||
 | 
						||
```html {2}
 | 
						||
<button
 | 
						||
  v-on:click="$emit('enlarge-text', 0.1)"
 | 
						||
>
 | 
						||
  Enlarge text
 | 
						||
</button>
 | 
						||
```
 | 
						||
 | 
						||
通过 `$event` 访问到被抛出的这个值
 | 
						||
 | 
						||
```html {3}
 | 
						||
<blog-post
 | 
						||
  ...
 | 
						||
  v-on:enlarge-text="postFontSize += $event"
 | 
						||
></blog-post>
 | 
						||
```
 | 
						||
 | 
						||
如果这个事件处理函数是一个方法
 | 
						||
 | 
						||
```html {3}
 | 
						||
<blog-post
 | 
						||
  ...
 | 
						||
  v-on:enlarge-text="onEnlargeText"
 | 
						||
></blog-post>
 | 
						||
```
 | 
						||
 | 
						||
那么这个值将会作为第一个参数传入这个方法
 | 
						||
 | 
						||
```js
 | 
						||
methods: {
 | 
						||
  onEnlargeText: function(enlargeAmount) {
 | 
						||
    this.postFontSize += enlargeAmount
 | 
						||
  }
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
### 在组件上使用 v-model
 | 
						||
<!--rehype:wrap-class=col-span-2-->
 | 
						||
 | 
						||
自定义事件也可以用于创建支持 `v-model` 的自定义输入组件。
 | 
						||
 | 
						||
```html
 | 
						||
<input v-model="searchText">
 | 
						||
```
 | 
						||
 | 
						||
等价于
 | 
						||
 | 
						||
```html
 | 
						||
<input
 | 
						||
  v-bind:value="searchText"
 | 
						||
  v-on:input="searchText = $event.target.value"
 | 
						||
>
 | 
						||
```
 | 
						||
 | 
						||
当用在组件上时,v-model 则会这样:
 | 
						||
 | 
						||
```html
 | 
						||
<custom-input
 | 
						||
  v-bind:value="searchText"
 | 
						||
  v-on:input="searchText = $event"
 | 
						||
></custom-input>
 | 
						||
```
 | 
						||
 | 
						||
为了让它正常工作,这个组件内的 \<input> 必须:
 | 
						||
 | 
						||
- 将其 `value` attribute 绑定到一个名叫 `value` 的 `prop` 上
 | 
						||
- 在其 `input` 事件被触发时,将新的值通过自定义的 `input` 事件抛出
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js
 | 
						||
Vue.component('custom-input', {
 | 
						||
  props: ['value'],
 | 
						||
  template: `
 | 
						||
    <input
 | 
						||
      v-bind:value="value"
 | 
						||
      v-on:input="$emit('input', $event.target.value)"
 | 
						||
    >
 | 
						||
  `
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
现在 `v-model` 就应该可以在这个组件上完美地工作起来了
 | 
						||
 | 
						||
```html {2}
 | 
						||
<custom-input
 | 
						||
  v-model="searchText"
 | 
						||
>
 | 
						||
</custom-input>
 | 
						||
```
 | 
						||
 | 
						||
### 通过插槽分发内容
 | 
						||
 | 
						||
```html
 | 
						||
<alert-box>
 | 
						||
  发生了不好的事情。
 | 
						||
</alert-box>
 | 
						||
```
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```js {5}
 | 
						||
Vue.component('alert-box', {
 | 
						||
  template: `
 | 
						||
    <div class="demo-alert-box">
 | 
						||
      <strong>Error!</strong>
 | 
						||
      <slot></slot>
 | 
						||
    </div>
 | 
						||
  `
 | 
						||
})
 | 
						||
```
 | 
						||
 | 
						||
### 动态组件示例
 | 
						||
<!--rehype:wrap-class=col-span-2 row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<div id="dynamic-component-demo" class="demo">
 | 
						||
  <button
 | 
						||
    v-for="tab in tabs"
 | 
						||
    v-bind:key="tab"
 | 
						||
    v-bind:class="['tab-button', { active: currentTab === tab }]"
 | 
						||
    v-on:click="currentTab = tab"
 | 
						||
  >
 | 
						||
    {{ tab }}
 | 
						||
  </button>
 | 
						||
  <component v-bind:is="currentTabComponent" class="tab"></component>
 | 
						||
</div>
 | 
						||
 | 
						||
<script>
 | 
						||
  Vue.component("tab-home", {
 | 
						||
    template: "<div>Home component</div>"
 | 
						||
  });
 | 
						||
  Vue.component("tab-posts", {
 | 
						||
    template: "<div>Posts component</div>"
 | 
						||
  });
 | 
						||
  Vue.component("tab-archive", {
 | 
						||
    template: "<div>Archive component</div>"
 | 
						||
  });
 | 
						||
  new Vue({
 | 
						||
    el: "#dynamic-component-demo",
 | 
						||
    data: {
 | 
						||
      currentTab: "Home",
 | 
						||
      tabs: ["Home", "Posts", "Archive"]
 | 
						||
    },
 | 
						||
    computed: {
 | 
						||
      currentTabComponent: function() {
 | 
						||
        return "tab-" + this.currentTab.toLowerCase();
 | 
						||
      }
 | 
						||
    }
 | 
						||
  });
 | 
						||
</script>
 | 
						||
```
 | 
						||
 | 
						||
### 解析 DOM 模板时的注意事项
 | 
						||
 | 
						||
有些 HTML 元素,诸如 `<ul>`、`<ol>`、`<table>` 和 `<select>`,对于哪些元素可以出现在其内部是有严格限制的。有些元素,诸如 `<li>`、`<tr>` 和 `<option>`,只能出现在其它某些特定的元素内部
 | 
						||
 | 
						||
```html
 | 
						||
<table>
 | 
						||
  <blog-post-row></blog-post-row>
 | 
						||
</table>
 | 
						||
```
 | 
						||
 | 
						||
`<blog-post-row>` 会被作为无效的内容提升到外部
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
如果我们从以下来源使用模板的话,这条限制是不存在的
 | 
						||
 | 
						||
- 字符串 (例如:`template: '...'`)
 | 
						||
- 单文件组件 (`.vue`)
 | 
						||
- `<script type="text/x-template">`
 | 
						||
<!--rehype:className=style-round-->
 | 
						||
 | 
						||
过渡 & 动画
 | 
						||
---
 | 
						||
 | 
						||
### 单元素/组件的过渡
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<template>
 | 
						||
  <button v-on:click="show = !show">
 | 
						||
    切换
 | 
						||
  </button>
 | 
						||
  <transition name="fade">
 | 
						||
    <p v-if="show">切换内容</p>
 | 
						||
  </transition>
 | 
						||
</template>
 | 
						||
 | 
						||
<script>
 | 
						||
  export default {
 | 
						||
    data: function() {
 | 
						||
      return {
 | 
						||
        show: true
 | 
						||
      };
 | 
						||
    }
 | 
						||
  };
 | 
						||
</script>
 | 
						||
 | 
						||
<style scoped>
 | 
						||
  .fade-enter-active, .fade-leave-active {
 | 
						||
    transition: opacity .5s;
 | 
						||
  }
 | 
						||
  /* .fade-leave-active 低于 2.1.8 版本 */
 | 
						||
  .fade-enter, .fade-leave-to {
 | 
						||
    opacity: 0;
 | 
						||
  }
 | 
						||
</style>
 | 
						||
```
 | 
						||
 | 
						||
### CSS 过渡
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<template>
 | 
						||
  <button @click="show = !show">
 | 
						||
    切换渲染
 | 
						||
  </button>
 | 
						||
  <transition name="slide-fade">
 | 
						||
    <p v-if="show">切换内容</p>
 | 
						||
  </transition>
 | 
						||
</template>
 | 
						||
<script>
 | 
						||
  export default {
 | 
						||
    data: function() {
 | 
						||
      return {
 | 
						||
        show: true
 | 
						||
      };
 | 
						||
    }
 | 
						||
  };
 | 
						||
</script>
 | 
						||
<style scoped>
 | 
						||
  /* 可以设置不同的进入和离开动画 */
 | 
						||
  /* 设置持续时间和动画函数 */
 | 
						||
  .slide-fade-enter-active {
 | 
						||
    transition: all .3s ease;
 | 
						||
  }
 | 
						||
  .slide-fade-leave-active {
 | 
						||
    transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
 | 
						||
  }
 | 
						||
  /* .slide-fade-leave-active 用于 2.1.8 以下版本 */ 
 | 
						||
  .slide-fade-enter, .slide-fade-leave-to {
 | 
						||
    transform: translateX(10px);
 | 
						||
    opacity: 0;
 | 
						||
  }
 | 
						||
</style>
 | 
						||
```
 | 
						||
 | 
						||
### CSS 动画
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<template>
 | 
						||
  <button @click="show = !show">切换展示</button>
 | 
						||
  <transition name="bounce">
 | 
						||
    <p v-if="show">切换内容</p>
 | 
						||
  </transition>
 | 
						||
</template>
 | 
						||
<script>
 | 
						||
  export default {
 | 
						||
    data: function() {
 | 
						||
      return {
 | 
						||
        show: true
 | 
						||
      };
 | 
						||
    }
 | 
						||
  };
 | 
						||
</script>
 | 
						||
<style scoped>
 | 
						||
.bounce-enter-active {
 | 
						||
  animation: bounce-in .5s;
 | 
						||
}
 | 
						||
.bounce-leave-active {
 | 
						||
  animation: bounce-in .5s reverse;
 | 
						||
}
 | 
						||
@keyframes bounce-in {
 | 
						||
  0% {
 | 
						||
    transform: scale(0);
 | 
						||
  }
 | 
						||
  50% {
 | 
						||
    transform: scale(1.5);
 | 
						||
  }
 | 
						||
  100% {
 | 
						||
    transform: scale(1);
 | 
						||
  }
 | 
						||
}
 | 
						||
</style>
 | 
						||
```
 | 
						||
 | 
						||
### 过渡的类名
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`v-enter` | 定义进入过渡的开始状态 [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#过渡的类名)
 | 
						||
`v-enter-active` | 定义进入过渡生效时的状态 [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#过渡的类名)
 | 
						||
`v-enter-to` _(2.1.8)_ | 定义进入过渡的结束状态 [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#过渡的类名)
 | 
						||
`v-leave` | 定义离开过渡的开始状态 [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#过渡的类名)
 | 
						||
`v-leave-active` | 定义离开过渡生效时的状态 [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#过渡的类名)
 | 
						||
`v-leave-to` _(2.1.8)_| 定义离开过渡的结束状态 [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#过渡的类名)
 | 
						||
 | 
						||
如果你使用了 `<transition name="my-tran">`,那么 `v-enter` 会替换为 `my-tran-enter`。
 | 
						||
 | 
						||
#### 自定义过渡的类名
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`enter-class` | [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#自定义过渡的类名)
 | 
						||
`enter-active-class` | [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#自定义过渡的类名)
 | 
						||
`enter-to-class` _(2.1.8+)_ | [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#自定义过渡的类名)
 | 
						||
`leave-class` | [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#自定义过渡的类名)
 | 
						||
`leave-active-class` | [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#自定义过渡的类名)
 | 
						||
`leave-to-class` _(2.1.8+)_ | [#](https://v2.cn.vuejs.org/v2/guide/transitions.html#自定义过渡的类名)
 | 
						||
 | 
						||
---
 | 
						||
 | 
						||
```html
 | 
						||
<transition
 | 
						||
  name="custom-classes-transition"
 | 
						||
  enter-active-class="animated tada"
 | 
						||
  leave-active-class="animated bounceOutRight"
 | 
						||
>
 | 
						||
  <p v-if="show">hello</p>
 | 
						||
</transition>
 | 
						||
```
 | 
						||
 | 
						||
### 显性的过渡持续时间
 | 
						||
 | 
						||
`<transition>` 组件上的 `duration` prop 定制一个显性的过渡持续时间 (以毫秒计):
 | 
						||
 | 
						||
```html
 | 
						||
<transition :duration="1000">
 | 
						||
  ...
 | 
						||
</transition>
 | 
						||
```
 | 
						||
 | 
						||
你也可以定制进入和移出的持续时间:
 | 
						||
 | 
						||
```html
 | 
						||
<transition :duration="{
 | 
						||
  enter: 500,
 | 
						||
  leave: 800
 | 
						||
}">
 | 
						||
  ...
 | 
						||
</transition>
 | 
						||
```
 | 
						||
 | 
						||
### 初始渲染的过渡
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
可以通过 `appear` attribute 设置节点在初始渲染的过渡
 | 
						||
 | 
						||
```html
 | 
						||
<transition appear>
 | 
						||
  <!-- ... -->
 | 
						||
</transition>
 | 
						||
```
 | 
						||
 | 
						||
这里默认和进入/离开过渡一样,同样也可以自定义 CSS 类名
 | 
						||
 | 
						||
```html
 | 
						||
<transition
 | 
						||
  appear
 | 
						||
  appear-class="custom-appear-class"
 | 
						||
  appear-to-class="custom-appear-to-class"
 | 
						||
  appear-active-class="custom-appear-active-class"
 | 
						||
>
 | 
						||
  <!-- ... -->
 | 
						||
</transition>
 | 
						||
```
 | 
						||
 | 
						||
自定义 JavaScript 钩子:
 | 
						||
 | 
						||
```html
 | 
						||
<transition
 | 
						||
  appear
 | 
						||
  v-on:before-appear="customBeforeAppearHook"
 | 
						||
  v-on:appear="customAppearHook"
 | 
						||
  v-on:after-appear="customAfterAppearHook"
 | 
						||
  v-on:appear-cancelled="customAppearCancelledHook"
 | 
						||
>
 | 
						||
  <!-- ... -->
 | 
						||
</transition>
 | 
						||
```
 | 
						||
 | 
						||
无论是 `appear` attribute 还是 `v-on:appear` 钩子都会生成初始渲染过渡
 | 
						||
 | 
						||
### JavaScript 钩子
 | 
						||
 | 
						||
```html
 | 
						||
<transition
 | 
						||
  v-on:before-enter="beforeEnter"
 | 
						||
  v-on:enter="enter"
 | 
						||
  v-on:after-enter="afterEnter"
 | 
						||
  v-on:enter-cancelled="enterCancelled"
 | 
						||
 | 
						||
  v-on:before-leave="beforeLeave"
 | 
						||
  v-on:leave="leave"
 | 
						||
  v-on:after-leave="afterLeave"
 | 
						||
  v-on:leave-cancelled="leaveCancelled"
 | 
						||
>
 | 
						||
  <!-- ... -->
 | 
						||
</transition>
 | 
						||
```
 | 
						||
 | 
						||
钩子函数可以结合 CSS `transitions`/`animations` 使用,也可以单独使用
 | 
						||
 | 
						||
### 列表的进入/离开过渡
 | 
						||
<!--rehype:wrap-class=col-span-2-->
 | 
						||
 | 
						||
```html
 | 
						||
<template>
 | 
						||
  <button v-on:click="add">添加</button>
 | 
						||
  <button v-on:click="remove">删除</button>
 | 
						||
  <transition-group name="list" tag="p">
 | 
						||
    <span v-for="item in items" v-bind:key="item" class="list-item">
 | 
						||
      {{ item }}
 | 
						||
    </span>
 | 
						||
  </transition-group>
 | 
						||
</template>
 | 
						||
<script>
 | 
						||
  export default {
 | 
						||
    data: function() {
 | 
						||
      return {
 | 
						||
        items: [1,2,3,4,5,6,7,8,9],
 | 
						||
        nextNum: 10
 | 
						||
      };
 | 
						||
    },
 | 
						||
    methods: {
 | 
						||
      randomIndex: function () {
 | 
						||
        return Math.floor(Math.random() * this.items.length)
 | 
						||
      },
 | 
						||
      add: function () {
 | 
						||
        this.items.splice(this.randomIndex(), 0, this.nextNum++)
 | 
						||
      },
 | 
						||
      remove: function () {
 | 
						||
        this.items.splice(this.randomIndex(), 1)
 | 
						||
      },
 | 
						||
    }
 | 
						||
  };
 | 
						||
</script>
 | 
						||
<style scoped>
 | 
						||
  .list-item {
 | 
						||
    display: inline-block;
 | 
						||
    margin-right: 10px;
 | 
						||
  }
 | 
						||
  .list-enter-active, .list-leave-active {
 | 
						||
    transition: all 1s;
 | 
						||
  }
 | 
						||
  /* .list-leave-active 适用于 2.1.8 以下版本 */
 | 
						||
  .list-enter, .list-leave-to {
 | 
						||
    opacity: 0;
 | 
						||
    transform: translateY(30px);
 | 
						||
  }
 | 
						||
</style>
 | 
						||
```
 | 
						||
 | 
						||
Vue 2 API 参考
 | 
						||
---
 | 
						||
 | 
						||
### 全局配置
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`silent` | 取消所有的日志与警告 [#](https://v2.cn.vuejs.org/v2/api/#silent)
 | 
						||
`optionMergeStrategies` | 自定义合并策略的选项 [#](https://v2.cn.vuejs.org/v2/api/#optionMergeStrategies)
 | 
						||
`devtools` | 是否允许 [devtools](https://github.com/vuejs/vue-devtools) 检查 [#](https://v2.cn.vuejs.org/v2/api/#devtools)
 | 
						||
`errorHandler` | 未捕获错误的处理函数 _(开发模式生效)_ [#](https://v2.cn.vuejs.org/v2/api/#errorHandler)
 | 
						||
`warnHandler` _(2.4.0)_ | 运行时警告处理函数 [#](https://v2.cn.vuejs.org/v2/api/#warnHandler)
 | 
						||
`ignoredElements` | 忽略 Vue 之外的 _(自定义元素)_ [#](https://v2.cn.vuejs.org/v2/api/#ignoredElements)
 | 
						||
`keyCodes` | `v-on` 自定义键位别名 [#](https://v2.cn.vuejs.org/v2/api/#keyCodes)
 | 
						||
`performance` _(2.2.0)_ | 性能追踪 [#](https://v2.cn.vuejs.org/v2/api/#performance)
 | 
						||
`productionTip` _(2.2.0)_ | 是否生成生产提示 [#](https://v2.cn.vuejs.org/v2/api/#productionTip)
 | 
						||
 | 
						||
### 全局 API
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`Vue.extend` | Vue 构造器,创建一个“子类” [#](https://v2.cn.vuejs.org/v2/api/#Vue-extend)
 | 
						||
`Vue.nextTick` | 执行延迟回调 [#](https://v2.cn.vuejs.org/v2/api/#Vue-nextTick)
 | 
						||
`Vue.set` | 向响应式对象中添加一个属性 [#](https://v2.cn.vuejs.org/v2/api/#Vue-set)
 | 
						||
`Vue.delete` | 删除对象的 property [#](https://v2.cn.vuejs.org/v2/api/#Vue-delete)
 | 
						||
`Vue.directive` | 注册或获取全局指令 [#](https://v2.cn.vuejs.org/v2/api/#Vue-directive)
 | 
						||
`Vue.filter` | 注册或获取全局过滤器 [#](https://v2.cn.vuejs.org/v2/api/#Vue-filter)
 | 
						||
`Vue.component` | 注册或获取全局组件 [#](https://v2.cn.vuejs.org/v2/api/#Vue-component)
 | 
						||
`Vue.use` | 安装 Vue.js 插件 [#](https://v2.cn.vuejs.org/v2/api/#Vue-use)
 | 
						||
`Vue.mixin` | 全局注册一个混入 [#](https://v2.cn.vuejs.org/v2/api/#Vue-mixin)
 | 
						||
`Vue.compile` | 将模板字符串编译成 render 函数 [#](https://v2.cn.vuejs.org/v2/api/#Vue-compile)
 | 
						||
`Vue.observable` _(2.6.0)_ | 让一个对象可响应 [#](https://v2.cn.vuejs.org/v2/api/#Vue-observable)
 | 
						||
`Vue.version` | Vue 安装版本号 [#](https://v2.cn.vuejs.org/v2/api/#Vue-version)
 | 
						||
 | 
						||
### 数据
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`data` | 实例的数据对象 [#](https://v2.cn.vuejs.org/v2/api/#data)
 | 
						||
`props` | 接收来自父组件的数据 [#](https://v2.cn.vuejs.org/v2/api/#props)
 | 
						||
`propsData` | 创建实例时传递 props [#](https://v2.cn.vuejs.org/v2/api/#propsData)
 | 
						||
`computed` | 计算属性将被混入到 Vue 实例中 [#](https://v2.cn.vuejs.org/v2/api/#computed)
 | 
						||
`methods` | 将被混入到 Vue 实例中 [#](https://v2.cn.vuejs.org/v2/api/#methods)
 | 
						||
`watch` | 对象键是观察的表达式,值是回调函数 [#](https://v2.cn.vuejs.org/v2/api/#watch)
 | 
						||
 | 
						||
### DOM
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`el` | 实例的挂载目标 [#](https://v2.cn.vuejs.org/v2/api/#el)
 | 
						||
`template` | 字符串模板作为 Vue 实例的标识使用 [#](https://v2.cn.vuejs.org/v2/api/#template)
 | 
						||
`render` | 字符串模板的代替方案 [#](https://v2.cn.vuejs.org/v2/api/#render)
 | 
						||
`renderError` _(2.2.0)_ | `render`错误时提供另一种渲染 [#](https://v2.cn.vuejs.org/v2/api/#renderError)
 | 
						||
 | 
						||
### 生命周期钩子
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`beforeCreate` | 实例初始化之后 [#](https://v2.cn.vuejs.org/v2/api/#beforeCreate)
 | 
						||
`created` | 实例创建完成后被立即同步调用 [#](https://v2.cn.vuejs.org/v2/api/#created)
 | 
						||
`beforeMount` | 在挂载开始之前被调用 [#](https://v2.cn.vuejs.org/v2/api/#beforeMount)
 | 
						||
`mounted` | 实例被挂载后调用 [#](https://v2.cn.vuejs.org/v2/api/#mounted)
 | 
						||
`beforeUpdate` | 数据改变后 DOM 更新之前调用 [#](https://v2.cn.vuejs.org/v2/api/#beforeUpdate)
 | 
						||
`updated` | 数据更改更新完毕之后被调用 [#](https://v2.cn.vuejs.org/v2/api/#updated)
 | 
						||
`activated` | keep-alive 缓存组件激活时调用 [#](https://v2.cn.vuejs.org/v2/api/#activated)
 | 
						||
`deactivated` | keep-alive 缓存的组件失活时调用 [#](https://v2.cn.vuejs.org/v2/api/#deactivated)
 | 
						||
`beforeDestroy` | 实例销毁之前调用 [#](https://v2.cn.vuejs.org/v2/api/#beforeDestroy)
 | 
						||
`destroyed` | 实例销毁后调用 [#](https://v2.cn.vuejs.org/v2/api/#destroyed)
 | 
						||
`errorCaptured` _(2.5.0)_ | 来自后代组件的错误时被调用 [#](https://v2.cn.vuejs.org/v2/api/#errorCaptured)
 | 
						||
 | 
						||
### 资源
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`directives` | 包含 Vue 实例可用指令的哈希表 [#](https://v2.cn.vuejs.org/v2/api/#directives)
 | 
						||
`filters` | 包含 Vue 实例可用过滤器的哈希表 [#](https://v2.cn.vuejs.org/v2/api/#filters)
 | 
						||
`components` | 包含 Vue 实例可用组件的哈希表 [#](https://v2.cn.vuejs.org/v2/api/#components)
 | 
						||
 | 
						||
### 组合
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`parent` | 指定已创建的实例之父实例 [#](https://v2.cn.vuejs.org/v2/api/#parent)
 | 
						||
`mixins` | 接收一个混入对象的数组 [#](https://v2.cn.vuejs.org/v2/api/#mixins)
 | 
						||
`extends` | 声明扩展另一个组件 [#](https://v2.cn.vuejs.org/v2/api/#extends)
 | 
						||
`provide/inject` _(2.2.0)_ | 祖组件向所有子孙后代注入依赖 [#](https://v2.cn.vuejs.org/v2/api/#provide-inject)
 | 
						||
 | 
						||
### 其它
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`name` | 允许组件模板递归地调用自身 [#](https://v2.cn.vuejs.org/v2/api/#name)
 | 
						||
`delimiters` | 改变纯文本插入分隔符 [#](https://v2.cn.vuejs.org/v2/api/#delimiters)
 | 
						||
`functional` | 使组件无状态和无实例 [#](https://v2.cn.vuejs.org/v2/api/#functional)
 | 
						||
`model` _(2.2.0)_ | 使用 v-model 时定制 prop 和 event [#](https://v2.cn.vuejs.org/v2/api/#model)
 | 
						||
`inheritAttrs` _(2.4.0)_ | [#](https://v2.cn.vuejs.org/v2/api/#inheritAttrs)
 | 
						||
`comments` _(2.4.0)_ | 是否保留模板中的`HTML`注释 [#](https://v2.cn.vuejs.org/v2/api/#comments)
 | 
						||
 | 
						||
### 实例方法 / 数据
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`vm.$watch` | 观察 Vue 实例上的一个表达式<br/>或者一个函数计算结果的变化 [#](https://v2.cn.vuejs.org/v2/api/#vm-watch)
 | 
						||
`vm.$set` | 全局 `Vue.set` 的别名 [#](https://v2.cn.vuejs.org/v2/api/#vm-set)
 | 
						||
`vm.$delete` | 全局 `Vue.delete` 的别名 [#](https://v2.cn.vuejs.org/v2/api/#vm-delete)
 | 
						||
 | 
						||
### 实例 property
 | 
						||
<!--rehype:wrap-class=row-span-3-->
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`vm.$data` | 观察的数据对象 [#](https://v2.cn.vuejs.org/v2/api/#vm-data)
 | 
						||
`vm.$props` _(2.2.0)_ | 组件接收的 props 对象 [#](https://v2.cn.vuejs.org/v2/api/#vm-props)
 | 
						||
`vm.$el` | 实例使用的根 DOM 元素 [#](https://v2.cn.vuejs.org/v2/api/#vm-el)
 | 
						||
`vm.$options` | 实例的初始化选项 [#](https://v2.cn.vuejs.org/v2/api/#vm-options)
 | 
						||
`vm.$parent` | 父实例 [#](https://v2.cn.vuejs.org/v2/api/#vm-parent)
 | 
						||
`vm.$root` | 当前组件树的根实例 [#](https://v2.cn.vuejs.org/v2/api/#vm-root)
 | 
						||
`vm.$children` | 当前实例的直接子组件 [#](https://v2.cn.vuejs.org/v2/api/#vm-children)
 | 
						||
`vm.$slots` | 访问被插槽分发的内容 [#](https://v2.cn.vuejs.org/v2/api/#vm-slots)
 | 
						||
`vm.$scopedSlots` _(2.1.0)_ | 访问作用域插槽 [#](https://v2.cn.vuejs.org/v2/api/#vm-scopedSlots)
 | 
						||
`vm.$refs` | DOM 元素和组件实例 [#](https://v2.cn.vuejs.org/v2/api/#vm-refs)
 | 
						||
`vm.$isServer` | 是否运行于服务器 [#](https://v2.cn.vuejs.org/v2/api/#vm-isServer)
 | 
						||
`vm.$attrs` _(2.4.0)_ | 包含父作用域中不作为 prop 被识别的属性绑定 ( [#](https://v2.cn.vuejs.org/v2/api/#vm-attrs)
 | 
						||
`vm.$listeners` _(2.4.0)_ | 包含了父作用域中的 (不含 .native 修饰器的) `v-on` 事件监听器 [#](https://v2.cn.vuejs.org/v2/api/#vm-listeners)
 | 
						||
 | 
						||
### 实例方法 / 事件
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`vm.$on` | 监听当前实例上的自定义事件 [#](https://v2.cn.vuejs.org/v2/api/#vm-on)
 | 
						||
`vm.$once` | 监听一个自定义事件,只触发一次 [#](https://v2.cn.vuejs.org/v2/api/#vm-once)
 | 
						||
`vm.$off` | 移除自定义事件监听器 [#](https://v2.cn.vuejs.org/v2/api/#vm-off)
 | 
						||
`vm.$emit` | 触发当前实例上的事 [#](https://v2.cn.vuejs.org/v2/api/#vm-emit)
 | 
						||
 | 
						||
### 实例方法 / 生命周期
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`vm.$mount` | 手动地挂载一个未挂载的实例 [#](https://v2.cn.vuejs.org/v2/api/#vm-mount)
 | 
						||
`vm.$forceUpdate` | 迫使 Vue 实例重新渲染 [#](https://v2.cn.vuejs.org/v2/api/#vm-forceUpdate)
 | 
						||
`vm.$nextTick` | 回调延迟执行 [#](https://v2.cn.vuejs.org/v2/api/#vm-nextTick)
 | 
						||
`vm.$destroy` | 完全销毁一个实例 [#](https://v2.cn.vuejs.org/v2/api/#vm-destroy)
 | 
						||
 | 
						||
### 指令
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`v-text` | 更新元素的 `textContent` [#](https://v2.cn.vuejs.org/v2/api/#v-text)
 | 
						||
`v-html` | 更新元素的 `innerHTML` [#](https://v2.cn.vuejs.org/v2/api/#v-html)
 | 
						||
`v-show` | 切换元素的 `display` css 属性 [#](https://v2.cn.vuejs.org/v2/api/#v-show)
 | 
						||
`v-if` | 有条件地渲染元素 [#](https://v2.cn.vuejs.org/v2/api/#v-if)
 | 
						||
`v-else` | [#](https://v2.cn.vuejs.org/v2/api/#v-else)
 | 
						||
`v-else-if` _(2.1.0)_ | [#](https://v2.cn.vuejs.org/v2/api/#v-else-if)
 | 
						||
`v-for` | 多次渲染元素或模板块 [#](https://v2.cn.vuejs.org/v2/api/#v-for)
 | 
						||
`v-on` | 绑定事件监听器 [#](https://v2.cn.vuejs.org/v2/api/#v-on)
 | 
						||
`v-bind` | 动态地绑定一个或多个属性  [#](https://v2.cn.vuejs.org/v2/api/#v-bind)
 | 
						||
`v-model` | 创建双向绑定 [#](https://v2.cn.vuejs.org/v2/api/#v-model)
 | 
						||
`v-slot` | 提供插槽或接收 prop 的插槽 [#](https://v2.cn.vuejs.org/v2/api/#v-slot)
 | 
						||
`v-pre` | 跳过元素和它的子元素编译过程 [#](https://v2.cn.vuejs.org/v2/api/#v-pre)
 | 
						||
`v-cloak` | 保持在元素上直到实例结束编译 [#](https://v2.cn.vuejs.org/v2/api/#v-cloak)
 | 
						||
`v-once` | 只渲染元素和组件一次 [#](https://v2.cn.vuejs.org/v2/api/#v-once)
 | 
						||
 | 
						||
### 特殊 attribute
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`key` | 用在 Vue 的虚拟 DOM 算法 [#](https://v2.cn.vuejs.org/v2/api/#key)
 | 
						||
`ref` | 元素或子组件注册引用信息 [#](https://v2.cn.vuejs.org/v2/api/#ref)
 | 
						||
`is` | 限制是否更新 [#](https://v2.cn.vuejs.org/v2/api/#is)
 | 
						||
~~`slot`~~ | 推荐 2.6.0 新增的 `v-slot` [#](https://v2.cn.vuejs.org/v2/api/#slot-废弃)
 | 
						||
~~`slot-scope`~~ | 推荐 2.6.0 新增的 `v-slot` [#](https://v2.cn.vuejs.org/v2/api/#slot-scope-废弃)
 | 
						||
~~`scope`~~ | `2.5.0` 新增的 `slot-scope` 取代 [#](https://v2.cn.vuejs.org/v2/api/#scope-移除)
 | 
						||
 | 
						||
### 内置的组件
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`<component>` | 渲染一个`元组件`为动态组件 [#](https://v2.cn.vuejs.org/v2/api/#component)
 | 
						||
`<transition>` | 单个元素/组件的过渡效果 [#](https://v2.cn.vuejs.org/v2/api/#transition)
 | 
						||
`<transition-group>` | 多个元素/组件的过渡效果 [#](https://v2.cn.vuejs.org/v2/api/#transition-group)
 | 
						||
`<keep-alive>` | 不活动的实例缓存不销毁 [#](https://v2.cn.vuejs.org/v2/api/#keep-alive)
 | 
						||
`<slot>` | 组件模板中的内容分发插槽 [#](https://v2.cn.vuejs.org/v2/api/#slot)
 | 
						||
 | 
						||
### v-on (事件)修饰符
 | 
						||
<!--rehype:wrap-class=row-span-2-->
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`v-on:click.stop` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 调用 event.stopPropagation()。
 | 
						||
`v-on:click.prevent` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 调用 event.preventDefault()。
 | 
						||
`v-on:click.capture` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 添加事件侦听器时使用 capture 模式。
 | 
						||
`v-on:click.self` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 只当事件是从侦听器绑定的元素本身触发时才触发回调。
 | 
						||
`v-on:click.{keyCode\|keyAlias}` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 只当事件是从特定键触发时才触发回调。
 | 
						||
`v-on:click.native` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 监听组件根元素的原生事件。
 | 
						||
`v-on:click.once` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 只触发一次回调。
 | 
						||
`v-on:click.passive` _(2.3.0)_ [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 以 { passive: true } 模式添加侦听器
 | 
						||
<!--rehype:className=style-list-->
 | 
						||
 | 
						||
### v-on (鼠标)修饰符
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`v-on:click.left` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 只当点击鼠标左键时触发
 | 
						||
`v-on:click.right` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 只当点击鼠标右键时触发
 | 
						||
`v-on:click.middle` [#](https://v2.cn.vuejs.org/v2/api/#v-on) | 只当点击鼠标中键时触发
 | 
						||
 | 
						||
在 _(2.2.0)_ 中新增
 | 
						||
 | 
						||
### 系统修饰键
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`v-on:keyup.ctrl` _(2.1.0)_ | [#](https://v2.cn.vuejs.org/v2/guide/events.html#系统修饰键)
 | 
						||
`v-on:keyup.alt` _(2.1.0)_ | [#](https://v2.cn.vuejs.org/v2/guide/events.html#系统修饰键)
 | 
						||
`v-on:keyup.shift` _(2.1.0)_ | [#](https://v2.cn.vuejs.org/v2/guide/events.html#系统修饰键)
 | 
						||
`v-on:keyup.meta` _(2.1.0)_ | [#](https://v2.cn.vuejs.org/v2/guide/events.html#系统修饰键)
 | 
						||
 | 
						||
### Keyboard 按键修饰符
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`v-on:keyup.enter` | [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
`v-on:keyup.tab` | [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
`v-on:keyup.delete` | 捕获“删除”和“退格”键 [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
`v-on:keyup.esc` | [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
`v-on:keyup.space` | [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
`v-on:keyup.up` | [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
`v-on:keyup.down` | [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
`v-on:keyup.left` | [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
`v-on:keyup.right` | [#](https://v2.cn.vuejs.org/v2/guide/events.html#按键修饰符)
 | 
						||
 | 
						||
### v-bind 修饰符
 | 
						||
 | 
						||
:- | :-
 | 
						||
:- | :-
 | 
						||
`v-bind.prop` [#](https://v2.cn.vuejs.org/v2/api/#v-bind) | 作为一个 DOM property 绑定而不是作为 attribute 绑定。([差别在哪里?](https://stackoverflow.com/questions/6003819/properties-and-attributes-in-html#answer-6004028))
 | 
						||
`v-bind.camel` _(2.1.0+)_ [#](https://v2.cn.vuejs.org/v2/api/#v-bind) | 将 kebab-case attribute 名转换为 camelCase。
 | 
						||
`v-bind.sync` _(2.3.0+)_ [#](https://v2.cn.vuejs.org/v2/api/#v-bind) | 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
 | 
						||
<!--rehype:className=style-list-->
 | 
						||
 | 
						||
另见
 | 
						||
---
 | 
						||
 | 
						||
- [Vue Essentials Cheat-Sheet.pdf](https://www.vuemastery.com/pdf/Vue-Essentials-Cheat-Sheet.pdf) _(vuemastery.com)_
 | 
						||
- [Vue 2 官方文档](https://v2.cn.vuejs.org/) _(vuejs.org)_
 | 
						||
- [Vue 2 实例方法事件](https://marozed.com/vue-cheatsheet#Instance-Methods-Events) _(marozed.com)_
 |