【Vue学习总结】15.父子组件主动获取数据和方法、非父子组件获取数据和方法

接上篇《14.Vue父子组件数据传递

上一篇我们主要讲解了Vue中父组件如何将值、方法、实例传给子组件,本篇我们来讲解非父子组件如何进行数据和方法的传递。
本系列博文使用的Vue版本:2.6.11

在讲非父子组件如何进行数据和方法的传递之前,我们先来补充一下上一篇的一个点,就是父子组件之间如何进行主动的获取数据和方法,而不是传递给对方。

一、父子组件主动获取数据和方法

这里的样例还是在之前的工程上进行的演示。

1、父组件主动获取子组件的数据和方法

假设我们在HelloWorld.vue页面想要主动调取Header.vue子组件的数据和方法,我们只需要进行两步:
(1)调用子组件时定义一个ref
<v-header ref="header"></v-header>
这里的ref中的参数,其实就是主动获取了Header.vue子组件的一个实例对象。
(2)在父组件中通过“this.$refs.实例名.属性、方法名”的方式来调用子组件的数据或方法
例如:
this.$refs.header.属性;
this.$refs.header.方法;测试:
在HelloWorld.vue页面调用子组件时定义ref,然后编写一个按钮,测试是否能通过引用实例获取到子组件的数据和方法:

<template>
  <!-- 所有的内容要被根节点包含起来 -->
  <div class="hello">
    <v-header ref="header"></v-header>
    <h1>{{ msg }}</h1>
    <button @click="getChildData()">获取子组件的数据和方法</button>
  </div>
</template>

<script>
import Header from './Header.vue';
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: '首页父组件'
    }
  },
  methods:{
    getChildData(){
      console.log(this.$refs.header.msg);//获取子组件的值
      this.$refs.header.headRun();//调用子组件的方法
    }
  },
  components:{
    'v-header':Header
  }
}
</script>

<!-- 添加 "scoped" 属性来限制里面css样式只能被该组件引用 -->
<style scoped>
  h1{
    color:red;
  }
</style>

子组件中定义其msg以及headRun方法:

<template>
  <!-- 所有的内容要被根节点包含起来 -->
  <div class="header">
    <h1>{{ msg }}</h1>
    <button @click="headRun()">执行自己的方法</button>
  </div>
</template>

<script>
export default {
  name: 'header',
  data () {
    return {
      msg: '头部组件'
    }
  },
  methods:{
    headRun(){
      alert("子组件的方法");
    }
  }
}
</script>

<!-- 添加 "scoped" 属性来限制里面css样式只能被该组件引用 -->
<style scoped>
  .header{
    background-color: #000;
  }
  h1{
    color:#fff;
  }
</style>

测试结果:

证明可以通过“this.$refs”获取到子组件的数据和方法。

2、子组件中主动获取父组件的数据和方法

子组件被父组件引用后,可以直接通过“this.$parent.属性、方法名”的方式来调用父组件的数据或方法
例如:
this.$parent.属性;
this.$parent.方法;测试:
在Header.vue子组件中编写一个按钮,来通过上述方式主动获取父组件的属性和方法:

<template>
  <!-- 所有的内容要被根节点包含起来 -->
  <div class="header">
    <h1>{{ msg }}</h1>
    <button @click="headRun()">执行自己的方法</button>
    <button @click="getParentData()">获取父组件的数据和方法</button>
  </div>
</template>

<script>
export default {
  name: 'header',
  data () {
    return {
      msg: '头部组件'
    }
  },
  methods:{
    headRun(){
      alert("子组件的方法");
    },
    getParentData(){
      console.log(this.$parent.msg);
      this.$parent.run();
    }
  }
}
</script>

<!-- 添加 "scoped" 属性来限制里面css样式只能被该组件引用 -->
<style scoped>
  .header{
    background-color: #000;
  }
  h1{
    color:#fff;
  }
</style>

然后在父组件HelloWorld.vue中添加一个自己的run方法:

methods:{
  getChildData(){
    console.log(this.$refs.header.msg);//获取子组件的值
    this.$refs.header.headRun();//调用子组件的方法
  },
  run(){
    alert("这里是父组件的方法");
  }
},

效果:

