之前我们介绍了父传子使用props属性,子传父使用$emit发射自定义函数实现父子组件通信。那么我们有什么方法可以直接在父组件操作子组件的数据或函数、子组件操作父组件的数据或函数吗?下面就通过 $children 、$refs、$parent实现。
有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件。
this.$children是一个数组类型,它包含所有子组件对象。
实例:在父组件通过this.$children来获取子组件定义的图片的imgSrc地址:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue_learntitle>
<style>style>
head>
<body>
<template id="component">
<div>
<img :src="imgSrc" />
div>
template>
<div class="container" @click="getChild">
<my-component>my-component>
div>
<script src="./vue.js">script>
<script>
// vue实例1
var app1 = new Vue({
el: ".container",
methods: {
getChild: function () {
console.log("子组件数据:", this.$children[0].imgSrc);
},
},
components: {
// 在vue实例注册组件,形成父子关系,局部组件
"my-component": {
template: "#component",
data: function () {
return {
imgSrc:
"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=272736508,2842806735&fm=26&gp=0.jpg",
};
},
},
},
});
script>
body>
html>
代码解释:
实例2:vue实例有多个子组件
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue_learntitle>
<style>style>
head>
<body>
<template id="component">
<div>
<img :src="imgSrc" />
div>
template>
<div class="container" @click="getChild">
<my-component>my-component>
<my-component>my-component>
<my-component>my-component>
div>
<script src="./vue.js">script>
<script>
// vue实例1
var app1 = new Vue({
el: ".container",
methods: {
getChild: function () {
console.log("所有子组件:", this.$children);
},
},
components: {
// 在vue实例注册组件,形成父子关系,局部组件
"my-component": {
template: "#component",
data: function () {
return {
imgSrc:
"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=272736508,2842806735&fm=26&gp=0.jpg",
};
},
},
},
});
script>
body>
html>
上面代码与实例1不同之处是在vue实例中添加了3个子组件(子组件可不相同)。我们打印了this.$children,证实这的确是一个数组。
$children的缺点:
this.$refs是一个对象类型,它包含所有子组件对象。
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue_learntitle>
<style>style>
head>
<body>
<template id="component">
<div>
<img :src="imgSrc" />
div>
template>
<div class="container" @click="getChild">
<my-component>my-component>
<my-component ref="second">my-component>
<my-component>my-component>
div>
<script src="./vue.js">script>
<script>
// vue实例1
var app1 = new Vue({
el: ".container",
methods: {
getChild: function () {
console.log("具体某个子组件:", this.$refs.second);
this.$refs.second.getData(); //父组件直接调用子组件方法
},
},
components: {
// 在vue实例注册组件,形成父子关系,局部组件
"my-component": {
template: "#component",
data: function () {
return {
imgSrc:
"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=272736508,2842806735&fm=26&gp=0.jpg",
};
},
methods: {
getData() {
console.log("这是子组件的方法");
},
},
},
},
});
script>
body>
html>
this.$refs.second.getData()
在子组件通过$parent访问父组件,这也是一个对象类型。
实例:子组件获取父组件数据
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue_learntitle>
<style>style>
head>
<body>
<template id="component">
<div @click="getParent">
<img :src="imgSrc" />
div>
template>
<div class="container">
<my-component>my-component>
div>
<script src="./vue.js">script>
<script>
// vue实例1
var app1 = new Vue({
el: ".container",
data: {
parentData: "我是来自父组件的数据,哈哈啊哈哈哈哈哈",
},
components: {
// 在vue实例注册组件,形成父子关系,局部组件
"my-component": {
template: "#component",
data: function () {
return {
imgSrc:
"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=272736508,2842806735&fm=26&gp=0.jpg",
};
},
methods: {
getParent() {
console.log("来自父组件的数据:", this.$parent.parentData);
},
},
},
},
});
script>
body>
html>