vue组件间通信的13种方式

前言

vue是数据驱动视图更新的框架, 我们平时开发,都会把页面不同模块拆分成一个一个vue组件, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢?

首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易理解他们的通信方式。

一般我们分为如下关系:

  • 父子组件之间通信
  • 非父子组件之间通信(兄弟组件、隔代关系组件等)

1.props / $emit

父组件通过props的方式向子组件传递数据,而通过$emit 子组件可以向父组件通信。

  1. 父组件向子组件传值
<!-- 父组件 -->
<template>
  <div class="section">
    <child :msg="articleList"></child>
  </div>
</template>

<script>
import child from './child.vue'
export default {
  name: 'HelloWorld',
  components: { comArticle },
  data() {
    return {
      msg: '阿离王'
    }
  }
}
</script>
<!-- 子组件 child.vue -->
<template>
  <div>
    {
  { msg }}
  </div>
</template>

<script>
export default {
  props: {
      msg: String
  }
}
</script>

注意:

prop 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且 prop 只读,不可被修改,所有修改都会失效并警告。

  • 第一,不应该在一个子组件内部改变 prop,这样会破坏单向的数据绑定,导致数据流难以理解。如果有这样的需要,可以通过 data 属性接收或使用 computed 属性进行转换。
  • 第二,如果 props 传递的是引用类型(对象或者数组),在子组件中改变这个对象或数组,父组件的状态会也会做相应的更新,利用这一点就能够实现父子组件数据的“双向绑定”,虽然这样实现能够节省代码,但会牺牲数据流向的简洁性,令人难以理解,最好不要这样去做。
  • 想要实现父子组件的数据“双向绑定”,可以使用 v-model.sync
  1. 子组件向父组件传值

使用 $emit 向父组件传数据,原理这样的: 父组件在子组件通过v-on监听函数并接收参数,vue框架就在子组件监听了你v-on="fn"的fn事件函数,在子组件使用$emit就能触发了,下面写个例子。

<!-- 父组件 -->
<template>
  <div class="section">
    <child :msg="articleList" @changMsg="changMsg"></child>
  </div>
</template>

<script>
import child from './child.vue'
export default {
  name: 'HelloWorld',
  components: { comArticle },
  data() {
    return {
      msg: '阿离王'
    }
  },
  methods:{
      changMsg(msg) {
          this.msg = msg
      }
  }
}
</script>
<!-- 子组件 child.vue -->
<template>
  <div>
    {
  { msg }}
    <button @click="change">改变字符串</button>
  </div>
</template>

<script>
export default {
  props: {
      msg: String
  },
  methods: {
      change(){
          this.$emit('changMsg', '阿离王带你学习前端')
      }
  }
}
</script>

2.v-model 指令

v-model 是用来在表单控件或者组件上创建双向绑定的,他的本质是 v-bindv-on语法糖,在一个组件上使用 v-model,默认会为组件绑定名为 value 的 prop 和名为 input 的事件。

当我们组件中的某一个 prop 需要实现上面所说的”双向绑定“时,v-model 就能大显身手了。有了它,就不需要自己手动在组件上绑定监听当前实例上的自定义事件,会使代码更简洁

下面以一个 input 组件实现的核心代码,介绍下 v-model 的应用。

<!--父组件-->
<template>
    <base-input v-model="inputValue"></base-input>
</template>
<script>
    export default {
        data() {
            return {
                input: ''
            }
        },
    }
</script>
<!--子组件-->
<template>
    <input type="text" :value="currentValue"  @input="handleInput">
</template>
<script>
    export default {
        data() {
            return {
                currentValue: this.value === undefined || this.value === null ? ''
            }
        },
        props: {
            value: [String, Number], // 关键1
        },
        methods: {
            handleInput(event) {
                const value = event.target.value;
                this.$emit('input', value); // 关键2
            },
        },
}
</script>

上面例子看到,v-model="inputValue" 他的本质就是 v-bind 和 v-on 的语法糖,默认为父组件绑定名为 :value="inputValue"的属性,和@input="(v) => { this.inputValue = v }"事件,子组件通过 this.$emit('input', value) 通知父组件

所以他原理也是利用了我们上面讲的父子组件传参 props / $emit 方式来实现双向绑定

有时,在某些特定的控件中名为 value 的属性会有特殊的含义,这时可以通过 v-model 选项来回避这种冲突。

3. .sync 修饰符

  • .sync 修饰符在 vue 1.x 的版本中就已经提供,1.x 版本中,当子组件改变了一个带有 .syncprop 的值时,会将这个值同步到父组件中的值。这样使用起来十分方便,但问题也十分明显,这样破坏了单向数据流,当应用复杂时,debug 的成本会非常高。
  • 于是乎,在vue 2.0中移除了 .sync。但是在实际的应用中,.sync 是有它的应用场景的,所以在 vue 2.3 版本中,又迎来了全新的 .sync
  • 新的 .sync 修饰符所实现的已经不再是真正的双向绑定,它的本质和 v-model 类似,只是一种缩写。

正常封装组件例子:

<text-document v-bind:title="doc.title" v-on:update:title="doc.title = $event" />

上面的代码,使用 .sync 就可以写成

<text-document v-bind:title.sync="doc.title" />

这样,在子组件中,就可以通过下面代码来实现对这个 prop 重新赋值了。

this.$emit('update:title', newTitle)

看到这里,是不是发现 .sync 修饰符 和 v-model 很相似,也是语法糖, v-bind:title.sync 也就是 等效于 v-bind:title="doc.title" v-on:update:title="doc.title = $event"

  • 23
    点赞
  • 133
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue是一流行的JavaScript框架,它允许您轻松地构建可重用的组件Vue组件是一个独立的功能部件,它可以通过不同的方式进行通信,以实现更好的交互和协作。以下是Vue中六常用的组件间通信方式: 1. Props Props是一用于从父组件向子组件传递数据的机制。父组件可以将数据作为属性传递给子组件,并且子组件可以通过props属性来使用这些数据。 2. Events Events是一Vue组件间通信的双向机制,它允许子组件通过触发事件来向父组件发送消息。父组件可以监听这些事件,并根据需要作出响应。 3. Provide / Inject Provide / Inject是一用于跨深度嵌套组件之间共享数据的机制。父组件可以通过provide属性将数据传递给子组件,然后子组件可以通过inject属性来访问这些数据。 4. Vuex Vuex是一Vue状态管理器,它允许您在单个应用程序中管理共享状态。Vuex包含一个中央状态存储库,可以跨组件访问和修改状态,以实现更好的协作和交互。 5. ref 属性 Ref是一用于访问组件实例的方法,它可以通过设置ref属性来指定组件的名称。然后你就可以通过$refs属性来访问该组件实例,并在组件之间进行通信。 6. $emit 和 $on $emit和$on是Vue的内置事件机制,它允许组件之间进行通信。$emit用于触发事件,而$on则用于监听事件。使用这方式,您可以轻松地在组件之间传递消息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值