全局配置

Vue.config 是一个对象,包含 Vue 的全局配置,可以在启动应用之前修改下列属性

silent

  • 类型:boolean
  • 默认值:false
  • 作用:取消 vue 所有的日志和警告
1
Vue.config.silent = true;

optionMergeStrategies

  • 类型:{[key: string]: Function}
  • 默认值:{}
  • 作用:自定义混入时的合并策略,合并策略选项分别在接收父实例和子实例上定义的该选项的值作为第一个和第二个参数,vue 实例上下文被定义为第三个参数传入
1
2
3
Vue.config.optionMergeStrategies._my_option = function(parent, child, vm){
return child + 1;
}

devtools

  • 类型:boolean
  • 默认值:true (生产版本为 false)
  • 作用:配置是否允许 vue-devtools 检查代码,开发版本默认是 true,生产版本默认是 false,生产版本设为 true 可以启动检查
1
2
// 务必在加载vue后,立即同步设置以下内容
Vue.config.devtools = true;

errorHandler

  • 类型:Function
  • 默认值:undefined
  • 作用:处理发生错误的逻辑
1
2
3
4
5
Vue.config.errorHandler = function(err, vm, info){
// err 错误信息
// vm 发生错误的实例
// info 是 vue 特定的错误信息,比如错误所发生的生命钩子 例如 mounted hook
}

warnHandler

  • 类型:Function
  • 默认值:undefined
  • 作用:运行时警告赋予一个自定义处理函数,注意这只会在开发者环境下生效,在生产环境下它会被忽略
1
2
3
4
5
Vue.config.warnHandler = function(msg, vm, trace){
// trace 是组件继承关系的追踪
}

// 为 Vue 的运行时警告赋予一个自定义处理函数。注意这只会在开发者环境下生效,在生产环境下它会被忽略

ignoredElements

  • 类型:Array<String | RegExp>
  • 默认值:[]
  • 作用:须使 Vue 忽略在 Vue 之外的自定义元素 (e.g. 使用了 Web Components APIs)。否则,它会假设你忘记注册全局组件或者拼错了组件名称,从而抛出一个关于 Unknown custom element 的警告w
1
Vue.config.ignoredElements = ['ant-a', /^ion-/];

keyCodes

  • 类型:{[key: string]: number | Array<number>}
  • 默认值:{}
  • 作用:给 v-on 自定义键位别名
1
2
3
4
5
6
7
8
Vue.config.keyCodes = {
v: 86,
f1: 112,
mediaPlayPause: 179,
// 如果是使用 kebab-case(下划线形式),用双引号括起来
"media-play-pause": 179,
up: [38, 87]
}
1
<input type="text" @keyup.media-play-pause="method" />

performance

  • 类型:boolean
  • 默认值:false
  • 作用:设置为 true 以在浏览器开发工具的性能/时间线面板中启用对组件初始化、编译、渲染和打补丁的性能追踪。只适用于开发模式和支持 performance.mark API 的浏览器上
1
Vue.config.performance = true;

productionTip

  • 类型:boolean
  • 默认值:true
  • 作用:设置为true以阻止vue在启动时生产提示
1
Vue.config.productionTip = true;

全局 api

Vue.extend(options)

  • 参数:{Object} options
  • 作用:使用基础 vue 构造器,创建一个子类,参数是一个包含组件选项的对象,data 选项是特例,需要注意 Vue.extend() 中它必须是函数
1
2
3
4
5
6
7
8
9
10
11
let Component = Vue.extend({
template: `<p>{{firstName}} {{lastName}}</p>`
data(){
return {
firstName: 'Walter',
lastName: 'White'
}
}
})

new Component().$mount('#div');

Vue.nextTick([callback, context])

  • 参数:{Function} [callback] {Object} [context]
  • 作用:在下次 dom 更新循环结束之后执行延迟回调,在修改数据之后立即使用这个方法,获取最新后的 dom
1
2
3
4
5
6
7
8
9
10
11
12
13
// 修改数据
vm.msg = 'hello';

// dom 还没有更新
Vue.nextTick(function(){
// dom 更新了
})

// 作为一个promise使用
Vue.nextTick()
.then(function(){
// dom 更新了
})

Vue.set(target, propertyName / index, value)

  • 参数:{Object | Array} target {string | number} propertyName / index {any} value
  • 作用:向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi'),返回设置的值,注意不能是 vue 实例,或者 vue 实例的根数据对象
1
2
3
4
5
6
7
data(){
return {obj: {}}
},

mounted(){
setTimeout(() => this.$set(this.obj, 'name', 'suxi'), 1000);
}

Vue.delete(target, propertyName / index)

  • 参数:{Object | Array} target {string | number} propertyName / index
  • 作用:删除对象的 property。如果对象是响应式的,确保删除能触发更新视图。注意目标对象不能是一个 Vue 实例或 Vue 实例的根数据对象,这个方法主要用于避开 Vue 不能检测到 property 被删除的限制,但是你应该很少会使用它
1
2
3
4
5
6
data(){
return {obj: {name: 'peiqi'}}
},
mounted(){
setTimeout(() => this.$delete(this.obj, 'name'), 2000);
}

Vue.directive(id, [definition])

  • 参数:{string} id {Function | Object} [definition]
  • 作用:注册或获取全局指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 注册
Vue.directive('my-directive', {
bind: function () {},
inserted: function () {},
update: function () {},
componentUpdated: function () {},
unbind: function () {}
})

// 注册 (指令函数)
Vue.directive('my-directive', function () {
// 这里将会被 `bind` 和 `update` 调用
// bind 和 update是一样的行为
})

// getter,返回已注册的指令
var myDirective = Vue.directive('my-directive')

Vue.filter(id, [definition])

  • 参数:{string} id {Function} [definition]
  • 作用:注册或获取全局过滤器
1
2
3
4
5
6
7
// 注册
Vue.filter('my-filter', function (value) {
// 返回处理后的值
})

