Vue 组件间传值

贾宝玉
• 阅读 3427

前言

Vue 作为现在比较火的框架之一,相信您在使用的过程中,也会遇到组件间传值的情况,本文将讲解几种 Vue 组件间传值的几种方法,跟着小编一起来学习一下吧!

实现

注意: 学习本文,需要您对 Vue 有一定的了解。

为了便于讲解,以下方法均假设父组件是 FatherComponent,子组件是 ChildComponent,兄弟组件是:BrotherComponent。我们来假定一种场景:点击父组件“传递给子组件”按钮,向子组件传递一条消息“I am your father.”;点击子组件“传递给父组件”按钮,向父组件传递一条消息“I am your child.”;点击子组件“传递给兄弟组件”按钮,向兄弟组件传递一条消息“I am your brother.”

1. 方法一

关键词: props、$emit

父组件 FatherComponent 代码:

<template>
  <div>
    <div>{{toFatherInfo}}</div>
    <ChildComponent :toChildInfo="toChildInfo" @toFather="toFather" @toBrother="toBrother"/>
    <BrotherComponent :toBrotherInfo="toBrotherInfo"/>
    <button @click="toChild">传递给子组件</button>
  </div>
</template>

<script>
  import ChildComponent from 'components/test/child-component'
  import BrotherComponent from 'components/test/brother-component'

  export default {
    components: {
      ChildComponent,
      BrotherComponent
    },
    data () {
      return {
        toFatherInfo: '',
        toChildInfo: '',
        toBrotherInfo: ''
      }
    },
    methods: {
      toFather (res) {
        this.toFatherInfo = res
      },
      toBrother (res) {
        this.toBrotherInfo = res
      },
      toChild () {
        this.toChildInfo = 'I am your father.'
      }
    }
  }
</script>

<style lang="less">
  button {
    font-size: 36px;
    border: none;
    padding: 20px;
    background-color: #999;
    color: #fff;
    width: 100%;
    margin-top: 30px;
  }
</style>

子组件 ChildComponent 代码:

<template>
  <div>
    <div>{{toChildInfo}}</div>
    <button @click="toFather">传递给父组件</button>
    <button @click="toBrother">传递给兄弟组件</button>
  </div>
</template>

<script>
  export default {
    props: {
      toChildInfo: {
        type: String
      }
    },
    methods: {
      toFather () {
        this.$emit('toFather', 'I am your child.')
      },
      toBrother () {
        this.$emit('toBrother', 'I am your brother.')
      }
    }
  }
</script>

<style lang="less">
</style>

兄弟组件 BrotherComponent 代码:

<template>
  <div>{{toBrotherInfo}}</div>
</template>

<script>
  export default {
    props: {
      toBrotherInfo: {
        type: String
      }
    }
  }
</script>

<style lang="less">
</style>

通过上面代码,不难发现,我们通过使用 props 来实现父组件给子组件传值;子组件向父组件传值时,借助 $emit 来实现;而子组件向兄弟组件传值时,将两者结合起来使用。

2. 方法二

关键词:独立的事件中心 eventHub

首先需要先创建 eventHub.js 文件,代码如下:

// 将在各处使用该事件中心
// 组件通过它来通信
import Vue from 'vue'
export default new Vue()

然后在组件中,可以使用 $emit, $on, $off 分别来分发、监听、取消监听事件。

父组件 FatherComponent 代码:

<template>
  <div>
    <div>{{info}}</div>
    <ChildComponent />
    <BrotherComponent />
    <button @click="toChild">传递给子组件</button>
  </div>
</template>

<script>
  import eventHub from '../../components/test/eventHub'
  import ChildComponent from 'components/test/child-component'
  import BrotherComponent from 'components/test/brother-component'

  export default {
    components: {
      ChildComponent,
      BrotherComponent
    },
    data () {
      return {
        info: ''
      }
    },
    created: function () {
      eventHub.$on('toFather', this.toFather)
    },
    // 最好在组件销毁前
    // 清除事件监听
    beforeDestroy: function () {
      eventHub.$off('toFather', this.toFather)
    },
    methods: {
      toFather (res) {
        this.info = res
      },
      toChild () {
        eventHub.$emit('toChild', 'I am your father.')
      }
    }
  }
