vue2父子组件传值(六种关系)

本文详细介绍了Vue开发中组件间数据传递的六种常见方式:父传子、子传父、兄弟组件间的平级传递、Vuex存储、provide&inject以及$parent和$children。重点讲解了每种方法的实现和适用场景。
摘要由CSDN通过智能技术生成

一:介绍

        在vue项目开发中,很多模块复用性很高,于是我们会将这些模块封装成组件,以便于减少代码的重复率,同时提高代码的可维护性和阅读性。

        那么在组件中如果需要一些数据该怎么办呢?这就涉及到了组件之间的传值,组件中传值一共有六种传值方法,分别是父传子,子传父,兄弟组件(平级传递),vuex存储公共数据,使用provide和inject监控祖孙之间传递,$parent和$chiildren传值。那么接下来让我们来看一下这六种传值方式该如何实现吧。

二:传值的六种方法

        1.父传子 

                父传子是目前vue开发中较为常见的一种方式,通常有接口的情况下,为了提高项目的效率,我们会传递一个ID值过去,通过ID获取数据。父传子的主要方式是通过props进行传值,如图:

         父页面

<template>
    <div>
        <son-component :id='id'></son-component>
    </div>
</template>

<script>
    import sonComponent from './components/sonComponent.vue'
    export default {
        components:{
            sonComponent
        },
        data() {
            return {
                id: 1
            }
        }
    }
</script>

         子组件

<template>
    <div>
        子组件的值:{{id}}
    </div>
</template>

<script>
    export default{
        props:['id']
    }
</script>


2.子传父 

        在vue开发中,子传父的使用频率不低于父传子。通常是在子组件中处理一些数据(比如子组件是个表单),在用户操作完成后需要保存这些数据,通常为了方便我们是不会在子组件中进行调用保存接口的,这样容易写出死组件,即失去了应有的模块化,所以我们通过this.$emit()进行传值到父页面中,在父页面进行保存。如图所示:

         父页面代码

<template>
    <div>
        <son-component :id='id' @success='successMethod'></son-component>
    </div>
</template>

<script>
    import sonComponent from './components/sonComponent.vue'
    export default {
        components:{
            sonComponent
        },
        data() {
            return {
                id: 1
            }
        },
        methods:{
            //子组件成功的回调函数
            successMethod(val){
                console.log(val)
            }
        }
    }
</script> 

        子组件代码 

<template>
    <div>
        子组件的值:{{id}}
        <ul>
            <li>
                我的id是:{{dataItem.id}}
            </li>
            <li>
                我的名字是:{{dataItem.name}}
            </li>
            <li>
                我的年龄是:{{dataItem.age}}
            </li>
        </ul>
        <el-button @click="onHandleUpdata">修改</el-button>
    </div>
</template>

<script>
    export default {
        props: ['id'],
        data() {
            return {
                //模拟数据库里的数据
                dataList: [{
                    id:0,
                    name: '张三',
                    age: 18
                }, {
                    id:1,
                    name: '李四',
                    age: 21
                }, {
                    id:2,
                    name: '王五',
                    age: 16
                }],
                dataItem:{}
            }
        },
        created() {
            this.getData()
        },
        methods:{
            getData(){
                this.dataItem=this.dataList.find((val,index,arr)=>{
                    if(val.id==this.id) return val
                })
                console.log(this.dataItem)
            },
            onHandleUpdata(){
                this.dataItem.age=25
                //前面是父组件中调用的方法,后面是传的值
                this.$emit('success',this.dataItem)
            }
        }
    }
</script>

         效果图:

 

               上图是子组件获取到的原值,通过点击修改后年龄变为25并传给父页面如下图

 3.兄弟组件(平级传递)

        兄弟组件的传值和子传父组价类似,都是通过emit()进行传值。主要是通过暴露一个事件总线,两个兄弟组件同时引入该总线,传值方使用this.$emit(),接收值的一方使用this.$on()

比如事件总线(eventBus.js)代码如下

import Vue from 'vue';
 
export default new Vue;

 兄弟组件的接收和发送数据代码如下:

<script>
import bus from '../../common/config/bus';
export default {
  components: {},
  data() {
    return {
      myList: [],
    };
  },
 
  mounted() {
    
  },
 
  methods: {
    getData(){
        //接收别的组件传过来的数据
        bus.$on('sendList', data => {
          this.myList = data;
        })
    },
    sendData() {
        //发送数据 
        this.myList=[];
        bus.$emit('sendList', this.myList);
    },
  },
}
 
