初识Vue-组件通信(详解props和emit)

24 篇文章 0 订阅
12 篇文章 0 订阅

目录

一、组件通信介绍

1.概念

2.作用

3.特点

4.应用

二、组件通信语法

1.Props

1.1.在子组件中声明 props

1.2.在父组件中传递数据

2.Emit

2.1.在子组件中触发事件

2.2.在父组件中监听事件

三、应用实例

1. 购物车组件

2. 表单数据处理

 四、总结


一、组件通信介绍

1.概念

在组件化开发中,一个应用程序通常由多个组件组成。这些组件可能位于不同的层级,有不同的作用和责任。组件通信就是让这些组件之间能够相互交流、传递数据、共享状态或触发行为的机制。

2.作用

  1. 传递数据: 父组件可以通过props向子组件传递数据,子组件可以通过emit触发事件向父组件发送消息。
  2. 共享状态: 多个组件之间可以共享同一份状态数据,确保数据的一致性。
  3. 触发行为: 组件之间可以通过事件触发行为,实现交互功能。
  4. 管理全局状态: 使用状态管理工具(如Vuex)进行全局状态的管理和同步。

3.特点

  1. 解耦性: 组件通信可以将各个组件解耦,使它们能够独立开发、测试和维护。
  2. 灵活性: 可以根据具体需求选择不同的通信方式,如props / emit、$emit / $on、Vuex等,从而灵活应对各种场景。
  3. 可重用性: 合理的组件通信设计可以增强组件的可重用性,提高开发效率。
  4. 状态管理: 可以通过组件通信实现状态的管理,让不同组件共享同一份状态数据。

4.应用

  1. 父子组件通信: 通过props和emit实现父子组件之间的通信,传递数据和触发事件。
  2. 兄弟组件通信: 通过共同的父组件或使用事件总线(如Vue的$emit / $on或自定义事件总线)实现兄弟组件之间的通信。
  3. 跨层级通信: 使用事件总线或状态管理工具(如Vuex)实现跨层级组件之间的通信。
  4. 全局状态管理: 使用状态管理工具(如Vuex)管理应用程序的全局状态,确保各个组件之间的状态同步和一致性。

二、组件通信语法

1.Props

Props 是一种机制,用于父组件向子组件传递数据。子组件通过在其标签上声明 props 来接收来自父组件的数据。在父组件中,可以使用子组件标签上的属性来传递数据。

1.1.在子组件中声明 props
<script>
export default {
  props: ['message']
};
</script>
1.2.在父组件中传递数据
<ChildComponent message="Hello from parent" />

2.Emit

Emit 是一种机制,用于子组件向父组件发送消息或数据。子组件通过调用 emit 方法触发一个事件,并传递需要发送的数据。父组件通过在子组件标签上监听事件来接收数据。

2.1.在子组件中触发事件
<script>
export default {
  methods: {
    sendMessage() {
      this.$emit('notify', 'Hello from child');
    }
  }
};
</script>
2.2.在父组件中监听事件
<ChildComponent @notify="handleNotify" />

这样,父组件就可以在 handleNotify 方法中接收来自子组件的消息了。

三、应用实例

1. 购物车组件

父组件:商品列表组件

<template>
  <div>
    <ProductItem v-for="product in products" :key="product.id" :product="product" @remove="removeProduct" />
    <ShoppingCart :items="cartItems" @checkout="checkout" />
  </div>
</template>

<script>
import ProductItem from './ProductItem.vue';
import ShoppingCart from './ShoppingCart.vue';

export default {
  components: {
    ProductItem,
    ShoppingCart
  },
  data() {
    return {
      products: [...], // 商品列表数据
      cartItems: []   // 购物车中的商品列表
    };
  },
  methods: {
    removeProduct(productId) {
      // 从购物车中移除商品
      this.cartItems = this.cartItems.filter(item => item.id !== productId);
    },
    checkout() {
      // 处理结账逻辑
      // 可以向后端提交订单数据等
    }
  }
};
</script>

子组件:购物车组件

<template>
  <div>
    <div v-for="item in items" :key="item.id">
      <span>{{ item.name }}</span>
      <button @click="removeItem(item.id)">Remove</button>
    </div>
    <button @click="checkout">Checkout</button>
  </div>
</template>

<script>
export default {
  props: ['items'],
  methods: {
    removeItem(itemId) {
      this.$emit('remove', itemId); // 触发从购物车中移除商品的事件
    },
    checkout() {
      this.$emit('checkout'); // 触发结账事件
    }
  }
};
</script>

2. 表单数据处理

父组件:表单组件

<template>
  <div>
    <InputField v-model="formData.username" label="Username" />
    <InputField v-model="formData.password" label="Password" type="password" />
    <SubmitButton @submit="submitForm" />
  </div>
</template>

<script>
import InputField from './InputField.vue';
import SubmitButton from './SubmitButton.vue';

export default {
  components: {
    InputField,
    SubmitButton
  },
  data() {
    return {
      formData: {
        username: '',
        password: ''
      }
    };
  },
  methods: {
    submitForm() {
      // 处理表单提交逻辑
      // 可以将 formData 发送到后端进行验证
    }
  }
};
</script>

子组件:InputField 组件

<template>
  <div>
    <label>{{ label }}</label>
    <input v-model="value" :type="type" />
  </div>
</template>

<script>
export default {
  props: ['value', 'label', 'type'],
  computed: {
    inputValue: {
      get() {
        return this.value;
      },
      set(newValue) {
        this.$emit('input', newValue); // 触发输入事件,更新父组件中的 formData
      }
    }
  }
};
</script>

子组件:SubmitButton 组件

<template>
  <button @click="submit">Submit</button>
</template>

<script>
export default {
  methods: {
    submit() {
      this.$emit('submit'); // 触发提交事件,通知父组件提交表单
    }
  }
};
</script>
  1. Props:

    • Props允许父组件向子组件传递数据。父组件通过Props属性将数据传递给子组件,在子组件中可以直接使用这些数据进行渲染或其他操作。
    • 在示例中,商品列表组件通过Props将商品数据传递给购物车组件,使购物车组件能够显示正确的商品信息。
  2. Emit:

    • Emit允许子组件向父组件发送消息。子组件可以使用$emit方法触发一个事件,并将需要传递给父组件的数据作为参数传递给该事件。
    • 在示例中,购物车组件通过$emit触发了“remove”和“checkout”事件,父组件可以监听这些事件并执行相应的操作,比如从购物车中移除商品或处理结账逻辑。

 四、总结

  1. Props:

    • Props 允许父组件向子组件传递数据。
    • 子组件通过 props 接收父组件传递的数据,并可以在组件内部使用这些数据。
    • 父组件使用 v-bind 指令将数据传递给子组件,并在子组件标签上使用相应的 prop 名称。
  2. Custom Events (自定义事件):

    • Custom Events 允许子组件向父组件发送消息。
    • 子组件使用 $emit 方法触发一个事件,并可以传递数据作为参数。
    • 父组件使用 v-on 指令监听子组件触发的事件,并在事件处理程序中处理数据。
  3. $emit 方法:

    • $emit 方法用于触发一个自定义事件。
    • 它接受两个参数:事件名称和要传递给事件处理程序的数据。
  4. v-model 指令:

    • v-model 指令用于在表单输入元素上创建双向数据绑定。
    • 它实质上是语法糖,结合了对值的绑定和对 input 事件的监听。
  5. $refs:

    • $refs 提供对子组件的直接访问。
    • 它可以用来访问子组件的属性和方法,但不推荐在父组件中过度使用。
  • 31
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值