</script>

<style lang="less">
  button {
    font-size: 36px;
    border: none;
    padding: 20px;
    background-color: #999;
    color: #fff;
    width: 100%;
    margin-top: 30px;
  }
</style>

子组件 ChildComponent 代码:

<template>
  <div>
    <div>{{info}}</div>
    <button @click="toFather">传递给父组件</button>
    <button @click="toBrother">传递给兄弟组件</button>
  </div>
</template>

<script>
  import eventHub from './eventHub'
  export default {
    data () {
      return {
        info: ''
      }
    },
    created: function () {
      eventHub.$on('toChild', this.toChild)
    },
    // 最好在组件销毁前
    // 清除事件监听
    beforeDestroy: function () {
      eventHub.$off('toChild', this.toChild)
    },
    methods: {
      toChild (res) {
        this.info = res
      },
      toFather () {
        eventHub.$emit('toFather', 'I am your child.')
      },
      toBrother () {
        eventHub.$emit('toBrother', 'I am your brother.')
      }
    }
  }
</script>

<style lang="less">
</style>

兄弟组件 BrotherComponent 代码:

<template>
  <div>{{info}}</div>
</template>

<script>
  import eventHub from './eventHub'
  export default {
    data () {
      return {
        info: ''
      }
    },
    created: function () {
      eventHub.$on('toBrother', this.toBrother)
    },
    // 最好在组件销毁前
    // 清除事件监听
    beforeDestroy: function () {
      eventHub.$off('toBrother', this.toBrother)
    },
    methods: {
      toBrother (res) {
        this.info = res
      }
    }
  }
</script>

<style lang="less">
</style>

3. 方法三

关键词:Vuex

我们需要创建 store.js 来存放数据:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    fromFatherInfo: '',
    fromChildInfo: '',
    fromBrotherInfo: ''
  },
  mutations: {
    changeFromFatherInfo (state, fromFatherInfo) {
      state.fromFatherInfo = fromFatherInfo
    },
    changeFromChildInfo (state, fromChildInfo) {
      state.fromChildInfo = fromChildInfo
    },
    changeFromBrotherInfo (state, fromBrotherInfo) {
      state.fromBrotherInfo = fromBrotherInfo
    }
  }
})

实例化:

import Vue from 'vue'
import App from './App'
import store from './store'

new Vue({
  el: '#app',
  store,
  template: '<App/>',
  components: { App }
})

父组件 FatherComponent 代码:

<template>
  <div>
    <div>{{fromChildInfo}}</div>
    <ChildComponent />
    <BrotherComponent />
    <button @click="toChild">传递给子组件</button>
  </div>
</template>

<script>
  import ChildComponent from 'components/test/child-component'
  import BrotherComponent from 'components/test/brother-component'

  export default {
    components: {
      ChildComponent,
      BrotherComponent
    },
    computed: {
      fromChildInfo () {
        return this.$store.state.fromChildInfo
      }
    },
    methods: {
      toChild () {
        this.$store.commit('changeFromFatherInfo', 'I am your father.')
      }
    }
  }
</script>

<style lang="less">
  button {
    font-size: 36px;
    border: none;
    padding: 20px;
    background-color: #999;
    color: #fff;
    width: 100%;
    margin-top: 30px;
  }
</style>

子组件 ChildComponent 代码:

<template>
  <div>
    <div>{{fromFatherInfo}}</div>
    <button @click="toFather">传递给父组件</button>
    <button @click="toBrother">传递给兄弟组件</button>
  </div>
</template>

<script>
  export default {
    computed: {
      fromFatherInfo () {
        return this.$store.state.fromFatherInfo
      }
    },
    methods: {
      toFather () {
        this.$store.commit('changeFromChildInfo', 'I am your child.')
      },
      toBrother () {
        this.$store.commit('changeFromBrotherInfo', 'I am your brother.')
      }
    }
  }
</script>

<style lang="less">
</style>

兄弟组件 BrotherComponent 代码:

<template>
  <div>{{fromBrotherInfo}}</div>
</template>

