组件基础
- 全局注册组件
// 注册组件
Vue.component('cpt-name', {})
// 使用
<cpt-name></cpt-name>
- 局部组件
// 注册局部组件
const cpt = {}
// 在实例中定义局部组件
new Vue({
components: {
cpt-name: cpt
}
})
// 使用
<cpt-name></cpt-name>
组件命名
-
大驼峰命名的组件
IButton
;
在html 中,只能通过烤串方式使用i-button
;
在template中,可以通过 大驼峰IButton
/ 小驼峰iButton
/ 烤串i-button
方式使用; -
小驼峰命名的组件
iButton
;
在html 中,只能通过烤串方式使用i-button
;
在template中,可以通过 小驼峰iButton
/ 烤串i-button
方式使用; -
烤串方式命名的组件
i-button
;
在html 和 template中都只能通过烤串命名方式使用i-button
;
所以,由上得出,给组件命名的时候,优先使用大驼峰命名;
但是,我个人感觉使用烤串命名会好一点,三方(组件名,html中使用时,template中使用时)保持一致,不容易混淆;
Prop
Prop的类型
- 字符串数组
Vue.component('my-component', {
props: ['name', 'title', 'age']
})
- 对象形式
Vue.component('my-component', {
props: {
name: String,
age: Number
}
})
Prop 验证
Vue.component('my-component', {
props: {
// 基础的类型检查('null' 和 'undefined' 会通过任何类型验证)
p1: String,
// 多个可能的类型
p2: [String, Number, Boolean],
// 必填项
p3: {
type: String,
required: true
},
// 默认值
p4: {
type: String,
default: '宫鑫'
},
}
})
一般常用的就是如上四种,Prop还可以自定义验证函数,这个想要详细了解可以看手册;
类型检查时,type
值可以是下列原生构造函数的一个
String
Number
Boolean
Array
Object
Function
Date
Symbol
Prop 单向数据流
父级prop的更新会向下流动到子组件中,但是反过来则不行;每次父级组件发生更新时,子组件中所有的prop都将刷新为最新的值。这意味着你不应该在一个子组件中改变prop。
如果在子组件中改变prop的值,可以使用如下两种办法
- 在子组件中将prop通过
data
转成本地数据来使用
Vue.component('my-component', {
props: {
name: String
},
data() {
return {
iName: this.name
}
},
})
- 如果传入的这个值需要转换,可以使用计算属性
props: ['name'],
computed: {
iName() {
return this.name + '你好';
}
}
注意:在javascript 中,对象和数组是通过引入传入的,所以如果将一个对象或数组通过prop传入子组件,在子组件中改变这个对象或数组本身将影响到父组件的状态;
Vue.component('test', {
props: ['obj'],
methods: {
change(){
this.obj.name = "路漫漫其修远其"
}
},
template: `
<div>
<p>子组件: {{obj.name}}</p>
<a href="javascript:;" @click="change">change</a>
</div>
`
})
new Vue({
el: "#app",
data: {
obj: { name: "任重道远" }
},
template: `
<div>
<p>{{obj.name}}</p>
<test :obj="obj"></test>
</div>
`
})
// 如上所示,在实例中定义了一个 obj 对象,传入到了子组件中,在子组件中修改了这个对象,
// 但是实例中(父组件)中的 obj 也发生了变化;
//(其实如果不是对象也会修改,不过会报错;就算将对象通过data转成了本地数据,照样会影响到父级)
// 所以,传参数时,尽量避免传递对象(只是尽量)
// 但是如果我需要传递对象,又不想子组件的修改影响到父组件该怎么办呢?
// 通过深拷贝,将prop传递过来的对象彻底转换成本地数据
props: ['obj'],
data(){
return {
iObj: JSON.parse(JSON.stringify(this.obj))
}
}
自定义事件
我们可以通过
Prop
实现父组件向子组件传递数据,但是,子组件不能直接修改父组件的数据,那如果子组件修改数据后想要在父组件上体现出来,该怎么处理呢?就通过自定义事件处理;
// 方法中
this.$emit('myEvent', 参数)
// 行间
<div @click="$emit('myEvent', 参数)"></div>
// 监听
<my-component
v-on:myEvent='change'
>
</my-component>
methods: {
change(str) {
// str -> 参数
}
}