// getter,返回已注册的过滤器
var myFilter = Vue.filter('my-filter')

Vue.component(id, [definition])

  • 参数:{string} id {Function | Object} [definition]
  • 作用:注册或获取全局组件,组件还会自动使用给定的 id 设置组件的名称
1
2
3
4
5
6
7
8
// 注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({ /* ... */ }))

// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', { /* ... */ })

// 获取注册的组件 (始终返回构造器)
var MyComponent = Vue.component('my-component')

Vue.use(plugin)

  • 参数:{Object | Function} plugin
  • 作用:安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入,该方法需要在调用 new Vue() 之前被调用,当 install 方法被同一个插件多次调用,插件将只会被安装一次
1
Vue.use(vuex)

Vue.mixin(mixin)

  • 参数:{Object} mixin
  • 作用:全局注册一个混入,影响注册之后所有创建的每个 Vue 实例。插件作者可以使用混入,向组件注入自定义的行为。不推荐在应用代码中使用

Vue.compile(template)

  • 参数:{string} template
  • 作用:将一个模板编译成 render 函数
1
2
3
4
5
6
7
8
9
var res = Vue.compile('<div><span>{{ msg }}</span></div>')

new Vue({
data: {
msg: 'hello'
},
render: res.render,
staticRenderFns: res.staticRenderFns
})

Vue.observable(object)

  • 参数:{Object} object
  • 作用:让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象,返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化的跨组件状态存储器,用于简单的场景
1
2
3
4
5
6
7
8
9
const state = Vue.observable({ count: 0 })

const Demo = {
render(h) {
return h('button', {
on: { click: () => { state.count++ }}
}, `count is: ${state.count}`)
}
}

Vue.version

  • 作用:提供字符串形式的 vue 安装版本号,这对社区的插件和组件来说是非常有用的,可以根据不同的版本号采取不同的策略
1
2
3
4
5
6
7
8
9
var version = Number(Vue.version.split('.')[0])

if (version === 2) {
// Vue v2.x.x
} else if (version === 1) {
// Vue v1.x.x
} else {
// Unsupported versions of Vue
}

数据 / 选项

data

  • 类型:Object | Function
  • 作用:vue 实例的数据对象,vue 会递归地把 dataproperty 转换为 getter/setter,从而让 dataproperty 能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个的 key/value 对):浏览器 API 创建的原生对象,原型上的 property 会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象,一旦观察过,你就无法在根数据对象上添加响应式 property。因此推荐在创建实例之前,就声明所有的根级响应式 property
  • 注意:
    • 实例创建之后,可以通过 vm.$data 访问原始数据对象。Vue 实例也代理了 data 对象上所有的 property,因此访问 vm.a等价于访问 vm.$data.a
    • _$ 开头的 property 不会被 Vue 实例代理,因为它们可能和 Vue 内置的 propertyAPI 方法冲突。你可以使用例如 vm.$data._property 的方式访问这些 property
    • 当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象
    • 如果需要,可以通过将 vm.$data 传入 JSON.parse(JSON.stringify(…)) 得到深拷贝的原始数据对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var data = { a: 1 }

// 直接创建一个实例
var vm = new Vue({
data: data
})
vm.a // => 1
vm.$data === data // => true

// Vue.extend() 中 data 必须是函数
var Component = Vue.extend({
data: function () {
return { a: 1 }
}
})

// 注意,如果你为 data property 使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问
data: vm => ({a: vm.myProp})

props

  • 类型:Array<string> | Object
  • 作用:组件间数据传递,props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值
  • 语法
    • type:可以是下列原生构造函数中的一种:String、Number、Boolean、Array、Object、Date、Function、Symbol、任何自定义构造函数、或上述内容组成的数组。会检查一个 prop 是否是给定的类型,否则抛出警告
    • defaultany,为该 prop 指定一个默认值。如果该 prop 没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回
    • requiredBoolean,定义该 prop 是否是必填项。在非生产环境中,如果这个值为 truthy 且该 prop 没有被传入的,则一个控制台警告将会被抛出
    • validatorFunction,自定义验证函数会将该 prop 的值作为唯一的参数代入。在非生产环境下,如果该函数返回一个 falsy 的值 (也就是验证失败),一个控制台警告将会被抛出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 简单语法
Vue.component('props-demo-simple', {
props: ['size', 'myMessage']
})

// 对象语法,提供验证
Vue.component('props-demo-advanced', {
props: {
// 检测类型
height: Number,
// 检测类型 + 其他验证
age: {
type: Number,
default: 0,
required: true,
validator: function (value) {
return value >= 0
}
}
}
})

propsData

  • 类型:{[key: string]: any}
  • 作用:创建实例时传递 props 主要作用是方便测试
1
2
3
4
5
6
7
8
9
10
var Comp = Vue.extend({
props: ['msg'],
template: '<div>{{ msg }}</div>'
})

var vm = new Comp({
propsData: {
msg: 'hello'
}
})

computed

  • 类型:{[key: string]: Function | {get: Function, set: Function}}
  • 作用:计算属性将被混入到 Vue 实例中。所有 gettersetterthis 上下文自动地绑定为 Vue实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。
computed: {
aDouble: vm => vm.a * 2
}

// 计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意,如果某个依赖 (比如非响应式 property) 在该实例范畴之外,则计算属性是不会被更新的

