Vue如何解决兄弟组件之间传值问题

目录
  • 解决兄弟组件之间传值问题
    • bus可以通过两种方式来实现
  • 各类组件间传值方法(父子、兄弟、页级)
    • 父子关系组件
    • 兄弟关系组件
    • 页级关系组件

解决兄弟组件之间传值问题

vue中 父组件向子组件传递参数时,可以通过prop来传递参数,prop可以是数组形式,也可以是对象格式,子向父组件传递参数时,通过$emit来传递,$emit('方法名', 传参),来实现子组件和父组件数据交互,但是在父组件中,有好多个子组件,这些子组件怎么样来进行数据通讯呢?

有的同学会立马想到 vuex ,答案是:可以的,但是会不会大材小用?在项目中,只是个别组件需要用到通讯,我们是不会优先考虑vuex来解决的。

下面我们可以使用一个特别好用的方法来实现兄弟组件之间数据通讯

bus.js 顾名思义 巴士,所有人都可以上车,不管你在哪里,不管你是什么组件,我都可以开车过去接你。

bus可以通过两种方式来实现

1. 通过创建.js文件局部方式来实现,在需要用到的组件中引入,然后调用它即可

在项目的utils文件中创建一个js文件,在正常的项目种,会用utils来存放哪些共用的js文件,这些js文件是一些常用的方法或例如这个bus

// bus.js
import Vue from 'vue';
export default new Vue();

接下来,哪个组件需要发车你就在哪里import给它建立一个发车点

// 在 vue组件中引入
import bus from "../../utils/bus";

然后这里我们在vue的实例中的methods函数中定义一个方法来触发这个bus发车

methods: {
      busFun(data) {
        // 通过 $emit 来触发方法,参数1 是定义方法名,参数2 是你要发送的数据
        bus.$emit('name', data)
      },
    }

这里千万要注意了,若你使用多个bus 那么参数1命名千万别重复,否则其他组件会出现无故上车的情况,这个bus中可以给无数个组件使用,但是命名不能重复,除非你创建多个bus。

接下来我们就看看这辆巴士有哪个组件要上车。

同样,如果其他组件要上车,我们必须要在这个组件中设立一个车站,不然巴士不知道要在哪里接这个组件。

// 这个组件需要上车,我们先设立一个车站
import bus from "../../utils/bus";

设立车站后,我们就需要通过 bus.$on来触发,也就是上车的技能

 created() {
      bus.$on('name', (data) => {
        console.log(data, '上车成功');
      })
    },
    // 打卡
    beforeDestroy() {
      bus.$off('name');
    },

这里会有同学会疑惑,为什么上车后需要打卡???

我们先说从上往下说吧,首先我们必须要在 vue 的created钩子函数中来触发这个bus,在页面还没加载的时候我们先触发它然后拿到数据,在created中执行,我们可以避免很多坑,例如触发bus无法拿到数据等问题(想了解的同学去问度娘,这里就不说明了)。

然后我们每次触发这个bus的时候,我们必须在整个生命周期走完的时候将这个bus给移除掉。

简单粗暴的说,就是我们每个组件上车的时候,我们必须要给它打卡掉,让后面的bus知道这个组件已经上车了,不需要在这里等待,接到就开走,头都不回的那种。

执行beforeDestroy来销毁这个bus方法,是避免方法“冗余”,若不清除这个方法,那将会出现多个bus触发,每次都会将这辆bus停留在这个vue的生命周期中,打开控制台你会发现有好多辆bus在这里停留,因为我们每次触发bus时,就会开一辆巴士出来,而不是这辆巴士一直重复开的原因。

2. 接下来我们就说一下第二种方式

// 我们在main.js中用常量创建一个bus,然后将它放入Vue实例的原型对象中。
const bus = new Vue()
Vue.prototype.$bus = bus;

