最简单的声明组件
import Vue from 'vue'
new Vue({
el: '#root',
template: '<div>123</div>'
})
全局注册组件
官方推荐,定义组件名,大写开头以及驼峰式命名,在模板中使用时,使用小写连接符的方式。
const component = {
template: '<div>This is component</div>'
}
Vue.component('CompOne', component)
new Vue({
el: '#root',
template: '<comp-one></comp-one>'
})
局部注册组件
通过组件 options 中的 components 选项来做。
const component = {
template: '<div>This is component</div>'
}
new Vue({
components: {
CompOne: component
},
el: '#root',
template: '<comp-one></comp-one>'
})
定义组件时,使用 data
定义组件时,使用 data 定义组件内数据时(不是 new Vue() 这种情况),data 需要改成 function,并返回一个单独的对象,不要使用全局的对象来做。
const component = {
template: '<div>{{text}}</div>',
data () {
return {
text: 123
}
}
}
new Vue({
components: {
CompOne: component
},
el: '#root',
template: '<comp-one></comp-one>'
})
如果不是单独的对象,组件复用时,数据会共用。如下例中,text 数据是共用的。
const data = {
text: 0
}
const component = {
template: `
<div>
<input type="text" v-model="text"/>
</div>
`,
data () {
return data
}
}
new Vue({
components: {
CompOne: component
},
el: '#root',
template: `
<div>
<comp-one></comp-one>
<comp-one></comp-one>
</div>
`
})
定义组件时,使用 props
props 定义组件在外部使用时一些可配置的行为。
props 类型检查
指定传入数据类型。
如果不使用绑定模式,直接使用 active="true",传入组件的就是字符串,vue 会发出警告。
const component = {
props: {
active: Boolean
},
template: `
<div>
<input type="text" v-model="text"/>
<span v-show="active">see me if active</span>
</div>
`,
data () {
return {
text: 0
}
}
}
new Vue({
components: {
CompOne: component
},
el: '#root',
template: `
<div>
<comp-one :active="true"></comp-one>
<comp-one :active="false"></comp-one>
</div>
`
})
props 命名
命名时使用驼峰式命名
在模板中使用时,使用小写连接符的方式(在模板中也可以使用驼峰式写法,与团队成员协商)。
const component = {
props: {
propOne: String
},
template: `
<div>
<span>{{propOne}}</span>
</div>
`
}
new Vue({
components: {
CompOne: component
},
el: '#root',
template: `
<div>
<comp-one prop-one="text1"></comp-one>
<comp-one propOne="text2"></comp-one>
</div>
`
})
不要子组件中改 props
直接改 props 能够修改成功,但是 vue 会警告,在组件内部主动改 props 是不正确的,props 是外部组件用来约束子组件展示行为的,所以有违初衷约束。
const component = {
props: {
propOne: String
},
template: `
<div>
<span>{{propOne}}</span>
</div>
`,
mounted () {
this.propOne = 'inner content'
}
}
new Vue({
components: {
CompOne: component
},
el: '#root',
template: `
<div>
<comp-one prop-one="text1"></comp-one>
<comp-one propOne="text2"></comp-one>
</div>
`
})
修改 props
子组件触发事件,通知父组件来改 props。
通过 props 传方法
如下,点击 text1 多一个 1
const component = {
props: {
propOne: String,
onChange: Function
},
template: `
<div>
<span @click="handleChange">{{propOne}}</span>
</div>
`,
data () {
return {
text: 0
}
},
methods: {
handleChange () {
this.onChange()
}
}
}
new Vue({
components: {
CompOne: component
},
el: '#root',
data: {
prop1: 'text1'
},
methods: {
handleChange () {
this.prop1 += 1
}
},
template: `
<div>
<comp-one :active="true" :prop-one="prop1" :on-change="handleChange"></comp-one>
</div>
`
})
通过 $emit
通过 $emit
通知父组件的方式,比较常用。
const component = {
props: {
propOne: String
},
template: `
<div>
<span @click="handleChange">{{propOne}}</span>
</div>
`,
data () {
return {
text: 0
}
},
methods: {
handleChange () {
this.$emit('change')
}
}
}
new Vue({
components: {
CompOne: component
},
el: '#root',
data: {
prop1: 'text1'
},
methods: {
handleChange () {
this.prop1 += 1
}
},
mounted () {
console.log(this.$refs.comp1)
},
template: `
<div>
<comp-one ref="comp1" :active="true" :prop-one="prop1" @change="handleChange"></comp-one>
</div>
`
})
props 的数据验证
不验证
这样简单,但不严谨
props: ['active', 'propOne']
验证数据类型
props: {
active: {
type: Boolean
},
propOne: String // 简洁写法
},
required
设置 required: true
,则 active 必须要传,否则 vue 警告。
props: {
active: {
type: Boolean,
require: true
}
},
default
default 默认是 false,如果设置为 true,当我们没有传 active 时,它会设置 active 为 true。
default 和 requied 不会同时使用,因为效果冲突。
props: {
active: {
type: Boolean,
default: true
},
propOne: String
},
如果 props 接收的是一个对象,使用 default 时,需要改成 function,返回单独的对象。
props: {
obj: {
type: obj
dafault () {
return {}
}
}
},
validator
通过 validator,可以自定义的对 props 进行验证。
下例,vue 对 active 的数据类型也会进行验证。
props: {
active: {
validator (value) {
return typeof value === 'boolean'
}
}
},
总结
组件定义方法、规范,命名规范,props 规范