組件基礎
- 全局註冊組件
// 註冊組件
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 -> 參數
}
}