一 子傳父(對(duì)$emit的理解)
作用
子組件可以使用 $emit 觸發(fā)父組件的自定義事件。
語法
vm.$emit( event, arg ) //觸發(fā)父級(jí)實(shí)例上的事件
對(duì)于vue.js中的this.emit的理解:
舉例 : this.emit(‘increment1’,”加參數(shù)”);
其實(shí)它的作用就是觸發(fā)自定義函數(shù)。此外,可以子組件傳參數(shù)給父組件
綜述,即子組件調(diào)用父組件的方法并傳遞數(shù)據(jù)
具體應(yīng)用如下
子組件
<template>
<button @click="emitEvent">點(diǎn)擊我</button>
</template>
<script>
export default {
data() {
return {
msg: "我是子組件中的數(shù)據(jù)"
}
},
methods: {
emitEvent(){
this.$emit('my-event', this.msg)
//通過按鈕的點(diǎn)擊事件觸發(fā)方法,然后用$emit觸發(fā)一個(gè)my-event的自定義方法,傳遞this.msg數(shù)據(jù)。
}
}
}
</script>
父組件
<template>
<div id="app">
<child-a @my-event="getMyEvent"></child-a>
<!--父組件中通過監(jiān)測my-event事件執(zhí)行一個(gè)方法,然后取到子組件中傳遞過來的值-->
</div>
</template>
<script>
import ChildA from './components/child.vue'
export default {
components: {
ChildA
},
methods: {
getMyEvent(msg){ // msg是個(gè)形參value,實(shí)質(zhì)是接收的子組件傳來數(shù)據(jù)的參數(shù)
console.log('接收的數(shù)據(jù)--------->'+msg)//接收的數(shù)據(jù)--------->我是子組件中的數(shù)據(jù)
}
}
}
</script>
二 父傳子
父組件可以使用 props 把數(shù)據(jù)傳給子組件。
子組件通過props拿到父組件傳來的數(shù)據(jù)。
父組件
<template>
<div id="app">
<div class="transac-del">
<div>
<span class="sub_title">交易詳情</span>
</div>
<p>
// v-if的原因是調(diào)接口回來數(shù)據(jù)是個(gè)異步操作,因此給個(gè)條件判斷,數(shù)據(jù)不為null的時(shí)候才傳數(shù)據(jù)給子組件,以免數(shù)據(jù)一開始拿到的是空對(duì)象
<transacDet v-if="deiMap" :DeiMap = 'deiMap' /> // 子組件,并且在數(shù)據(jù)模型中定義deiMap:null
</p>
</div>
</div>
</template>
子組件
props: {
DeiMap:{
type:Object,
required: true
}
},
mounted () {
// 子組件通過props拿到父組件傳來的數(shù)據(jù),是個(gè)對(duì)象,直接this.DeiMap可以使用數(shù)據(jù)
console.log('obj==',this.DeiMap)
},
prop的單向數(shù)據(jù)流
vue官方:
所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級(jí) prop 的更新會(huì)向下流動(dòng)到子組件中,但是反過來則不行。這樣會(huì)防止從子組件意外變更父級(jí)組件的狀態(tài),從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。
額外的,每次父級(jí)組件發(fā)生變更時(shí),子組件中所有的 prop 都將會(huì)刷新為最新的值。這意味著你不應(yīng)該在一個(gè)子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會(huì)在瀏覽器的控制臺(tái)中發(fā)出警告。
如下