var vm = new Vue({
data: { a: 1 },
computed: {
// 仅读取
aDouble: function () {
return this.a * 2
},
// 读取和设置
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
vm.aPlus // => 2
vm.aPlus = 3
vm.a // => 2
vm.aDouble // => 4

methods

  • 类型:{[key: string]: Function}
  • 作用:methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例
1
2
3
4
5
6
7
8
9
10
11
12
// 注意,不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined

var vm = new Vue({
data: { a: 1 },
methods: {
plus: function () {
this.a++
}
}
})
vm.plus()
vm.a // 2

watch

  • 类型:{[key: string]: string | Function | Object | Array}
  • 作用:watch 一个对象,键是需要观察的表单式,值是回调函数,值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个 property
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 

var vm = new Vue({
data: {
a: 1,
b: 2,
c: 3,
d: 4,
e: {
f: {
g: 5
}
}
},
watch: {
// 没有设置immediate,被侦听的变量在页面初次加载时第一次绑定值的时候,并不会执行监听操作
a: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
},
// 方法名
b: 'someMethod',
// 设置了深度监听,回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深,数组的变化不需要深度监听,对象数组中的属性变化则需要深度监听
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// 设置了immediate为true 该回调将会在侦听开始之后被立即调用
d: {
handler: 'someMethod',
immediate: true
},
// 你可以传入回调数组,它们会被逐一调用
e: [
'handle1',
function handle2 (val, oldVal) { /* ... */ },
{
handler: function handle3 (val, oldVal) { /* ... */ },
/* ... */
}
],
// watch vm.e.f's value: {g: 5}
'e.f': function (val, oldVal) { /* ... */ }
}
})
vm.a = 2 // => new: 2, old: 1

// 注意,不应该使用箭头函数来定义 watcher 函数 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例

选项 / DOM

el

  • 类型:string | Element
  • 详细:
    • 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例
    • 在实例挂载之后,元素可以用 vm.$el 访问
    • 如果在实例化时存在这个选项,实例将立即进入编译过程,否则,需要显式调用 vm.$mount() 手动开启编译
    • 提供的元素只能作为挂载点。不同于 Vue 1.x,所有的挂载元素会被 Vue 生成的 DOM 替换。因此不推荐挂载 root 实例到 <html> 或者 <body>
    • 如果 render 函数和 template property 都不存在,挂载 DOM 元素的 HTML 会被提取出来用作模板,此时,必须使用 Runtime + Compiler 构建的 Vue

template

  • 类型:string
  • 详细:
    • 一个字符串模板作为 Vue 实例的标识使用。模板将会替换挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发插槽
    • 如果值以 # 开始,则它将被用作选择符,并使用匹配元素的 innerHTML 作为模板。常用的技巧是用 <script type="x-template"> 包含模板
    • 出于安全考虑,你应该只使用你信任的 Vue 模板。避免使用其他人生成的内容作为你的模板
    • 如果 Vue 选项中包含渲染函数,该模板将被忽略

render

  • 类型:(createElement: () => VNode) => VNode
  • 详细:
    • 字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。该渲染函数接收一个 createElement 方法作为第一个参数用来创建 VNode
    • 如果组件是一个函数组件,渲染函数还会接收一个额外的 context 参数,为没有实例的函数组件提供上下文信息
    • Vue 选项中的 render 函数若存在,则 Vue 构造函数不会从 template 选项或通过 el 选项指定的挂载元素中提取出的 HTML 模板编译渲染函数

renderError

  • 类型:(createElement: () => VNode, error: Error) => VNode
  • 详细:
    • 只能在开发者环境下工作
    • render 函数遭遇错误时,提供另一种渲染输出,其错误将会作为第二个参数传递到 renderError,这个功能配合 hot-reload 非常实用
1
2
3
4
5
6
7
8
new Vue({
render (h) {
throw new Error('oops')
},
renderError (h, err) {
return h('pre', { style: { color: 'red' }}, err.stack)
}
}).$mount('#app')

选项 / 生命周期钩子

所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对 property 和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos())。这是因为箭头函数绑定了父上下文,因此 this 与你期待的 Vue 实例不同,this.fetchTodos 的行为未定义

beforeCreate

  • 类型:Function
  • 作用:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用

created

  • 类型:Function
  • 作用:在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el property 目前尚不可用

beforeMount

  • 类型:Function
  • 作用:在挂载开始之前被调用,相关的 render 函数首次被调用,该钩子在服务端渲染期间不被调用

mounted

  • 类型:Function
  • 详细:
    • 实例被挂载后调用,这时 el 被新创建的 vm.$el 替换了。如果根实例挂载到了一个文档内的元素上,当 mounted 被调用时 vm.$el 也在文档内
    • 注意 mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick
    • 该钩子在服务器端渲染期间不被调用
1
2
3
4
5
6
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}

beforeUpdate

  • 类型:Function
  • 详细:
    • 数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器
    • 该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行

updated

  • 类型:Function
  • 详细:
    • 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子
    • 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之
    • 注意 updated 不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated 里使用 vm.$nextTick
    • 该钩子在服务器端渲染期间不被调用
1
2
3
4
5
6
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}

activated

  • 类型:Function
  • 详细:
    • keep-alive 缓存的组件激活时调用
    • 该钩子在服务器端渲染期间不被调用

deactivated

  • 类型:Function
  • 详细:
    • keep-alive 缓存的组件停用时调用
    • 该钩子在服务器端渲染期间不被调用

beforeDestroy

  • 类型:Function
  • 详细:
    • 实例销毁之前调用。在这一步,实例仍然完全可用
    • 该钩子在服务器端渲染期间不被调用

destroyed

  • 类型:Function
  • 详细:
    • 实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁
    • 该钩子在服务器端渲染期间不被调用

errorCaptured

  • 类型:(err: Error, vm: Component, info: string) => ?boolean
  • 详细:
    • 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播
    • 可以在此钩子中修改组件的状态。因此在捕获错误时,在模板或渲染函数中有一个条件判断来绕过其它内容就很重要;不然该组件可能会进入一个无限的渲染循环
  • 错误传播规则
    • 默认情况下,如果全局的 config.errorHandler 被定义,所有的错误仍会发送它,因此这些错误仍然会向单一的分析服务的地方进行汇报
    • 如果一个组件的继承或父级从属链路中存在多个 errorCaptured 钩子,则它们将会被相同的错误逐个唤起
    • 如果此 errorCaptured 钩子自身抛出了一个错误,则这个新错误和原本被捕获的错误都会发送给全局的 config.errorHandler
    • 一个 errorCaptured 钩子能够返回 false阻止错误继续向上传播。它会阻止其它任何会被这个错误唤起的 errorCaptured 钩子和全局的 config.errorHandler

