Vue 组件传值(通信)方式详解

目录

Vue 组件传值(通信)方式详解

一、Vue2 组件传值方式

(一)父传子

(二)子传父

(三)平辈之间传值

二、Vue3 中的组件传值方式

(一)父传子

(二)子传父

(三)平辈之间传值

三、总结


在 Vue 开发中,组件之间的传值是非常重要的环节。本文将详细介绍 Vue2 中的组件传值方式,并结合 Vue3 的情况进行分析,同时给出相应的代码示例。

一、Vue2 组件传值方式

(一)父传子

  1. 绑定形式传值
    • 在父组件中,通过单向绑定的方式将数据传递给子组件。例如:

   <template>
     <div>
       <list :str1="str1"></list>
     </div>
   </template>

   <script>
   import list from './list.vue';
   export default {
     components: { list },
     data() {
       return {
         str1: 'home 的数据',
       };
     },
   };
   </script>

  • 在子组件中,通过props接收父组件传递过来的数据。例如:

   <template>
     <div>{{ str1 }}</div>
   </template>

   <script>
   export default {
     props: {
       str1: {
         type: String,
         default: '',
       },
     },
   };
   </script>

  • 这种方式的优点是父传子很方便,但缺点是无法直接将数据传递给孙子辈组件,需要一级一级传递。

  1. 子组件直接使用父组件数据
    • 在子组件中,可以通过this.$parent来获取父组件的数据。例如:

   <template>
     <div>{{ this.$parent.str1 }}</div>
   </template>

   <script>
   export default {
     mounted() {
       console.log(this.$parent.str1);
     },
   };
   </script>

  • 这种方式子组件可以直接拿到父组件的数据,但与传统的传值方式不同,它不是通过父组件主动传递数据给子组件。而且这种方式写死了数据的获取路径,不便于维护。同时,子组件可以直接修改父组件的数据,这可能会导致数据的不可控性。

(二)子传父

  1. 自定义事件传值
    • 在子组件中,定义一个自定义事件,并在触发事件时将数据传递给父组件。例如:
   <template>
     <div>
       <button @click="sendDataToParent">点击传值给父组件</button>
     </div>
   </template>

   <script>
   export default {
     data() {
       return {
         str2: 'list 组件的数据',
       };
     },
     methods: {
       sendDataToParent() {
         this.$emit('change', this.str2);
       },
     },
   };
   </script>

  • 在父组件中,通过监听子组件的自定义事件来接收数据。例如:

   <template>
     <div>
       <list @change="receiveDataFromChild"></list>
       {{ str2 }}
     </div>
   </template>

   <script>
   import list from './list.vue';
   export default {
     components: { list },
     data() {
       return {
         str2: '',
       };
     },
     methods: {
       receiveDataFromChild(value) {
         this.str2 = value;
       },
     },
   };
   </script>

  1. 父组件直接获取子组件数据
    • 父组件可以通过this.$childrenthis.$refs来直接获取子组件的数据,但这种方式不常用,因为通过下标获取子组件可能会因为子组件的顺序变化而导致问题,而且代码的可读性和可维护性较差。例如:
   <template>
     <div>
       <list ref="child"></list>
       <button @click="getChildData">获取子组件数据</button>
       {{ str2 }}
     </div>
   </template>

   <script>
   import list from './list.vue';
   export default {
     components: { list },
     data() {
       return {
         str2: '',
       };
     },
     methods: {
       getChildData() {
         this.str2 = this.$refs.child.str2;
       },
     },
   };
   </script>

(三)平辈之间传值

  • 通常使用bus(事件总线)的方式进行平辈组件之间的传值。创建一个工具类bus.js,用于实现全局的事件监听和触发。例如:
   import Vue from 'vue';
   export default new Vue();

  • 在发送数据的组件中,通过触发bus的事件将数据传递出去。例如:

   <template>
     <div>
       <button @click="sendDataToBrother">点击传值给兄弟组件</button>
     </div>
   </template>

   <script>
   import bus from './bus.js';
   export default {
     data() {
       return {
         str3: 'list 给兄弟的数据',
       };
     },
     methods: {
       sendDataToBrother() {
         bus.$emit('change', this.str3);
       },
     },
   };
   </script>

  • 在接收数据的组件中,通过监听bus的事件来接收数据。例如:
   <template>
     <div>{{ str3 }}</div>
   </template>

   <script>
   import bus from './bus.js';
   export default {
     data() {
       return {
         str3: '',
       };
     },
     mounted() {
       bus.$on('change', (value) => {
         this.str3 = value;
       });
     },
   };
   </script>

