文章目录
1. $parent,$children属性
在介绍传参方式之前,我们先来看一下 $parent
,$children
属性.
我们先来看下面的代码,在里面定义了一个子组件,一个父组件,在子组件中添加了 handleClick
方法:
<div id="app">
<button @click="FatherBtn">父组件按钮</button>
<son-com></son-com>
</div>
<script>
//定义子组件
let SonCom = ({
template:`
<button @click = "handleClick">子组件按钮</button>
`,
methods:{
handleClick(){
console.log(this);
console.log(this.$parent);
}
}
})
let vm = new Vue({
el:"#app",
data:{
user:{
name:"joe"
}
},
components:{
SonCom,
},
})
</script>
在子组件中添加了一个方法打印 this
,我们来看看打印的结果:
可以看到她身上有这三个属性,还有个 $root
属性.
那么我们在子组件中打印 this.$parent
会发生什么呢??
handleClick(){
console.log(this);
console.log(this.$parent);
}
打印的结果如下:
可以看到他找到了自己的父组件,也是就是 Vue
的实例化对象.
那么我们在父组件中打印 this.$children
的结果也可以看看,在父组件中添加下面的方法:
methods:{
FatherBtn(){
console.log(this.$children);
}
}
打印的结果如下:
打印的结果是一个数组,那么我们就可以通过下标来获取到我们想要的元素.
既然我们已经了解了在父组件中找到子组件的方法,在子组件中找到父组件的方法,那么我们在子组件中执行父组件的方法岂不是会很简单.
2.利用$parent在子组件中执行父组件的方法
看下面的代码:
<div id="app">
<h2>父组件中的数据{{user}}</h2>
<button @click="FatherBtn">父组件按钮</button>
<son-com></son-com>
</div>
<script>
//定义子组件
let SonCom = ({
template:`
<button @click = "handleClick">子组件按钮</button>
`,
methods:{
handleClick(){
//在子组件中找到父组件的方法并执行
this.$parent.ChangeUser();
}
}
})
let vm = new Vue({
el:"#app",
data:{
user:{
name:"joe"
}
},
components:{
SonCom,
},
methods:{
FatherBtn(){
console.log(this.$children[0]);
},
//定义添加属性的方法
ChangeUser() {
this.user = Object.assign({},this.user,{age:19});
}
}
})
</script>
初始页面的显示结果如下图:
仔细看代码,我们在父组件中定义了一个名字叫 ChangeName
的方法来给user对象添加属性,但是我们在子组件中执行了该方法,并没有在父组件中直接执行,点击按钮之后的结果:
在上面的代码里面,添加的属性是我们直接在父组件中定义好了的,那么想想…
既然我们可以在子组件中执行父组件的方法,那么肯定也可以传参啊,就像下面这样:
在上面的代码的基础上改变:
handleClick(){
this.$parent.ChangeUser({age:19});
}
//可以在父组件中打印传过来的数据
ChangeUser(value) {
console.log(value)
this.user = Object.assign({},this.user,value);
}
代码执行后的结果如下图:
总结:子组件通过$parent获取父组件实例,进而就可以在子组件中执行父组件的方法
3.父组件中执行子组件的方法
3.1 通过 $children 属性
看下面的示例代码:
<div id="app">
<h2>父组件中的数据{{user}}</h2>
<button @click="FatherBtn">父组件按钮</button>
<son-com></son-com>
</div>
<script>
//定义子组件
let SonCom = ({
template:`
<div>
<h2>我是子组件中的数据{{msg}}</h2>
<button @click = "handleClick">子组件按钮</button>
</div>
`,
data(){
return{
msg:"hello world"
}
},
methods:{
changeMsg(value){
console.log(value);
this.msg = value
}
}
})
let vm = new Vue({
el:"#app",
data:{
user:{
name:"joe"
}
},
components:{
SonCom,
},
methods:{
FatherBtn(){
console.log(this.$children[0]);
this.$children[0].changeMsg("你好,世界!");
},
}
})
初始显示结果如下:
在父组件中定义了 FatherClick
方法,当我们点击父组件中的按钮时就会执行子组件中的方法.,结果如下:
可以看到打印的信息就是我们传递的参数 “你好,世界!” ,我们在父组件中执行了子组件的方法,并且改变了子组件的数据.
3.2 通过$ref属性来执行
我们知道:
- ref属性使用在普通DOM元素上,获取的 是原生DOM元素
- ref属性使用在组件省上,获取就是组件的实例对象
所以我们可以通过 $ref
属性来获取子组件
示例代码如下:
在上面代码的基础上,为 son-com
标签添加 ref
属性,并且在父组件中打印:
<div id="app">
<h2>父组件中的数据{{user}}</h2>
<button @click="FatherBtn">父组件按钮</button>
<son-com ref = "son"></son-com>
</div>
//父组件中的方法:
FatherBtn(){
console.log(this.$refs.son);
},
打印的结果如下,已经获取到了我们想要的子组件:
所以我们就可以在父组件中执行子组件的方法,也可以传参
在上面代码的基础上上,添加下面的代码即可:
FatherBtn(){
console.log(this.$refs.son);
this.$refs.son.changeMsg("你好,世界!")
},
执行代码后的结果:
总结
- 父组件获取子组件的实例向子组件传参, 可以通过
$children
来获取子组件实例 - 父组件获取子组件的实例向子组件传参, 也可以通过
$ref
来获取子组件实例
4. $root属性的使用
$root
属性顾名思义就是用来寻找他的根实例的.
let MinCom = ({
template:'#mincom',
methods:{
find(){
console.log(this.$parent);
console.log(this.$root)
}
}
})
let MyCom = ({
template:"#mycom",
components: {
MinCom,
}
})
let vm = new Vue({
el:"#app",
components:{
MyCom
}
})
通过上面几行简单的代码,我们来了解 $root
属性,看看它的打印结果:
观察上面的打印的两行信息,可以看到,this.$parent
打印出来的是他的父组件mycom
而 this.$root
打印得到的信息是 它的根实例vue
的石榴花对象 vm
.
所以通过这两个属性,我们就可以在 孙子组件中执行父组件和根实例中的方法,代码如下:
<div id="app">
<div>
<h2>父组件中的数据{{user}}</h2>
<button @click="FatherBtn">父组件按钮</button>
<son-com ref = "son"></son-com>
</div>
</div>
<!--定义小小组件模板-->
<template id="mincom">
<div>
<h2>{{msg}}</h2>
<button @click = "changeRoot">执行根实例中的方法</button>
<button @click = "changeFather">执行父组件中的方法</button>
</div>
</template>
<!--定义子组件模板-->
<template id="soncom">
<div>
<h2>子组件中的数据{{msg}}</h2>
<button @click = "handleClick">子组件按钮</button>
<min-com></min-com>
</div>
</template>
<script>
let MinCom = ({
template: "#mincom",
data(){
return{
msg:"小小组件的数据"
}
},
methods:{
//执行根实例中分方法
changeRoot(){
this.$root.ChangeUser({
sex:"女",
})
},
//执行父组件中的方法
changeFather(){
this.$parent.changeMsg("我们都是最棒的");
},
},
})
//定义子组件
let SonCom = ({
template:`#soncom`,
data(){
return{
msg:"hello world"
}
},
components:{
MinCom,
},
methods:{
changeMsg(value){
console.log(value);
this.msg = value
},
//执行父组件中的方法
handleClick(){
this.$parent.ChangeUser({age:19});
}
}
})
let vm = new Vue({
el:"#app",
data:{
user:{
name:"joe"
}
},
components:{
SonCom,
},
methods:{
FatherBtn(){
// console.log(this.$refs.son);
// this.$refs.son.changeMsg("你好,世界!")
// console.log(this.$children[0]);
// this.$children[0].changeMsg("你好,世界!");
},
ChangeUser(value) {
console.log(value)
this.user = Object.assign({},this.user,value);
}
}
})
</script>
点击按钮之前的结果如下图:
点击按钮之后的结果如下图:
所以我们也可以在孙子组件中执行到父组件和根实例中的方法,使用的属性就是 $parent
和 $root
.