我們得弄清楚一個(gè)是父子組件的通訊型奥,另一個(gè)是父子組件的訪問,兩個(gè)概念不能混淆碉京。
有時(shí)候我們需要父組件直接訪問子組件定義的某個(gè)方法或?qū)傩韵嵝冢咏M件也有時(shí)候出現(xiàn)要直接訪問父組件,或者是子組件訪問根組件的情況谐宙。
父組件訪問子組件:
1.使用$children
2.使用$refs (中文翻譯是引用的意思烫葬,是references的縮寫)
子組件訪問父組件
使用$parent
使用$root
關(guān)于父組件使用$children去訪問子組件
this.$children是一個(gè)數(shù)組類型,它包含所有子組件對(duì)象凡蜻,
這句話是說搭综,父組件下面有n個(gè)子組件,
父組件下面放了很多個(gè)子組件划栓。
(我們一般通過遍歷取出所有子組件的狀態(tài))
父組件通過this.$children訪問單個(gè)子組件里面的showMessage方法.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- Vue根實(shí)例模板(父組件) -->
<div id="app">
<!-- 調(diào)用已經(jīng)注冊(cè)的子組件 -->
<div>
<mycom></mycom>
<button @click="btnClick">button</button>
</div>
</div>
<!-- 子組件模板 -->
<template id="com">
<div>
<p>我是子組件</p>
</div>
</template>
<script>
//將Vue實(shí)例作為父組件
const app = new Vue({
el: '#app',
data() {
return {
message: 'hello '
}
},
methods: {
btnClick () {
console.log(this.$children)
//this.$children[0].showMessage
console.log(this.$children[0].showMessage)
}
},
//子組件
components: {
mycom: {
template: '#com',
methods: {
showMessage () {
console.log('showMessage');
}
},
}
}
})
</script>
</body>
</html>
多個(gè)子組件的場(chǎng)景兑巾,調(diào)用多次子組件測(cè)試。
我們可以看到有了4個(gè)同名的子組件忠荞。
上面我們通過根組件使用this.$children訪問子組件里面定義的showMessage方法蒋歌,已經(jīng)測(cè)試過,是可以成功的委煤。
下面我們?cè)谧咏M件里面定義一個(gè)屬性name
因?yàn)槲覀冇?個(gè)同名的子組件
Vue實(shí)例的根組件想訪問子組件下面定義的name屬性堂油,我們需要用到遍歷。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- Vue根實(shí)例模板(父組件) -->
<div id="app">
<!-- 調(diào)用已經(jīng)注冊(cè)的子組件 -->
<div>
<mycom></mycom>
<mycom></mycom>
<mycom></mycom>
<mycom></mycom>
<button @click="btnClick">button</button>
</div>
</div>
<!-- 子組件模板 -->
<template id="com">
<div>
<p>我是子組件</p>
</div>
</template>
<script>
//將Vue實(shí)例作為父組件
const app = new Vue({
el: '#app',
data() {
return {
message: 'hello '
}
},
methods: {
btnClick () {
console.log(this.$children);
for (let c of this.$children) {
console.log(c.name);
c.showMessage();
}
}
},
//子組件
components: {
mycom: {
template: '#com',
data() {
return {
name: '我是組件的name'
}
},
methods: {
showMessage () {
console.log('showMessage');
}
},
}
}
})
</script>
</body>
</html>
但實(shí)際開發(fā)中碧绞,根組件下面擁有很多子組件,
我們一般不會(huì)使用$children府框,去訪問子組件的屬性或方法的,
子組件過多時(shí)讥邻,我們不推薦使用$children
因?yàn)橐褂?children[索引]去找到對(duì)應(yīng)的組件迫靖,修改起來非常的不利索。
比如我們某天又多了一個(gè)需求计维,多了幾個(gè)組件插進(jìn)來袜香,而我們本身想獲取索引是3的組件,現(xiàn)在挪了位置到第5位去了鲫惶,我們又得手動(dòng)去修改method蜈首。
所以遇到這種場(chǎng)景,我們是通過另外一個(gè)父組件訪問子組件的方式,$refs,它的作用類似給每個(gè)子組件終身綁定一個(gè)唯一的識(shí)別身份key欢策,一一對(duì)應(yīng)吆寨。
當(dāng)子組件沒有綁定ref的時(shí)候,控制臺(tái)輸出的$refs是一個(gè)默認(rèn)的空對(duì)象踩寇。
上面的代碼再修改成這樣啄清,就能訪問到<mycom ref="reference"></mycom>子組件的name屬性了
完整代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- Vue根實(shí)例模板(父組件) -->
<div id="app">
<!-- 調(diào)用已經(jīng)注冊(cè)的子組件 -->
<div>
<mycom></mycom>
<mycom></mycom>
<mycom ref="reference"></mycom>
<mycom></mycom>
<button @click="btnClick">button</button>
</div>
</div>
<!-- 子組件模板 -->
<template id="com">
<div>
<p>我是子組件</p>
</div>
</template>
<script>
//將Vue實(shí)例作為父組件
const app = new Vue({
el: '#app',
data() {
return {
message: 'hello '
}
},
methods: {
btnClick () {
console.log(this.$refs.reference.name);
}
},
//子組件
components: {
mycom: {
template: '#com',
data() {
return {
name: '我是組件的name'
}
},
methods: {
showMessage () {
console.log('showMessage');
}
},
}
}
})
</script>
</body>
</html>
子組件訪問父組件
1.使用$parent
2.使用$root
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- Vue根實(shí)例模板(父組件) -->
<div id="app">
<!-- 調(diào)用已經(jīng)注冊(cè)的子組件 -->
<div>
<mycom></mycom>
</div>
</div>
<!-- 子組件模板 -->
<template id="com">
<div>
<p>我是子組件</p>
<button @click="btnClick">button</button>
</div>
</template>
<script>
//將Vue實(shí)例作為父組件
const app = new Vue({
el: '#app',
data() {
return {
}
},
//子組件
components: {
mycom: {
template: '#com',
data() {
return {
}
},
methods: {
btnClick () {
//1.訪問父組件$parent
console.log(this.$parent)
}
},
}
}
})
</script>
</body>
</html>
當(dāng)$parent遇上組件層層嵌套的層級(jí)關(guān)系的情形。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- Vue根實(shí)例模板(父組件) -->
<div id="app">
<!-- 調(diào)用已經(jīng)注冊(cè)的子組件 -->
<div>
<mycom></mycom>
</div>
</div>
<!-- 子組件模板 -->
<template id="com">
<div>
<p>我是組件mycom</p>
<mycom2></mycom2>
</div>
</template>
<template id="mycom2">
<div>
<p>我是子組件mycom2</p>
<button @click="btnClick">button</button>
</div>
</template>
<script>
//將Vue實(shí)例作為父組件
const app = new Vue({
el: '#app',
data() {
return {
}
},
//子組件
components: {
mycom: {
template: '#com',
data() {
return {
name:'我是組件mycom的name'
}
},
components: {
mycom2: {
template: '#mycom2',
methods: {
btnClick() {
//1.訪問父組件$parent
console.log(this.$parent.name)
}
}
}
}
}
}
})
</script>
</body>
</html>
使用$parent,父組件和子組件的耦合度太高俺孙,組件復(fù)用性的太低且太亂辣卒,用的少。
$root打印