证明子组件可以通过“this.$parent”获取到父组件的数据和方法。

二、非父子组件获取数据和方法

讲完了父子组件之间主动、非主动的获取和传递数据和方法的方式后,我们来了解一下非父子组件(兄弟组件)之间如何获取数据和方法。

我们观察一下,之前我们写的工程中,组件结构如下:

其中首页组件和新闻组件就不是非父子组件,是兄弟组件。兄弟组件之间的传值有两种方式:

1、通过上级组件来进行传值

兄弟组件一定是有相同的祖先的,只要找到两方都有关系的父组件,便可通过父组件来获取兄弟组件的数据。

例如首页组件需要获取新闻组件的msg,可以先获取父亲组件的实例,通过父亲组件的实例获取父亲引用的新闻组件的实例,进而获取到新文组件的msg:

this.$parent.$refs.news.msg

使用这种方法简单粗暴,但是如果两兄弟组件的父组件隔代过多,链路过长,调用起来十分复杂,就不推荐这种方式了。

2、通过根组件实例广播数据

我们可以创建公共js文件,其中声明一个vue根组件实例,非父子组件可以同时引用根组件的实例,然后在传递信息的一方,通过根组件实例的广播数据方法“$emit”,广播一个key,对应一个值或者方法,然后在接收数据的一方,通过根组件实例的接收广播方法“$on”,获取对方广播的值。

这里我们进行一下测试,首先我们在model文件夹下新建一个公共js,名为“vueEvent.js”,用于引入和实例化vue根组件,最后暴露出来:

代码:

import Vue from 'vue'

var vueEvent = new Vue();

export default vueEvent;

然后首页组件HelloWorld.vue中引用刚刚的实例“vueEvent”,然后定义一个按钮和方法“emitNews”,向新闻组件News.vue广播一个数据(其msg):

<template>
  <!-- 所有的内容要被根节点包含起来 -->
  <div class="hello">
    <v-header ref="header"></v-header>
    <h1>{{ msg }}</h1>
    <button @click="getChildData()">获取子组件的数据和方法</button>
    <button @click="emitNews()">给News组件广播数据</button>
  </div>
</template>

<script>
import Header from './Header.vue';
import vueEvent from '../model/vueEvent.js';
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: '首页父组件'
    }
  },
  methods:{
    getChildData(){
      console.log(this.$refs.header.msg);//获取子组件的值
      this.$refs.header.headRun();//调用子组件的方法
    },
    run(){
      alert("这里是父组件的方法");
    },
    emitNews(){
      vueEvent.$emit('to-news',this.msg);
    }
  },
  components:{
    'v-header':Header
  }
}
</script>

<!-- 添加 "scoped" 属性来限制里面css样式只能被该组件引用 -->
<style scoped>
  h1{
    color:red;
  }
</style>

在新闻组件News.vue中,我们在组件挂载时(生命周期函数mounted),获取首页组件HelloWorld.vue广播的数据:

<template>
    <div class="News">
        <v-header :title="title"></v-header>
        <h1>新闻组件</h1>
        <ul>
            <li>111111</li>
            <li>222222</li>
            <li>333333</li>
        </ul>
    </div>
</template>

<script>
import Header from './Header.vue';
import vueEvent from '../model/vueEvent.js';
export default {
  name: 'News',
  data () {
    return {
      title:'新闻头部'
    }
  },
  components:{
    'v-header':Header
  },
  mounted(){
    vueEvent.$on('to-news',function(data){
        console.log(data);
    });
  }
}
</script>

<style scoped>
</style>

效果:

可以看到兄弟组件广播的数据被接收方获取到了。

非父子组件传值总结:
1、新建一个js文件,引入和实例化vue,并暴露该实例;
2、在需要广播的组件中引入刚才定义的实例;
3、通过“vue实例名.$emit('名称','数据')”广播需要传递的数据;
4、在接收数据的地方通过“vue实例名.$on('名称',方法定义)”接收广播的数据,格式如下:
vue实例名.$on('名称',function(data){  });


参考:
《IT营:itying.com-2018年Vue2.x 5小时入门视频教程》

转载请注明出处:https://blog.csdn.net/acmman/article/details/109436798

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光仔December

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值