二、Vue3 中的组件传值方式

在 Vue3 中,组件传值的方式与 Vue2 有一些相似之处,但也有一些新的特性和变化。

(一)父传子

  1. props传值
    • 与 Vue2 类似,在父组件中通过属性绑定将数据传递给子组件,子组件通过props接收数据。例如:
   <template>
     <div>
       <child :data="parentData"></child>
     </div>
   </template>

   <script>
   import child from './child.vue';
   export default {
     components: { child },
     data() {
       return {
         parentData: '父组件的数据',
       };
     },
   };
   </script>

   <template>
     <div>{{ data }}</div>
   </template>

   <script>
   export default {
     props: {
       data: {
         type: String,
         default: '',
       },
     },
   };
   </script>

  1. provideinject
    • 在 Vue3 中,可以使用provideinject来实现跨层级的组件传值。例如:
   <template>
     <div>
       <child></child>
     </div>
   </template>

   <script>
   import child from './child.vue';
   export default {
     components: { child },
     provide() {
       return {
         parentData: '父组件提供的数据',
       };
     },
   };
   </script>

   <template>
     <div>{{ injectedData }}</div>
   </template>

   <script>
   export default {
     inject: ['parentData'],
     data() {
       return {
         injectedData: '',
       };
     },
     mounted() {
       this.injectedData = this.parentData;
     },
   };
   </script>

(二)子传父

  1. 自定义事件传值
    • 和 Vue2 类似,在子组件中通过触发自定义事件将数据传递给父组件。例如:

   <template>
     <div>
       <button @click="sendDataToParent">点击传值给父组件</button>
     </div>
   </template>

   <script>
   import { defineComponent } from 'vue';
   export default defineComponent({
     methods: {
       sendDataToParent() {
         this.$emit('change', '子组件的数据');
       },
     },
   });
   </script>

   <template>
     <div>
       <child @change="receiveDataFromChild"></child>
       {{ parentData }}
     </div>
   </template>

   <script>
   import child from './child.vue';
   import { defineComponent } from 'vue';
   export default defineComponent({
     components: { child },
     data() {
       return {
         parentData: '',
       };
     },
     methods: {
       receiveDataFromChild(value) {
         this.parentData = value;
       },
     },
   });
   </script>

  1. 使用ref获取子组件实例
    • 在 Vue3 中,可以使用ref来获取子组件的实例,从而直接访问子组件的数据和方法。例如:

   <template>
     <div>
       <child ref="childRef"></child>
       <button @click="getChildData">获取子组件数据</button>
       {{ parentData }}
     </div>
   </template>

   <script>
   import child from './child.vue';
   import { defineComponent, ref } from 'vue';
   export default defineComponent({
     components: { child },
     data() {
       return {
         parentData: '',
       };
     },
     setup() {
       const childRef = ref(null);
       const getChildData = () => {
         if (childRef.value) {
           this.parentData = childRef.value.childData;
         }
       };
       return {
         childRef,
         getChildData,
       };
     },
   });
   </script>

   <template>
     <div>{{ childData }}</div>
   </template>

   <script>
   import { defineComponent } from 'vue';
   export default defineComponent({
     data() {
       return {
         childData: '子组件的数据',
       };
     },
   });
   </script>

(三)平辈之间传值

  • 在 Vue3 中,平辈之间的传值仍然可以使用事件总线或者状态管理工具(如PiniaVuex)。

使用事件总线的方式与 Vue2 类似,创建一个全局的事件总线对象,在需要传值的组件中触发事件,在接收数据的组件中监听事件。

例如:

// bus.js
import { createApp } from 'vue';
export const bus = createApp({});

<template>
  <div>
    <button @click="sendDataToBrother">点击传值给兄弟组件</button>
  </div>
</template>

<script>
import { bus } from './bus.js';
export default {
  methods: {
    sendDataToBrother() {
      bus.$emit('change', '数据 from 组件 A');
    },
  },
};
</script>

<template>
  <div>{{ receivedData }}</div>
</template>

<script>
import { bus } from './bus.js';
export default {
  data() {
    return {
      receivedData: '',
    };
  },
  mounted() {
    bus.$on('change', (value) => {
      this.receivedData = value;
    });
  },
};
</script>

三、总结

组件传值在 Vue 应用开发中是非常重要的环节。无论是 Vue2 还是 Vue3,都有多种方式实现组件之间的数据传递。在实际开发中,应根据具体的业务需求和项目结构选择合适的传值方式,以保证代码的可维护性和可读性。同时,随着 Vue 的不断发展,新的特性和工具也为组件传值提供了更多的选择和优化的可能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值