</script>

4. vuex存储公共数据

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

创建@/store/omdex.js目录,文件内容如下: 

 import Vue from 'vue'
import Vuex from 'vuex'
 
//1.安装插件
Vue.use(Vuex)
 
//2.创建对象
const store = new Vuex.Store({
  state:{
    count:0
  },
  mutations:{
    addCount(state){
        state.count++
    },
    subCount(state){
        state.count--
    }
  },
  actions:{
    aAddCount(context,payload){
          setTimeout(() => {
            context.commit('addCount')
            console.log(payload);
          }, 500);
        }
  },
  getters:{
 
  },
  modules:{
    
  }
})
//3.导出使用
export default store

 在main.js添加以下代码

import store from './store'

// 创建vm
new Vue({
    // 指定容器
    el: '#app',
    // 解析App模板
    render: h => h(App),
    store
})

 子组件一的代码

<template>
    <div>
        当前的值是:{{$store.state.count}}
        <button @click="onSubClick">+1</button>
    </div>
</template>

<script>
    export default{
        data(){
            return{
                
            }
        },
        methods:{
            onSubClick(){
                // this.$store.commit('addCount')
                this.$store.dispatch('aAddCount')
            }
        }
        
    }
</script>

<style>
</style>

子组件二的代码

<template>
    <div>
        当前的值是:{{$store.state.count}}
        <button @click="onSubClick">-1</button>
    </div>
</template>

<script>
    export default{
        methods:{
            onSubClick(){
                this.$store.commit('subCount')
            },
        }
    }
</script>

<style>
</style>

 父组件引入两个子组件

<template>
    <div>
        <div>vuex(状态管理)的使用如下:</div>
        <AddCount></AddCount>
        ------------------------------
        <SubCount></SubCount>
    </div>
</template>

<script>
    import AddCount from './components/AddCount.vue'
    import SubCount from './components/SubCount.vue'
    export default {
        // 组测组件
        components: {
            AddCount,
            SubCount
        },
        methods: {
        },
    };
</script>

运行效果,当点击任意一个按钮时,会改变vuex里的值,其余组件会自动同步

 

 5.provide和inject注入

        在父子组件传递数据时,通常使用的是 props 和 emit,父传子时,使用的是 props,如果是父组件传孙组件时,就需要先传给子组件,子组件再传给孙组件,如果多个子组件或多个孙组件使用时,就需要传很多次,会很麻烦。

        像这种情况,可以使用 provide 和 inject 解决这种问题,不论组件嵌套多深,父组件都可以为所有子组件或孙组件提供数据,父组件使用 provide 提供数据,子组件或孙组件 inject 注入数据。同时兄弟组件之间传值更方便。

父组件

<script>
export default {
  // 父组件通过provide将自己的数据以对象形式传出去
  provide(){
    return {
      msg:'一条信息'
    }
  }
};
</script>

子孙组件

<script>
export default {
  // inject:["msg"], // 使用一个注入的值作为数据入口
  inject:{ //或者写成对象
    // 使用一个默认值使其变成可选项
    msg: { // 键名
      from: 'msg', // 来源
      default: '' // 默认值
    }
  }
}
</script>

 6.$parent和$chiildren传值

        在开发中该方法使用频率没有那么高,因此在本文中不做详细解释,只做概括。

        (1)父传子

       this.$children[index]  需要指定子组件的下标(第几个子组件)

this.$children[0].name = '张三';//将子组件的name值设置为'张三'

        (2)子传父 

this.$parent  不需要指定下标

this.$parent.name = "李四";//将父组件的name属性设置为'李四'

 三:尾记

        目前开发中,比较常见的传值方法是父传子,子传父,vuex存储,provide和inject监控(至少我在项目中很少使用到第三个和第六个)。当然传值的方法还有很多,比如缓存等,但这些容易导致浏览器缓存过多而加载慢,甚至导致浏览器未响应关闭等,同时会占用电脑大量内存,因此我在这里不做介绍与推荐。好啦,希望各位小伙伴通过本篇章能够学到一点东西,这就是对博主的最大支持啦~ 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

暴怒的代码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值