选项 / 资源

directives

  • 类型:Object
  • 作用:包含 Vue 实例可用指令的哈希表

filters

  • 类型:Object
  • 作用:包含 Vue 实例可用过滤器的哈希表

components

  • 类型:Object
  • 作用:包含 Vue 实例可用组件的哈希表

选项 / 组合

parent

  • 类型:vue instance
  • 详细:
    • 指定已创建的实例之父实例,在两者之间建立父子关系。子实例可以用 this.$parent 访问父实例,子实例被推入父实例的 $children 数组中
    • 节制地使用 $parent$children - 它们的主要目的是作为访问组件的应急方法。更推荐用 propsevents 实现父子组件通信

mixins

  • 类型:Array<Object>
  • 详细:
    • mixins 选项接收一个混入对象的数组。这些混入对象可以像正常的实例对象一样包含实例选项,这些选项将会被合并到最终的选项中,使用的是和 Vue.extend() 一样的选项合并逻辑。也就是说,如果你的混入包含一个 created 钩子,而创建组件本身也有一个,那么两个函数都会被调用
    • mixin 钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用
1
2
3
4
5
6
7
8
9
var mixin = {
created: function () { console.log(1) }
}
var vm = new Vue({
created: function () { console.log(2) },
mixins: [mixin]
})
// => 1
// => 2

extends

  • 类型:Object | Function
  • 作用:允许声明扩展另一个组件 (可以是一个简单的选项对象或构造函数),而无需使用 Vue.extend。这主要是为了便于扩展单文件组件
1
2
3
4
5
6
7
var CompA = { ... }

// 在没有调用 `Vue.extend` 时候继承 CompA
var CompB = {
extends: CompA,
...
}

provide / inject

  • 类型:
    • provideObject | () => Object
    • injectArray<string> | {[key: string]: string | Symbol | Object}
  • 详细:
    • 这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性(context)很相似
    • provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 SymbolReflect.ownKeys 的环境下可工作
    • inject 选项应该是:一个字符串数组,或一个对象,对象的 key 是本地的绑定名,value 是在可用的注入内容中搜索用的 key (字符串或 Symbol),或一个对象,该对象的 from property 是在可用的注入内容中搜索用的 key (字符串或 Symbol),default property 是降级情况下使用的 value
    • provideinject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}

// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
// ...
}

// 使用symbol
const s = Symbol()

const Provider = {
provide () {
return {
[s]: 'foo'
}
}
}

const Child = {
inject: { s },
// ...
}
// 使用注入的值作为一个 property 的默认值
const Child = {
inject: ['foo'],
props: {
bar: {
default () {
return this.foo
}
}
}
}
// 使用一个注入的值作为数据入口
const Child = {
inject: ['foo'],
data () {
return {
bar: this.foo
}
}
}
// 使用默认值使其变成可选项
const Child = {
inject: {
foo: { default: 'foo' }
}
}
// 如果它需要从一个不同名字的 property 注入,则使用 from 来表示其源 property
const Child = {
inject: {
foo: {
from: 'bar',
default: 'foo'
}
}
}
// 与 prop 的默认值类似,你需要对非原始值使用一个工厂方法
const Child = {
inject: {
foo: {
from: 'bar',
default: () => [1, 2, 3]
}
}
}

选项 / 其它

name

  • 类型:string
  • 详细:
    • 只有作为组件选项时起作用
    • 允许组件模板递归地调用自身。注意,组件在全局用 Vue.component() 注册时,全局 ID 自动作为组件的 name
    • 指定 name 选项的另一个好处是便于调试。有名字的组件有更友好的警告信息。另外,当在有 vue-devtools,未命名组件将显示成 <AnonymousComponent>,这很没有语义。通过提供 name 选项,可以获得更有语义信息的组件树

delimiters

  • 类型:Array<string>
  • 默认值:["{{", "}}"]
  • 详细:
    • 这个选项只在完整构建版本中的浏览器内编译时可用
    • 改变纯文本插入符号
1
2
3
4
5
new Vue({
delimiters: ['${', '}']
})

// 插值由 {{}} 变成了 ${}

functional

  • 类型:boolean
  • 作用:使组件无状态 (没有 data) 和无实例 (没有 this 上下文)。他们用一个简单的 render 函数返回虚拟节点使它们渲染的代价更小

model

  • 类型:{ prop?: string, event?: string }
  • 作用:允许一个自定义组件在使用 v-model 时定制 propevent。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突
  • 简单来说就是将自定义组件实现数据双向绑定的效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// v-model的语法糖
<input v-model="value" />
// 相当于
<input v-bind="value" @input="value = $event.target.value" />

// 模块化 model 自定义

<my-component :value="value" />
// 或者
<my-component v-model="value" />


export default{
model: {
prop: 'value',
event: 'change'
},
prop: {
value: {
type: String
}
},
methods: {
// 自己触发事件
// 传过来的值改变了
op(){
this.$emit('change', '佩奇');
}
}
}

<my-component :value="value" @change="this.value = $event" />


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Vue.component('my-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
// this allows using the `value` prop for a different purpose
value: String,
// use `checked` as the prop which take the place of `value`
checked: {
type: Number,
default: 0
}
},
// ...
})
1
2
3
4
5
6
7
8
9
<my-checkbox v-model="foo" value="some value"></my-checkbox>

// 相当于

<my-checkbox
:checked="foo"
@change="val => { foo = val }"
value="some value">
</my-checkbox>

inheritAttrs

  • 类型:boolean
  • 默认值:true
  • 作用:默认情况下,组件的根元素会继承组件的属性,如果不希望继承,设置为 false。取消默认继承后,可以通过 $attrs 属性显性的 v-bind 根元素上,注意:这个选项不影响 classstyle 绑定