然后我们就可以在全局 通过this.$bus来开巴士了(#滑稽)。接下来只要开稳就可以为所欲为了。

 created() {
      this.$bus.$on('name', (data) => {
        console.log(data, '上车成功');
      })
    },
    // 打卡
    beforeDestroy() {
      this.$bus.$off('name');
    },

最后别忘了给乘客打卡哦!

各类组件间传值方法(父子、兄弟、页级)

熟悉vue各类关系的组件之间传值方法会令开发更加得心应手,下面将对父子、兄弟、页级组件之间的传值作浅谈。

父子关系组件

- 父向子组件传值

父组件向子组件传值通常是利用props属性。首先,在子组件里定义一个props值用来接收父组件数据;然后调用子组件并v-bind绑定这个props值 = 父组件的data值。

父组件代码:

<template>
  <div class="home">
    <HelloWorld :newMsg="msg" /> 
    //绑定子组件newMsg(props值) = 父组件msg(data值)
  </div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
  name: "Home",
  data(){
    return{msg:'Welcome to Vue.js'} //父组件数据msg
  },
  components: {HelloWorld}
};
</script>

子组件代码:

<template>
  <div>
    <h1>{{ newMsg }}</h1>  //直接调用newMsg,显示“Welcome to Vue.js”
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  props: {newMsg: String}  //为子组件定义newMsg(props值)接收父组件msg
  //或者props:['newMsg']
};
</script>

- 子向父组件传值

子组件向父组件传值有两种方式:

1. 利用$emit()方法。 首先在子组件中用$emit()向上传递一个自定义事件并附带想要传递的数据;然后在父组件v-on监听这个自定义事件并自动接收到数据;最后在响应该事件的方法中进行数据操作。

子组件代码:

<script>
export default {
  name: "HelloWorld",
  data() {
    return {msg:"Welcome to Vue"} //data值,即将向上传递的值
  },
  created(){
    this.$emit('change',this.msg) //向上传递自定义事件change和data值。这里我调用created生命周期函数触发$emit()
  }
};
</script>

父组件代码:

<template>
  <div class="home">
    <HelloWorld @change="handle" /> //监听到子组件传递来的事件并响应handle方法
    <span>{{newMsg}}</span>  //直接调用newMsg,显示“Welcome to Vue”
  </div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
  name: "Home",
  data() {
    return {newMsg:""}
  },
  methods:{
    handle(msg){           //定义handle方法,将自动接收到的msg值给了自己的newMsg
      this.newMsg = msg
    }
  },
  components: {HelloWorld}
};
</script>

2.利用ref属性。 ref是vue提供的内部属性,它其实相当于类似"id""class"的标识。首先在子组件上定义ref值(例:ref="son");然后在父组件中用this.\$refs.son即可获取到son这个ref的组件,进行操作。

子组件代码:

<script>
export default {
  name: "HelloWorld",
  data() {
    return {msg:"Welcome to Vue"}  //即将向父传递的data值
  }
};
</script>

父组件代码:

<template>
  <div class="home">
    <HelloWorld ref="son" />  //在子组件上定义一个ref 名为"son"
  </div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
  name: "Home",
  mounted(){
    console.log(this.$refs.son.msg)  //获取到ref名为"son"的子组件内msg数据,在控制台显示“Welcome to Vue”
  },
  components:{HelloWorld}
};
</script>

兄弟关系组件

兄弟组件间的传值方式我称为 “总线转送” 。原理很简单,利用父组件作为总线去转送数据。首先,用上述讲到的ref属性或$emit()将组件A的数据向上传递给父组件;再由父组件通过props属性向下传值到组件B。

组件A代码:

<template>
  <div>click me</div>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {helloMsg:"Welcome to Vue"} //即将传送的数据helloMsg
  }
};
</script>

组件B代码:

<template>
  <div>
    {{hiMsg}}  //直接调用hiMsg,显示“Welcome to Vue”
  </div>