<script>
  export default {
    computed: {
      fromBrotherInfo () {
        return this.$store.state.fromBrotherInfo
      }
    }
  }
</script>

<style lang="less">
</style>
点赞
收藏
评论区
推荐文章
晴空闲云 晴空闲云
3年前
vue3中基于script setup语法糖的$refs使用
在用vue3开发项目的时候,需要调用子组件的方法,于是想着用$refs来实现,但是我是使用scriptsetup语法糖,原先vue2的语法已经不适用了。于是一番折腾和查阅资料,终于搞定。vue2语法vue2语法在组件上设置ref属性后,在代码里可以通过this.$refs.ref值访问到对应的子组件。一个设置ref值的组件:html在js代码中可以通
Alex799 Alex799
4年前
vue最新面试题
最近在面试,总结几个重点的面试题:一、vue父子组件之间的传值:简单来说,子组件通过props方法接受父组件传来的值,子组件通过$emit方法来向父组件发送数据。(具体案例可以看我之前写的博客)。二、vue生命周期函数:beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedbeforeDestr
Chase620 Chase620
4年前
vue的8种通信方式
1.props/emit1.父组件向子组件传值下面通过一个例子说明父组件如何向子组件传递数据:在子组件article.vue中如何获取父组件section.vue中的数据articles:\'红楼梦','西游记','三国演义'\//section父组件<template<divclass"section"
海军 海军
4年前
2021前端技术面试必备Vue:(二)组件篇
上一章已经更新了Vue基础,那么本章将更新Vue中最重要的概念组件,会介绍到组件的使用,组件传值,插槽的使用,插槽的分类。当第一章基础掌握差不多了,然后再学习了组件的开发,那么你就可以开发简单的Vue项目,路由文章还没有更新,学习完Router后,就可以开发实战项目了。<sectionid"nice"datatool"mdnice编
可莉 可莉
4年前
了解Vuex状态管理模式
1Vuex是什么呢?它是Vue的状态管理模式,在使用vue的时候,需要在vue中各个组件之间传递值是很痛苦的,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被改变,所有引用该值的地方就会自动更新。是不是很方便,很好用呢?vuex是专门为vue.js设计的状态管理模式,集中式存储和管理应用程序中所有组件的状态,vuex也集成了vue的
马丁路德 马丁路德
4年前
微信小程序 - 页面间传值
小程序页面间传值大家晚上好,说晚上好是因为是在晚上写的,说这句话是因为这句话开篇不那么突然。那么小程序的页面间传值,在我使用这段时间里,我就非常的主观的把它们分为wx.navigateTo和非wx.navigateTo的,因为wx.navigateTo有一个事件参数event,我从当前页跳转到下一页,如果需要能返回,我都用的wx.naviga
爱丽丝13 爱丽丝13
4年前
React 组件通信之发布订阅模式
React通信react的数据流是单向的,react通信有以下几种方式:父向子通信:传入props子向父通信:父组件向子组件传一个函数,然后通过这个函数的回调,拿到子组件传过来的值父向孙通信:利用context传值。React.createContext()兄弟间通信:​1、找一个相同的父组件,既可以用pr
LinMeng LinMeng
4年前
vue中页面间跳转传值的两种方式(query,params)
两者都可以传递参数,区别是什么?query传参配置的是path,而params传参配置的是name,在params中配置path无效query在路由配置不需要设置参数,而params必须设置query传递的参数会显示在地址栏中params传参刷新会无效,但是query会保存传递过来的值,刷新不变;query:this.$route
Dax Dax
3年前
Vue父子组件
几种常见的通信方式:1、prop属性父组件通过绑定属性的方式,给子组件传值,同时子组件通过设置props来接收letChildVue.extend(template:'content',props:content:type:String,default:()r
Wesley13 Wesley13
3年前
unity将 -u4E00 这种 编码 转汉字 方法
 unity中直接使用 JsonMapper.ToJson(对象),取到的字符串,里面汉字可能是\\u4E00类似这种其实也不用转,服务器会通过类似fastjson发序列化的方式,将json转对象,获取对象的值就是中文但是有时服务器要求将传参中字符串中类似\\u4E00这种转汉字,就需要下面 publ
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(