comments

  • 类型:boolean
  • 默认值:false
  • 作用:当设为 true 时,将会保留且渲染模板中的 HTML 注释。默认行为是舍弃它们,注意,这个选项只在完整构建版本中的浏览器内编译时可用

实例 property

vm.$data

  • 类型:Object
  • 作用:Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象 property 的访问

vm.$props

  • 类型:Object
  • 作用:当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象 property 的访问

vm.$el

  • 类型:Element
  • 作用:Vue 实例使用的根 DOM 元素,只读属性

vm.$options

  • 类型:Object
  • 作用:用于当前 Vue 实例的初始化选项。需要在选项中包含自定义 property 时会有用处,只读属性
1
2
3
4
5
6
new Vue({
customOption: 'foo',
created: function () {
console.log(this.$options.customOption) // => 'foo'
}
})

vm.$parent

  • 类型:Vue instance
  • 作用:获取父实例对象,只读属性

vm.$root

  • 类型:Vue instance
  • 作用:获取根实例对象,只读属性

vm.$children

  • 类型:`Array
  • 作用:当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源

vm.$slots

  • 类型:{ [name: string]: ?Array<VNode> }
  • 详细:
    • 无响应性
    • 用来访问被插槽分发的内容。每个具名插槽有其相应的 property (例如:v-slot:foo 中的内容将会在 vm.$slots.foo 中被找到)。default property 包括了所有没有被包含在具名插槽中的节点,或 v-slot:default 的内容
    • 请注意插槽不是响应性的。如果你需要一个组件可以在被传入的数据发生变化时重渲染,我们建议改变策略,依赖诸如 propsdata 等响应性实例选项
    • 在使用渲染函数书写一个组件时,访问 vm.$slots 最有帮助
1
2
3
4
5
6
7
8
9
10
11
12
13
<blog-post>
<template v-slot:header>
<h1>About Me</h1>
</template>

<p>Here's some page content, which will be included in vm.$slots.default, because it's not inside a named slot.</p>

<template v-slot:footer>
<p>Copyright 2016 Evan You</p>
</template>

<p>If I have some content down here, it will also be included in vm.$slots.default.</p>.
</blog-post>
1
2
3
4
5
6
7
8
9
10
11
12
Vue.component('blog-post', {
render: function (createElement) {
var header = this.$slots.header
var body = this.$slots.default
var footer = this.$slots.footer
return createElement('div', [
createElement('header', header),
createElement('main', body),
createElement('footer', footer)
])
}
})

vm.$scopedSlots

  • 类型:{ [name: string]: props => Array<VNode> | undefined }
  • 详细:
    • 用来访问作用域插槽。对于包括 默认 slot 在内的每一个插槽,该对象都包含一个返回相应 VNode 的函数
    • vm.$scopedSlots 在使用渲染函数开发一个组件时特别有用
  • 注意:
    • 作用域插槽函数现在保证返回一个 VNode 数组,除非在返回值无效的情况下返回 undefined
    • 所有的 $slots 现在都会作为函数暴露在 $scopedSlots 中。如果你在使用渲染函数,不论当前插槽是否带有作用域,我们都推荐始终通过 $scopedSlots 访问它们。这不仅仅使得在未来添加作用域变得简单,也可以让你最终轻松迁移到所有插槽都是函数的 Vue 3

vm.$refs

  • 类型:Object
  • 作用:一个对象,持有注册过 ref attribute 的所有 DOM 元素和组件实例,只读属性

vm.$isServer

  • 类型:boolean
  • 作用:当前 vue 实例是否运行于服务器,只读属性

vm.$attrs

  • 类型:{ [key: string]: string }
  • 作用:包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (classstyle 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (classstyle 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用,只读属性
1
<super-component :value="{1}" />

vm.$listeners

  • 类型:{ [key: string]: Function | Array<Function> }
  • 作用:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用

实例方法 / 数据

vm.$watch( expOrFn, callback, [options] )

  • 参数:
    • {string | Function} expOrFn
    • {Function | Object} callback
    • {Object} [options]
      • {boolean} deep
      • {boolean} immediate
  • 返回值:{Function} unwatch
  • 作用:观察 Vue 实例上的一个表达式或者一个函数计算结果的变化。回调函数得到的参数为新值和旧值。表达式只接受简单的键路径。对于更复杂的表达式,用一个函数取代
  • 注意:在变更 (不是替换) 对象或数组时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变更之前值的副本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 键路径
vm.$watch('a.b.c', function (newVal, oldVal) {
// 做点什么
})

// 函数
vm.$watch(
function () {
// 表达式 `this.a + this.b` 每次得出一个不同的结果时
// 处理函数都会被调用。
// 这就像监听一个未被定义的计算属性
return this.a + this.b
},
function (newVal, oldVal) {
// 做点什么
}
)


// vm.$watch 返回一个取消观察函数,用来停止触发回调:
var unwatch = vm.$watch('a', cb)
// 之后取消观察
unwatch()
  • 选项:deep,为了发现对象内部值的变化,可以在选项参数中指定 deep: true。注意监听数组的变更不需要这么做
1
2
3
4
5
vm.$watch('someObject', callback, {
deep: true
})
vm.someObject.nestedValue = 123
// callback is fired
  • 选项:immediate,在选项参数中指定 immediate: true 将立即以表达式的当前值触发回调,注意在带有 immediate 选项时,不能在第一次回调时取消侦听器侦听给定的 property
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
vm.$watch('a', callback, {
immediate: true
})
// 立即以 `a` 的当前值触发回调


// 这会导致报错
var unwatch = vm.$watch(
'value',
function () {
doSomething()
unwatch()
},
{ immediate: true }
)

// 如果你仍然希望在回调内部调用一个取消侦听的函数,你应该先检查其函数的可用性
var unwatch = vm.$watch(
'value',
function () {
doSomething()
if (unwatch) {
unwatch()
}
},
{ immediate: true }
)

vm.$set( target, propertyName/index, value )

  • 参数:
    • {Object | Array} target
    • {string | number} propertyName/index
    • {any} value
  • 作用:这是全局 Vue.set 的别名,返回设置的值

vm.delete(target, propertyName/index)

  • 参数:
    • {Object | Array} target
    • {string | number} propertyName/index
  • 作用:这是 Vue.delete 的别名

实例方法 / 事件

vm.$on(event, callback)

  • 参数:
    • {string | Array<string>} event
    • {Function} callback
  • 作用:监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。回调函数会接收所有传入事件触发函数的额外参数
1
2
3
4
5
vm.$on('test', function (msg) {
console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"

vm.$once(event, callback)

  • 参数:
    • {string} event
    • {Function} callback
  • 作用:监听一个自定义事件,但只触发一次,监听器就会被移除

vm.$off([event, callback])

  • 参数:
    • {string | Array<string>} event
    • {Function} callback
  • 作用:
    • 移除自定义事件监听器
    • 如果没有提供参数,则移除所有事件监听器
    • 如果只提供了事件名,则移除该事件所有的监听器
    • 如果同时提供了事件和回调,则只移除这个回调的监听器

vm.$emit(eventName, [...args])

  • 参数:

    • {string} eventName
    • [...args]
  • 作用:触发当前实例上的事件,附加参数都会传给监听器回调

1
2
3
4
5
6
7
Vue.component('welcome-button', {
template: `
<button v-on:click="$emit('welcome')">
Click me to be welcomed
</button>
`
})
1
2
3
<div id="emit-example-simple">
<welcome-button v-on:welcome="sayHi"></welcome-button>
</div>
1
2
3
4
5
6
7
8
new Vue({
el: '#emit-example-simple',
methods: {
sayHi: function () {
alert('Hi!')
}
}
})

实例方法 / 生命周期

vm.$mount([elementOrSelector])

  • 参数:
    • {Element | string} [elementOrSelector]
    • {boolean} [hydrating]
  • 返回值:vm 实例自身
  • 用法:
    • 如果 Vue 实例在实例化时没有收到 el 选项,则它处于未挂载状态,没有关联的 DOM 元素。可以使用 vm.$mount() 手动地挂载一个未挂载的实例
    • 如果没有提供 elementOrSelector 参数,模板将被渲染为文档之外的的元素,并且你必须使用原生 DOM API 把它插入文档中
1
2
3
4
5
6
7
8
9
10
11
12
13
var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})

// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')

// 同上
new MyComponent({ el: '#app' })

// 或者,在文档之外渲染并且随后挂载
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)

vm.$forceUpdate()

  • 作用:迫使 vue 实例重新渲染,注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件

vm.$nextTick([callback])

  • 参数:{Function} [callback]
  • 作用:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
new Vue({
// ...
methods: {
// ...
example: function () {
// 修改数据
this.message = 'changed'
// DOM 还没有更新
this.$nextTick(function () {
// DOM 现在更新了
// `this` 绑定到当前实例
this.doSomethingElse()
})
}
}
})

vm.$destroy()

  • 用法:完全销毁一个实例,清理它与其它实例的连接,解绑它的全部指令及事件监听器,触发 beforeDestroydestroyed 钩子

指令

v-text

  • 预期:string
  • 详细:更新元素的 textContent,如果要更新部分的 textContent,需要使用 {{Mustache}} 插值
1
2
3
<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>

v-html

  • 预期:string
  • 详细:更新元素的 innerHTML。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代
  • 注意:
    • 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击,只在可信内容上使用 v-html,永不用在用户提交的内容上
    • 在单文件组件里,scoped 的样式不会应用在 v-html 内部,因为那部分 HTML 没有被 Vue 的模板编译器处理。如果你希望针对 v-html 的内容设置带作用域的 CSS,你可以替换为 CSS Modules 或用一个额外的全局 <style> 元素手动设置类似 BEM 的作用域策略
1
<div v-html="html"></div>

v-show

  • 预期:any
  • 作用:根据表达式之真假值,切换元素的 display CSS property,当条件变化时该指令触发过渡效果

v-if

  • 预期:any
  • 作用:根据表达式的值的 truthiness 来有条件地渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。如果元素是 <template>,将提出它的内容作为条件块,当条件变化时该指令触发过渡效果
  • 注意:当和 v-if 一起使用时,v-for 的优先级比 v-if 更高

v-else

  • 限制:前一兄弟元素必须有 v-ifv-else-if
  • 作用:条件渲染
1
2
3
4
5
6
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>

v-else-if

  • 类型:any
  • 限制:前一兄弟元素必须有 v-ifv-else-if
  • 作用:条件渲染
1
2
3
4
5
6
7
8
9
10
11
12
<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>

v-for

  • 预期:Array | Object | number | string | Iterable
  • 用法:基于源数据多次渲染元素或模板块。此指令之值,必须使用特定语法 alias in expression,为当前遍历的元素提供别名
  • 新增:v-for 实现了部署了 Interable 接口的值,包括原生的 MapSet,不过 vue2.x 目前不支持响应式的 MapSet,所以无法自动探测到变更
  • 注意:当和 v-if 一起使用时,v-for 的优先级比 v-if 更高
1
2
3
4
5
6
7
8
9
10
11
<div v-for="item in items">
{{ item.text }}
</div>

<div v-for="(item, index) in items"></div>
<div v-for="(val, key) in object"></div>
<div v-for="(val, name, index) in object"></div>

<div v-for="item in items" :key="item.id">
{{ item.text }}
</div>

v-on

  • 缩写:@
  • 预期:Function | Inline Statement | Object
  • 参数:event
  • 修饰符:
    • .stop - 调用 event.stopPropagation()
    • .prevent - 调用 event.preventDefault()
    • .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} 模式添加侦听器
  • 用法:
    • 绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略
    • 用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件
    • 在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event property:v-on:click="handle('ok', $event)"
    • 2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!-- 方法处理器 -->
<button v-on:click="doThis"></button>

<!-- 动态事件 (2.6.0+) -->
<button v-on:[event]="doThis"></button>

<!-- 内联语句 -->
<button v-on:click="doThat('hello', $event)"></button>

<!-- 缩写 -->
<button @click="doThis"></button>

<!-- 动态事件缩写 (2.6.0+) -->
<button @[event]="doThis"></button>

<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>

<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>

<!-- 阻止默认行为,没有表达式 -->
<form @submit.prevent></form>

<!-- 串联修饰符 -->
<button @click.stop.prevent="doThis"></button>

<!-- 键修饰符,键别名 -->
<input @keyup.enter="onEnter">

<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">

<!-- 点击回调只会触发一次 -->
<button v-on:click.once="doThis"></button>

<!-- 对象语法 (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
在子组件上监听自定义事件 (当子组件触发“my-event”时将调用事件处理器):

<my-component @my-event="handleThis"></my-component>

<!-- 内联语句 -->
<my-component @my-event="handleThis(123, $event)"></my-component>

<!-- 组件中的原生事件 -->
<my-component @click.native="onClick"></my-component>

v-bind

  • 缩写::
  • 预期:any (with argument) | Object (without argument)
  • 参数:attrOrProp (optional)
  • 修饰符:
    • .prop
    • .camel
    • .sync
  • 用法:
    • 动态地绑定一个或多个 attribute,或一个组件 prop 到表达式
    • 在绑定 classstyle attribute 时,支持其它类型的值,如数组或对象
    • 在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型
    • 没有参数时,可以绑定到一个包含键值对的对象。注意此时 classstyle 绑定不支持数组和对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!-- 绑定一个 attribute -->
<img v-bind:src="imageSrc">

<!-- 动态 attribute 名 (2.6.0+) -->
<button v-bind:[key]="value"></button>

<!-- 缩写 -->
<img :src="imageSrc">

<!-- 动态 attribute 名缩写 (2.6.0+) -->
<button :[key]="value"></button>

<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- class 绑定 -->
<div :class="{red: isRed}"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, {classB: isB, classC: isC}]">

<!-- style 绑定 -->
<div :style="{fontSize: size + 'px'}"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个全是 attribute 的对象 -->
<div v-bind="{id: someProp, 'other-attr': otherProp}"></div>

<!-- 通过 prop 修饰符绑定 DOM attribute -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>

<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

.camel 修饰符允许在使用 DOM 模板时将 v-bind property 名称驼峰化,例如 SVGviewBox property,在使用字符串模板或通过 vue-loader / vueify 编译时,无需使用 .camel

1
<svg :view-box.camel="viewBox"></svg>

v-model

  • 预期:随表单控件类型不同而不同
  • 限制:
    • input
    • select
    • textarea
    • components
  • 修饰符:
    • .lazy - 取代 input 监听 change 事件
    • .number - 输入字符串转为有效的数字
    • .trim - 输入首尾空格过滤
  • 用法:在表单控件或组件上创建双向绑定

v-slot

  • 缩写:#
  • 预期:可放置在函数参数位置的 javascript 表达式,可选,只需要在为插槽传入 prop 的时候使用
  • 参数:插槽名(可选,默认是 default)
  • 限制:
    • template
    • 组件
  • 用法:提供具名插槽或需要接收 prop 的插槽
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- 具名插槽 -->
<base-layout>
<template v-slot:header>
Header content
</template>

Default slot content

<template v-slot:footer>
Footer content
</template>
</base-layout>

<!-- 接收 prop 的具名插槽 -->
<infinite-scroll>
<template v-slot:item="slotProps">
<div class="item">
{{ slotProps.item.text }}
</div>
</template>
</infinite-scroll>

<!-- 接收 prop 的默认插槽,使用了解构 -->
<mouse-position v-slot="{ x, y }">
Mouse position: {{ x }}, {{ y }}
</mouse-position>

v-pre

  • 不需要参数
  • 用法:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译
1
2
3
4
5
<span v-pre>{{ this will not be compiled }}</span>

<span v-pre>{{me}}</span>

<!-- 原样 <span>{{me}}</span> -->

v-cloak

  • 不需要表达式
  • 用法:这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] {display: none} 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕
1
2
3
[v-cloak] {
display: none;
}
1
2
3
4
<!-- 直到编译结束后显示 -->
<div v-cloak>
{{ message }}
</div>

v-once

  • 不需要表达式
  • 详细:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 单个元素 -->
<span v-once>This will never change: {{msg}}</span>
<!-- 有子元素 -->
<div v-once>
<h1>comment</h1>
<p>{{msg}}</p>
</div>
<!-- 组件 -->
<my-component v-once :comment="msg"></my-component>
<!-- `v-for` 指令-->
<ul>
<li v-for="i in list" v-once>{{i}}</li>
</ul>

特殊的 attribute

key

  • 预期:number | string | boolean (2.4.2 新增) | symbol (2.5.12 新增)
  • key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 keyVue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素
  • 有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误
  • 它可以用于强制替换元素 / 组件,而不是重复使用它
    • 完整地触发组件的生命周期钩子
    • 触发过渡
1
2
3
4
<!-- 当 text 改变时,span总是被替换而不是修改 text的内容 -->
<transition>
<span :key="text">{{ text }}</span>
</transition>

ref

  • 预期:string

ref被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例

1
2
3
4
5
<!-- `vm.$refs.p` will be the DOM node -->
<p ref="p">hello</p>

<!-- `vm.$refs.child` will be the child component instance -->
<child-component ref="child"></child-component>

v-for 用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组

关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs 也不是响应式的,因此你不应该试图用它在模板中做数据绑定

is

  • 预期:string | Object(组件的选项对象)

用于动态组件且基于DOM内模板的限制来工作

1
2
3
4
5
6
7
8
<!-- 当 `currentView` 改变时,组件也跟着改变 -->
<component v-bind:is="currentView"></component>

<!-- 这样做是有必要的,因为 `<my-row>` 放在一个 -->
<!-- `<table>` 内可能无效且被放置到外面 -->
<table>
<tr is="my-row"></tr>
</table>

slot

已经废弃,使用 v-slot 代替它,用于标记哪个具名插槽中插入子组件内容

slot-scope

已经废弃,使用 v-slot="property" 代替

scope

已经废弃,使用 v-slot:attrbute#attrbute 代替

内置的组件

component

  • propsfsf
    • is
    • inline-template
  • 用法
    • 渲染一个元组件为动态组件,根据 is 的值,来决定哪个组件被渲染
1
2
3
4
5
<!-- 动态组件由 vm 实例的 `componentId` property 控制 -->
<component :is="componentId"></component>

<!-- 也能够渲染注册过的组件或 prop 传入的组件 -->
<component :is="$options.components.child"></component>

transition

  • props
    • name - string,用于自动生成 CSS 过渡类名。例如:name: 'fade' 将自动拓展为 .fade-enter,.fade-enter-active 等。默认类名为 v
    • appear - boolean,是否在初始渲染时使用过渡。默认为 false
    • css - boolean,是否使用 CSS 过渡类。默认为 true。如果设置为 false,将只通过组件事件触发注册的 JavaScript 钩子。
    • type - string,指定过渡事件类型,侦听过渡何时结束。有效值为 transitionanimation。默认 Vue.js 将自动检测出持续时间长的为过渡事件类型
    • mode - string,控制离开/进入过渡的时间序列。有效的模式有 out-inin-out;默认同时进行。
    • duration - number | {enter: number, leave: number} 指定过渡的持续时间。默认情况下,Vue 会等待过渡所在根元素的第一个 transitionendanimationend 事件。
    • enter-class - string
    • leave-class - string
    • appear-class - string
    • enter-to-class - string
    • leave-to-class - string
    • appear-to-class - string
    • enter-active-class - string
    • leave-active-class - string
    • appear-active-class - string
  • 事件
    • before-enter
    • before-leave
    • before-appear
    • enter
    • leave
    • appear
    • after-enter
    • after-leave
    • after-appear
    • enter-cancelled
    • leave-cancelled (v-show only)
    • appear-cancelled
  • 用法:

<transition> 元素作为单个元素/组件的过渡效果。<transition> 只会把过渡效果应用到其包裹的内容上,而不会额外渲染 DOM 元素,也不会出现在可被检查的组件层级中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 简单元素 -->
<transition>
<div v-if="ok">toggled content</div>
</transition>

<!-- 动态组件 -->
<transition name="fade" mode="out-in" appear>
<component :is="view"></component>
</transition>

<!-- 事件钩子 -->
<div id="transition-demo">
<transition @after-enter="transitionComplete">
<div v-show="ok">toggled content</div>
</transition>
</div>
1
2
3
4
5
6
7
8
9
new Vue({
...
methods: {
transitionComplete: function (el) {
// 传入 'el' 这个 DOM 元素作为参数。
}
}
...
}).$mount('#transition-demo')

transition-group

  • props
    • tag - string,默认是 span
    • move-class - 覆盖移动过渡期间应用的 css
    • 除了 mode,其他 attributetransition 相同
  • 事件
    • 事件和 transition 相同
  • 用法
    • <transition-group> 元素作为多个元素/组件的过渡效果。<transition-group> 渲染一个真实的 DOM 元素。默认渲染 <span>,可以通过 tag attribute 配置哪个元素应该被渲染
    • <transition-group> 支持通过 CSS transform 过渡移动。当一个子节点被更新,从屏幕上的位置发生变化,它会被应用一个移动中的 CSS 类 (通过 name attribute 或配置 move-class attribute 自动生成)。如果 CSS transform property 是可过渡property,当应用移动类时,将会使用 FLIP 技术使元素流畅地到达动画终点
1
2
3
4
5
<transition-group tag="ul" name="slide">
<li v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</transition-group>

keep-alive

  • props
    • include - 字符串或正则表达式,只有名称匹配的组件会被缓存
    • exclude - 字符串或正则表达式,任何名称匹配的组件都不会被缓存
    • max - 最多可以缓存多少个组件实例
  • 用法
    • <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中
    • 当组件在 <keep-alive> 内被切换,它的 activateddeactivated 这两个生命周期钩子函数将会被对应执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 在 2.2.0 及其更高版本中,activated 和 deactivated 将会在 <keep-alive> 树内的所有嵌套组件中触发 -->
<!-- 主要用于保留组件状态或避免重新渲染 -->
<!-- 基本 -->
<keep-alive>
<component :is="view"></component>
</keep-alive>

<!-- 多个条件判断的子组件 -->
<keep-alive>
<comp-a v-if="a > 1"></comp-a>
<comp-b v-else></comp-b>
</keep-alive>

<!-- 和 `<transition>` 一起使用 -->
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>

注意,keep-alive用在其一个直属的子组件被开关的情形,如果你在其中有 v-for 则不会工作。如果有上述的多个条件性的子元素,<keep-alive> 要求同时只有一个子元素被渲染

includeexclude 允许组件有条件地缓存,二者都可以用逗号分割字符串、正则表达式或一个数字表示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
<component :is="view"></component>
</keep-alive>

匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配

max 表示最多可以缓存多少组件,一旦这个数字达到了,新实例创建之前,已缓存组件中最久没有被访问的实例会被销毁

1
2
3
4
<!-- <keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例 -->
<keep-alive :max="10">
<component :is="view"></component>
</keep-alive>

slot

  • propsname - string 用于命名插槽
  • usage: slot 元素作为组件模板之中的内容分发插槽,slot 元素自身将会被替换