</template>
<script>
export default {
  name: "Hi",
  props:{hiMsg:String} //用来接收父组件传值的props属性hiMsg
};
</script>

父组件代码:

<template>
  <div class="home">
    <HelloWorld ref="son" @click.native="change"></HelloWorld> //定义ref属性接收组件A传来的数据;点击组件A触发change()
    <Hi :hiMsg="msg"></Hi>  //绑定组件B的hiMsg=msg,将数据转发给组件B
  </div>
</template>
<script>
import HelloWorld from "@/components/HelloWorld.vue";
import Hi from "@/components/Hi.vue";
export default {
  name: "Home",
  data(){
    return{ msg: "" }
  },
  methods:{
    change(){
      return this.msg = this.$refs.son.helloMsg //将组件A传来的helloMsg赋予this.msg
    }
  },
  components:{HelloWorld, Hi}
};
</script>

页级关系组件

在vuecli3.0以后,项目结构对组件级别作了明确的区别:入口组件(App) - 页级组件(View) - 零件组件(Component)。一般在开发中我们也会尽量按照这种结构去划分模块,但页级组件没有父组件,如果说页级组件之间需要传值,那就不能用“总线转送”的方法了。

vuex:这是官方提供的一个插件,可称为“状态管理仓库”,用来管理项目中需要跨页共享反复调用的状态(状态你可以理解成就是数据、变量、方法)。

vuex的存放仓库为Store,内部结构可分五大块:

  • state:状态库,寄放基础状态。
  • mutations:同步方法,可理解成相当于组件内的computed属性,接收state进行改装。
  • actions:异步方法,只针对mutations,接收并改装。
  • getters:过滤器,对state调用前进行改装、派生并返回数据。
  • modules:模块,在复杂项目中用modules处理Store,使分工更清晰。