image.png
可以這樣理解
父傳子 prop是單向數(shù)據(jù)流
如果在子組件中已經(jīng)接受了值,這時(shí)在子組件內(nèi)直接再次改變這個(gè)值,會(huì)出現(xiàn)問題,vue不允許這樣操作,vue規(guī)定了props是單向數(shù)據(jù)流傳值
解決方法
在data中定義一個(gè)第三方的變量接收數(shù)據(jù)(即克隆數(shù)據(jù)),這個(gè)第三方變量即可更改
同時(shí),在mounted階段賦值給這個(gè)變量
三 $refs的使用
$refs作用1 => 在DOM元素上使用$refs可以迅速進(jìn)行dom定位
$refs作用2 => 在組件上使用ref屬性,可以通過$refs實(shí)現(xiàn)對(duì)子組件操作
即$refs是父組件調(diào)用子組件的方法,可以傳遞數(shù)據(jù)
首先給子組件做標(biāo)記。demo :<firstchild ref="one"></firstchild>
然后在父組件中,通過this.$refs.one就可以訪問了這個(gè)自組件了,包括訪問自組件的data里面的數(shù)據(jù),調(diào)用它的函數(shù)
注意1
ref 被用來給元素或子組件注冊(cè)引用信息。引用信息將會(huì)注冊(cè)在父組件的 $refs 對(duì)象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素; 如果用在子組件上,引用就指向組件實(shí)例
當(dāng) v-for 用于元素或組件的時(shí)候,引用信息將是包含 DOM 節(jié)點(diǎn)或組件實(shí)例的數(shù)組
注意2
$refs不能在created生命周期中使用 因?yàn)樵诮M件創(chuàng)建時(shí)候 該ref還沒有綁定元素
它是非響應(yīng)的,所以應(yīng)該避免在模板或計(jì)算屬性中使用 $refs ,它僅僅是一個(gè)直接操作子組件的應(yīng)急方案
當(dāng)使用v-for的元素或組件,引用信息$refs將是包含DOM節(jié)點(diǎn)的或組件實(shí)例的數(shù)組,類似$children的使用
父組件
<template>
<div id="app">
<child-a ref="child"></child-a>
<!--用ref給子組件起個(gè)名字-->
<button @click="getMyEvent">點(diǎn)擊父組件</button>
</div>
</template>
<script>
import ChildA from './components/child.vue'
export default {
components: {
ChildA
},
data() {
return {
msg: "我是父組件中的數(shù)據(jù)"
}
},
methods: {
getMyEvent(){
this.$refs.child.emitEvent(this.msg);
//調(diào)用子組件的方法,child是上邊ref起的名字,emitEvent是子組件的方法。
}
}
}
</script>
子組件
<template>
<button>點(diǎn)擊我</button>
</template>
<script>
export default {
methods: {
emitEvent(msg){
console.log('接收的數(shù)據(jù)--------->'+msg)//接收的數(shù)據(jù)--------->我是父組件中的數(shù)據(jù)
}
}
}
</script>
四 $on的使用
待補(bǔ)充
五 $parent
vue 里 this.$parent 作用
$parent在子組件中調(diào)用父組件的方法或獲得其數(shù)據(jù)
this.$parent 可以訪問到父組件上所有的 data(){ 里的數(shù)據(jù)信息和生命周期方法,methods里的方法 }
如 this.$parent.List = []; 表示訪問到父組件中data的數(shù)據(jù)list數(shù)組
區(qū)分
1、ref為子組件指定一個(gè)索引名稱,通過索引來操作子組件;
2、this.$parent 可以直接訪問該組件的父實(shí)例或組件;
3、父組件也可以通過this.$children 訪問它所有的子組件,
$parent和$children 可以遞歸向上或向下無線訪問, 直到根實(shí)例或最內(nèi)層的組件。
六 $children
他返回的是一個(gè)組件集合,如果你能清楚的知道子組件的順序,你也可以使用下標(biāo)來操作;
for(let i=0;i<this.$children.length;i++){
console.log(this.$children[i].children_data);
this.$children[i].children_fun();
}
七
children的案例
父組件index.vue
<template>
<div>
<testVue ref="childVue"></testVue> <br/><br/>
<testVue2></testVue2> <br/><br/>
<button @click="clickChild1">點(diǎn)擊訪問子組件</button> <br/><br/>
<button @click="clickChild2">點(diǎn)擊訪問子組件2</button>
</div>
</template>
<script>
import testVue from './testVue'
import testVue2 from './testVue2'
export default {
data(){
return {
total: 0
}
},
methods: {
clickChild1(){
console.log(this.$refs.childVue.counter);
},
clickChild2(){
console.log(this.$children[1].testval);
}
},
components: {
testVue,
testVue2
}
}
</script>
子組件1
<template>
<div>
<button @click="parentClick">點(diǎn)擊訪問父組件</button>
</div>
</template>
<script>
export default {
data(){
return {
counter: 0
}
},
methods: {
parentClick(){
console.log(this.$parent.total);
}
}
}
</script>
子組件2
<template>
<div>
</div>
</template>
<script>
export default {
data(){
return {
testval: '2222'
}
}
}
</script>