一、选项/数据
1. data
- 类型:
Object | Function
- 组件的定义只接受
Function
- 因为组件可能被用来创建多个实例。如果
data
仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!而通过data
函数,每次创建一个新实例后,我们能够调用data
函数,从而返回初始数据的一个全新副本数据对象。
- 因为组件可能被用来创建多个实例。如果
-
data
属性使用箭头函数,则this
不会指向这个组件的实例- 如果你为data属性使用了箭头函数,则this不会指向这个组件的实例,不过仍然可以将其实例作为函数的第一个参数来访问
data:vm=>({a:vm.myProp})复制代码
2. props
- 如果你为data属性使用了箭头函数,则this不会指向这个组件的实例,不过仍然可以将其实例作为函数的第一个参数来访问
- 类型:
Array<string> | Object
用于接收来自父组件的数据。 - 使用对象
object
有以下选项:- type:
String
、Number
、Boolean
、Array
、Object
、Date
、Function
、Symbol
、自定义构造函数 - default:默认值,对象或数组的默认值必须从一个工厂函数返回
- required:
Boolean
,定义是否是必填项 - validator:
Function
,自定义验证函数
- type:
// 对象语法,提供验证
Vue.component('props-demo-advanced', {
props: {
// 检测类型
height: Number,
// 检测类型 + 其他验证
age: {
type: Number,
default: 0,
required: true,
validator: function (value) {
return value >= 0
}
}
}
})复制代码
- Prop的大小写,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})复制代码
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>复制代码
- 单项数据流
- 父级prop的更新会向下流动到子组件中,但是反过来不行。所以就意味着不能在子组件内改变prop
- 使用计算属性对prop原始值进行转换
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}复制代码
3. computed
- 类型:
{[key : string] : Function | {get : Function,set : Function}}复制代码
- 计算属性缓存 VS 方法
computed:{
reverseName:function(){
return this.name.split('.').reverse().join('.')
}
}复制代码
methods:{
reverseName(){
return this.name.split('.').reverse().join('.')
}
}复制代码
以上两种方式调用都可以达到同样效果,不同的是计算属性computed是基于他们的响应式依赖name
进行缓存的。name
还没有改变,多次访问reverseName
计算属性会从缓存中返回之前的计算结果。而调用方法将总会再次执行函数。
- 计算属性 VS 侦听属性
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
}
}复制代码
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}复制代码
不能滥用watch
,通常更好做法是使用计算属性而不是命令式的watch
回调
4. method
- 类型:{ [ key:string ] : Function }
- 不应该使用箭头函数来定义method函数,箭头函数绑定了父级作用域的上下文
5.watch
- 类型:{ [key:string] : string | Function | Object | Array }
- 主要用于观测某个值的变化去完成一段开销较大的复杂业务逻辑
二、选项/DOM
1. el
- 类型:
string | Element
- 可以是css选择器,也可以是HTMLElement实例
- 实例挂载之后,可以
用vm.$el
来访问- 如果实例化时存在这个选项,实例将立即进入编译过程,否则需要显示调用vm.$mount()手动开启编译。
var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})
// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')
// 或者
new MyComponent().$mount(document.querySelector('#app'))复制代码
2. template
- 类型:
string
- 模板将会替换挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发插槽
slot
<alert-box>
Something bad happened.
</alert-box>复制代码
Vue.component('alert-box', {
template: `
<div class="demo-alert-box">
<strong>Error!</strong>
<slot></slot>
</div>
`
})复制代码
3. render
- 类型:
(createElement:() => VNode)=>VNode
三、选项/生命周期钩子
1. beforeCreate
- 类型:Function
- 实例初始化之后,数据观测(data observer)和event/watcher事件配置之前被调用。
2. created
- 类型:Function
- 这一步,实例完成以下配置:数据观测(data observer),属性和方法运算,watch/event事件回调。然而,挂载阶段还没开始,$el属性目前不可见
3. beforeMount
- 类型:Function
- 相关的
render
函数首次被调用
4. mounted
- 类型:Function
- el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。
- 注意
mounted
不会承诺所有的子组件也都一起被挂载。如果希望等到整个视图都渲染完毕,可以用vm.$nextTick替换掉mounted
5. beforeUpdate
- 类型:Function
- 数据更新时调用,发生在虚拟DOM打补丁之前。
6. updated
- 类型:Function
- 当这个钩子被调用时,组件DOM已经更新,所以可以执行依赖于DOM操作。
- updated不会承诺所有子组件也都一起被重绘,如果希望等到整个视图都重绘完毕,可以用
vm.$nextTick
替换掉updated
:
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}复制代码
7. actived
- 类型:Function