vuex令开发中数据共享操作更得心应手,还需要大家到官方文档认真学习。以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vue项目中props传值时子组件检测不到的问题及解决

    目录 props传值时子组件检测不到 props用法和传值问题 基本用法 props的使用 单向数据流:props是单向绑定的 总结一下props传值的注意点 props传值时子组件检测不到 我们在Vue项目开发的过程中,经常会需要在父子组件传值,我们都知道,父子组件传值的时候是通过 props 来进行的,但是在父组件的数据动态改变的时候,子组件却接收不到最新变化的数据,这个时候怎么办呢? 首先,传值不能用驼峰命名法,因为vue语法中规定HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大

  • vue3 父子组件间相互传值方式

    目录 vue3父子组件相互传值 父向子传值 子组件向父组件传值 vue3父子组件传值的注意事项 解决办法:两种 vue3父子组件相互传值 父向子传值 父 <pie-chart :pieData="post_data.pid" /> 父组件只需在子组件上声明一个变量即可. :代表变量,可以传变量;否则只能传常量 子 export default {     props:['pieData'],     setup(props,ctx) {         const pie_

  • vue中兄弟组件传值的两种方式小结

    目录 一. bus总线传值的使用 二. 使用常规的传值:(子传父,父再传子) 总结 本demo主要是为了演示vue项目中兄弟组件之间的传值,这里我演示了两种方式: a. bus总线传值: b. 我自己一般把它当成常规的传值(其实也就是子组件A传父组件,父组件再传子组 件B) 下边开始本次demo的编写: 一. bus总线传值的使用 在项目中创建一个单独的eventBus.js文件 该js文件的内容很简单,就是暴露一个vue实例而已. 有人喜欢在main.js全局引入该js文件,我一般在需要使用到

  • Vue3兄弟组件传值之mitt的超详细讲解

    目录 前言 比起 Vue 实例上的 EventBus,mitt.js 好在哪里呢? 项目中安装mitt 使用方式一:在原型中声明 使用方式二:在组件中引用 总结 前言 Vue2.x 使用 EventBus 事件总线进行兄弟组件通信,而在Vue3中事件总线模式已经被移除,官方建议使用外部的.实现了事件触发器接口的库,例如 mitt 或 tiny-emitter. 比起 Vue 实例上的 EventBus,mitt.js 好在哪里呢? 首先它足够小,仅有200bytes. 其次支持全部事件的监听和批

  • vue3父组件和子组件如何传值实例详解

    目录 1.父组件打开子组件的的dialog组件 2.父组件关闭子组件的的dialog组件 3.开始运用: 用户的增加修改操作 1.父组件的修改 2.子组件的修改 3.父组件给子组件赋值 4.子组件调用父组件方法 总结 1.父组件打开子组件的的dialog组件 新建一个vue文件命名为test 然后咱们直接从官网CV一个带有表单的dialog组件如下 //子组件 <template> <el-dialog v-model="dialogFormVisible" titl

  • vue组件之间进行传值的方法

    目录 前言 1.父组件向子组件进行传值 2.子组件向父组件进行传值 3.非父子组件之间的传值 总结 前言 目前在做vue的项目,用到了子组件依赖其父组件的数据,进行子组件的相关请求和页面数据展示,父组件渲染需要子组件通知更新父组件的state,父子组件之间的传值一般有三种方法: 父传子子传父非父子传值 注意: 父子组件的关系可以总结为 prop 向下传递,事件向上传递.父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息.  接下来,我们会通过实例代码来看的更清晰,理解更容易:

  • 分享Vue组件传值的几种常用方式(一)

    目录 前言 第一种:父向子传值 新建文件导入结构 引入 注册 使用子组件 子组件内部代码完善 父组件内部代码完善 操作main.js文件 思路总结 前言 大家好,这个系列我们来讲解一下vue组件传值的几种常见方法和逻辑链路.最常见的vue组件传值分为三种,第一种是父向子传值,第二种是子向父传值,第三种是兄弟组件之间的传值,下面我们先就第一种情况来进行分析和编写. 第一种:父向子传值 父向子传值意思就是要把父组件里的值传递给子组件,方法是在子组件内部自定义一个props属性,通过props属性来完

  • 深入了解Vue3组件传值方式

    目录 父子组件传值 props 祖孙组件传值 provide 和 inject 父组件中点击按钮向子组件传值 今天说一下 vue3 的组件间传值,学习过 vue2 的宝子们肯定知道,组件传值是 vue 项目开发过程中必不可少的功能场景,在 vue2 里面有很多传值的方式,vue3 的传值方式呢,在这里稍微整理总结一下,但是不是很全,后期可能慢慢补充. 父子组件传值 props 和 vue2 一样,vue3 也可以使用 props 进行父组件传值给子组件,这个就不多说了直接上代码. 父组件 <te

  • Vue如何解决兄弟组件之间传值问题

    目录 解决兄弟组件之间传值问题 bus可以通过两种方式来实现 各类组件间传值方法(父子.兄弟.页级) 父子关系组件 兄弟关系组件 页级关系组件 解决兄弟组件之间传值问题 vue中 父组件向子组件传递参数时,可以通过prop来传递参数,prop可以是数组形式,也可以是对象格式,子向父组件传递参数时,通过$emit来传递,$emit('方法名', 传参),来实现子组件和父组件数据交互,但是在父组件中,有好多个子组件,这些子组件怎么样来进行数据通讯呢? 有的同学会立马想到 vuex ,答案是:可以的,

  • Vue.js中兄弟组件之间互相传值实例

    兄弟组件之间互相传值,需要建立一个"中转站"(新的vue实例),并且需要主动触发. 实例上的$on方法来接受监听. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件传值</title> <script src="vue.js"></script

  • vue 解决兄弟组件、跨组件深层次的通信操作

    兄弟组件之间的通信同样是在项目中经常会遇到的组件间的通信问题之一, 这种问题的最根本方法就是: 把兄弟组件内部的变量提升到一个中央仓库. 借助父级组件链式交互 使子组件1 通过 $emit 通知父级, 父级再通过响应 子组件1 的事件去触发子组件2的事件,这样的链式操作,在子组件不多的时候,但是一个不错的解决方法 子组件1 <template> <div> <p @click="$emit('fromFirst','来自A组件')">first组件&

  • 基于vue 兄弟组件之间事件触发(详解)

    直奔主题! 兄弟组件之间的事件触发,大概思路是通过父级组件交换数据,watch来监听触发事件. 场景是父级组件A同时引用两个子级组件B,C.点击B组件中的按钮执行C组件中的事件. 第一步:父级组件A <bottom-play :play="playStatus" @playStatus="btmChild"></bottom-play> methods:{ listChild:function(val){//B组件自定义事件 状态是布尔值 t

  • vue实现组件之间传值功能示例

    本文实例讲述了vue实现组件之间传值功能.分享给大家供大家参考,具体如下: slot标签: 想向封装好结构的组件中插入内容,需要借助<slot></slot> 在组件之中进行关联:如 模板中: <slot name='txt'></slot> 组件调用中: <p slot='txt'></p> 注:如果只有slot上面每一定义name属性,则只能有一个slot <div class='box'> <com> &

  • 深入理解Vue 组件之间传值

    一.父组件向子组件传递数据 在 Vue 中,可以使用props向子组件传递数据. 子组件部分: 这是 header.vue 的 HTML 部分,logo 是在 data 中定义的变量. 如果需要从父组件获取 logo 的值,就需要使用props: ['logo'] 在 props 中添加了元素之后,就不需要在 data 中再添加变量了 父组件部分: 在调用组件的时候,使用 v-bind 将 logo 的值绑定为 App.vue 中定义的变量 logoMsg 然后就能将App.vue中 logoM

  • vue实现兄弟组件之间跳转指定tab标签页

    目录 兄弟组件之间如何跳转指定tab标签页 场景 vue.js实现tab页面的跳转 tab标签 tab标签对应的展示的内容 vue实例中对应的数据以及函数 兄弟组件之间如何跳转指定tab标签页 场景 index跳转至list的第三个标签栏并刷新列表 // index methods: {      ...      go(){       this.$router.push({         name: 'list',        //要跳转的路由name         query: {

  • vue2.0组件之间传值、通信的多种方式(干货)

    Vue中组件这个特性让不少前端er非常喜欢,我自己也是其中之一,它让前端的组件式开发更加合理和简单.这次我们就来聊一聊vue2.0组件之间传值.通信的多种方式. 一.通过路由带参数进行传值 ①两个组件 A和B,A组件通过query把orderId传递给B组件(触发事件可以是点击事件.钩子函数等) this.$router.push({ path: '/conponentsB', query: { orderId: 123 } }) // 跳转到B ②在B组件中获取A组件传递过来的参数 this.

  • vue实现两个组件之间数据共享和修改操作

    我们在使用vue开发过程中会遇到这样的情况,在父组件中引入了子组件,需要将父组件的值传到子组件中显示,同时子组件还可以更改父组件的值. 以我目前的一个项目的开发为例,如下图页面: 在父组件中,我引入了两个子组件,一个是左边的导航栏,还有中间的一个富文本编译器组件,当我点击左边导航栏时,中间的页面会切换,也就是改变引入的子组件. 怎么实现呢,首先,设置在该页面index.vue中设置一个变量index,左边导航栏每一项也对应一个index值,导航菜单绑定select函数,@select="hand

  • Vue.js实战之组件之间的数据传递

    前言 Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 首先用 vue-cli 创建一个项目,其中 App.vue 是父组件,components 文件夹下都是子组件. 一.父组件向子组件传递数据 在 Vue 中,可以使用 props 向子组件传递数据. 子组件部分: 这是 header.vue 的 HTML 部分,logo 是在 data 中定义的变量. 如果需要从父组件获取 logo 的值,就需要使用 props: [

随机推荐