theme: v-green
精读 Vue 官方文档系列 🎉
创建组件时的配置项,属于 optionsAPI 范畴。
组件选项 - 数据
data
值必须是一个函数
为了防止跨组件共享数据,组件的 data
选项必须是一个函数。
data
函数返回的数据对象,会被 Vue 递归处理,最终转换为带有 getter/setter 的响应式对象。
访问 Vue 实例的数据对象
可以通过 vm.$data.property
的方式访问,也可以使用 vm.property
的方式访问响应式对象,因为 Vue 实例已经代理了对 $data
的访问。
私有的数据对象
以 _
或 $
开头的 property 不会被 Vue 实例代理,因为它们可能和 Vue 内置的 property、API 方法冲突。你可以使用例如 vm.$data._property
的方式访问这些 property。
data: (vm) => {
return {
_msg:'111'
};
},
mounted(){
console.log(this.$data._msg)
}
关于 data
函数内的 this
data
函数里面通过 this
来访问当前组件的实例,但是如果 data
是一个箭头函数,那么只能通过接受参数的形式来访问当前的组件实例。
{
props: {
myProp: String,
},
data: (vm) => {
return {
msg: vm.myProps,
};
}
}
究其本质是因为箭头函数的
this
永远指向的是上一个作用域的上下文对象。而data
的初始化是在独立的initData
->getData
函数中进行,它们的上下文对象,非严格模式下是window
对象,严格模式下则为undefined
。
在 Vue 源码 initState
中会首先初始化 props
与 mthods
,所以 data
选项函数中就可以事先拿到这些值,来帮助初始化响应式数据。
props
值可以是一个对象或数组,数组可以声明多种类型,对象则允许更高级的配置:
- 类型检查:
type
的值除了原生的构造函数,也可以通过as
类型断言结合 TypeScript 类型声明一起使用。 - 默认值:
default
,为该prop
指定一个默认值。 - 是否必传:
required
,值是一个Boolean
类型。 - 校验值:
validator
,值是一个Function
,返回值是一个布尔类型,用于表明校验的状态。
propsData
只用于 new 创建的实例中,可以实时传入 props
,方便测试。
var Comp = Vue.extend({
props: ['msg'],
template: '<div>{{ msg }}</div>'
})
var vm = new Comp({
propsData: {
msg: 'hello'
}
})
computed
- 计算属性是通过混入的方式加入到 Vue 实例中,可以通过
vm
组件实例来直接访问。所有的 getter/setter 函数的this
上下都将自动绑定为 Vue 实例。 - 计算属性的结果会被缓存,只有依赖的响应式对象发生更改时,才会重新计算。
- 计算属性如果没有使用到,则不会执行,因此具有懒执行的特性。
- 计算属性方法如果是一个箭头函数,则也会遇到
data
选项函数同样的问题,此时可以通过参数的方式来访问当前组件实例。
computed: {
aDouble: vm => vm.a * 2
}
methods
methods
中的方法是以混入的方式加入到 Vue 实例中的,所以我们可以通过的 vm
组件实例来直接访问这些方法。并且方法内部的 this
也是自动绑定为当前的组件实例。
不应该使用箭头函数来定义
method
方法,因为它的上下文永远是父级的上下文对象。
watch
值是一个对象,对象的 key
是要监听的表达式,value
则是对应的回调函数。
{
a:function(){},
'b.c':function(){}
}
value
也可以是一个方法名,Vue 会自动调用 vm.$methods
中同名的方法。
{
d:'doSomeThing'
}
否则是一个对象选项,可以实现更丰富的监听设置。
e:{
handler: function(){},
deep:true,
immediate:true
}
不应该使用箭头函数来定义
watch
的方法,因为它的上下文永远是父级的上下文对象。
组件选项 - DOM
el
只在用 new 创建实例时生效。
提供一个在页面上已存在的 DOM 元素作为值,可灵活的将组件挂载到指定的 DOM 位置。
在实例挂载之后,元素可以用 vm.$el
访问。
注意,如果组件选项不存在
template
也不存在render
选项,那么el
指定 DOM 元素的innerHTML
内容将会被取出来作为模板使用。此种方式只能用于完整版(Runtime + Compiler)的 Vue 中。
template
字符串模板。如果值是以 #
开始,则会作为选择符,将匹配到的 X-Template
元素的 innerHTML
值作为模板。
出于安全考虑,你应该只使用你信任的 Vue 模板。避免使用其他人生成的内容作为你的模板。 如果 Vue 选项中包含渲染函数,该模板将被忽略。
render
渲染函数,接收一个 createElement
参数,可使用 JavaScript 编程能力来创建 Vnode,其优先级高于 template
字符串模板方式。
如果组件是一个函数组件,渲染函数还会接收一个额外的 context 参数,为没有实例的函数组件提供上下文信息。
renderError
只用于开发环境。
当 render
函数遭遇错误时,提供另外一种渲染输出。其错误将会作为第二个参数传递到 renderError
。这个功能配合 hot-reload 非常实用。
new Vue({
render (h) {
throw new Error('oops')
},
renderError (h, err) {
return h('pre', { style: { color: 'red' }}, err.stack)
}
}).$mount('#app')
组件选项 - 生命周期钩子
beforeCreate
此时响应式数据、事件方法、watch 都还没有被初始化,所以无法使用。
created
此时响应式数据、事件方法、watch 都可以使用,但是组件还没有渲染与挂载,所以 $el
property 还不可用。
beforeMount
挂载之前调用,相关的 render
函数被首次调用,此时 Vnode 开始创建。
mounted
实例被挂载后调用,此时 $el
可以被访问。
注意 mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick:
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。
注意 updated 不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated 里使用 vm.$nextTick:
actived
被 keep-alive 缓存的组件激活时调用。
deactived
被 keep-alive 缓存的组件停用时调用。
beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。 通常我们会在这里清除定时器、解除全局的事件监听。
destroyed
Vue 实例销毁后调用。 对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
errorCaptured
当捕获到一个来自子孙组件的错误时被调用。
其传播链路是 子级的 errorCaptured
-> 父级的 errorCaptured
-> 全局的 errorHandler
。
如果方法内部返回一个 false
则可以中断自身继续向上传播的链路。
你可以在此钩子中修改组件的状态,专门实现错误时的提示。
组件选项 - 组合
parent
手动指定当前组件实例的父实例,建立父子关系(子实例被推入父实例的 $children
数组中)。
export default Vue.extend({
name: "HelloWorld",
mounted() {
new (Vue.extend({
name: "Comp",
parent: this,
mounted() {
console.log(this.$parent);
},
render(c) {
return c("h1", ["h1"]);
},
}))().$mount("#box");
},
});
子实例可以通过 this.$parent
获取父实例,
mixins
mixins 选项接收一个混入对象的数组。这些混入对象可以像正常的组件对象一样包含实例选项,这些选项将会被合并到最终的选项中。
extends
扩展另一个组件选项对象,它与 mixins
非常类似。与 mixins
的最大区别就在于前者可以接收一个混入对象的数组,而后者只能是一个组件选项对象。
provide/inject
这对组件选项必须要一起使用。以允许一个祖先组件向其所有后代组件注入一个依赖,不论组件的层级有多深。
Vue 的
provide/inject
本身并不是响应式的,但是支持传输本身就是响应式对象的依赖。
组件选项 - 其它
name
- 为组件定义名称。
- 组件模板更好的递归调用自身。
- 结合
vue-devtools
工具可以更方便的调试。
model
值是一个 { prop?: string, event?: string }
的对象,用于自定义组件的 v-model
。
inHeritAttrs
如果父组件通过 v-bind
指令传入的 prop 没有在子组件中通过 props
选项进行预先声明,那么就会被作为普通的 HTML Attribute 绑定到子组件的根元素上。
通过设置 inheritAttrs 到 false,这些默认行为将会被去掉。
注意:这个选项不影响 class 和 style 绑定。
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: Mottle 原文链接:https://juejin.im/post/6989107179001217055