Vue2基础-Vue2.x 父子组件数据通信 Prop 和 Event

父子组件间通信

vue 提供了prop实现父组件向子组件传递数据,提供emit实现子组件向父组件回传数据。

组件参数传递 prop

【组件创建使用示例】
在该示例的HelloWorld组件中我们接收了msg数据,然后在使用组件时可以传入指定的msg数据。

// 定义组件
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
};
</script>

// 使用组件
<HelloWorld
      ref="helloWorld1"
      msg="第二个 HelloWorld"
      @on-msg-click="onMsgClick"
    />

下面是使用prop时的可选的一些参数,推荐在写prop是将信息描述完整。如:是否必填,是否有默认值等

 props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }

prop里面的type可以传递那些类型的数据呢?

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol
  • 额外的,它还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级prop 的更新会向下流动到子组件中,但是反过来则不推荐。因为这样会使得子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

重要PS:

比如在子组件更新了父组件里的对象属性,从而导致页面显示效果不一致。故推荐在更新子组件数据时必须从父组件去更新

额外的,每次父级组件发生变更时,子组件中所有的prop都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

子组件需要更新数据如何处理

前面我们也推荐了必须从父组件去更新子组件的数据,但是有的时候业务很变态,需要在子组件里面修改prop的数据,我们该如何做呢?

我们可以在computed函数里面定义内部的数据接收prop传递过来的值,然后改变的就是该组件computed内部定义的值即可。伪代码如下:

<template>
  <div class="hello">
    <h2>counter: {{ counter }}</h2>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    initialCounter: {
      type: Number,
      default: 0,
    },
  },
  computed: {
    counter() {
      return this.initialCounter;
    },
  }
};
</script>

我们传入的是initialCounter,然后赋值给计算属性的counter字段,后续在组件中即可使用counter做修改。

有时候我们需要从子组件传递数据给父组件,那么可以通过emit事件来实现。

监听子组件事件 emit

组件创建使用示例
示例中我们通过点击子组件中的msg信息传递数据给父组件,并在console中打印结果。
伪代码示例如下:
在子组件定义处理点击事件,然后通过$emit将数据发送给父组件

<template>
  <div class="hello">
    <h1 @click="handleData">{{ msg }}</h1>
  </div>
</template>

methods: {
    handleData() {
      this.$emit("on-msg-click", "点击msg传递的数据");
    },
  },

父组件中接收并处理的代码如下:

 <HelloWorld
      ref="helloWorld1"
      msg="第二个 HelloWorld"
      @on-msg-click="onMsgClick"
    />
methods: {
    onMsgClick(msg) {
      console.log(msg);
    },
   
  },

官方推荐我们在this.$emit(‘事件名’,数据)的事件名始终使用 kebab-case 格式。

我们已经知道父子组件间如何通信,但是很多时候我们需要在多个组件以及没有父子关系的组件间通信,官方及社区提供了很多的解决方案。比如EventBusVuex.

多层级组件间通信

如果我们使用vue提供的propemit实现会很麻烦,需要层层嵌套。下篇文章介绍EventBusVuex两种方式实现。

源码示例

组件创建使用示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_龙衣

赏杯快乐水喝喝

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

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

打赏作者

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

抵扣说明:

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

余额充值