【Vue2】组件通信

本文详细解释了Vue中的父子组件通信机制,包括props和emit的使用,单向数据流原则,以及如何通过v-model、sync、$parents、$children、事件总线、provide/inject和Vuex进行数据交互和管理。还讨论了router对URL变化的响应和store模式的优缺点。
摘要由CSDN通过智能技术生成

在这里插入图片描述

父子通信

props 和 emit

父 -> 子

在这里插入图片描述

子 -> 父

在这里插入图片描述

props: {
  校验的属性名: {
    type: 类型,  // Number String Boolean ...
    required: true, // 是否必填
    default: 默认值, // 默认值
    validator (value) {
      // 自定义校验逻辑
      return 是否通过校验
    }
  }
},
  • data 的数据是自己的 → 随便改
  • prop 的数据是外部的 → 不能直接改,要遵循 单向数据流
  • 子组件不能直接修改父组件的数据

style 和 class

子组件的根元素可以合并自身的和父元素传递过来的 class 和 style

  <div class="son" style="color: chartreuse">
    <h1>{{msg}}</h1>
    <button @click="changeMsg">我是子组件,我要修改父组件的内容</button>
  </div>
<Son style="margin-top: 20px" class="father" :msg="msg" @changeMsg="handleChange"/>

在这里插入图片描述

attribute

父组件传递一些属性到子组件中,但是子组件并没有声明这些属性,则它们成为 attribute ,这些属性直接附在子元素的根元素上。

不包括 class 和 style ,处理机制不同

  <Son
      data-a="123"
      b-c="234"
  />

然后在子组件中通过 this.$attrs 获取父组件传递过来的属性。

在这里插入图片描述

当然,子组件可以通过 inheritAttrs: false 进行配置,禁止将 attribute 附在子组件的根元素上,但仍然可以通过 $attrs 获取。

在这里插入图片描述

native 修饰符

  <Son
      @click.native="handleClick"
  />
  handleClick(){
      console.log(1)
  }

此时父组件的事件会直接挂载到子组件的根元素上,所以点击子组件根div 会打印 1 。

listeners

子组件可以通过 $listeners 获取父组件传递过来的所有事件处理函数。

v-model

双向数据绑定。

sync 修饰符

类似于 v-model。 那么区别是什么呢?先看一个例子:

<template>
  <div>
    <button @click="$emit(`update:num1`, num1 - 1)"> - </button>
    {{num1}}
    <button @click="$emit(`update:num1`, num1 + 1)"> + </button>
    <button @click="$emit(`update:num2`, num2 - 1)"> - </button>
    {{num2}}
    <button @click="$emit(`update:num2`, num2 + 1)"> + </button>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'Son',
  props: ['num1', 'num2'],
  methods: {

  }
}
</script>

<style scoped>

</style>
<template>
  <Son
      :num1="n1"
      :num2="n2"
      @update:num1="n1 = $event"
      @update:num2="n2 = $event"
  />
</template>

<script>
import Son from './components/Son.vue'

export default {
  name: 'App',
  components: {
    Son
  },
  data(){
    return {
      n1: 1,
      n2: 2
    }
  },
  created() {
    console.log(this.$listeners)
  },
  methods: {
    handleClick(){
      console.log(1)
    }
  }
}
</script>

<style>

</style>

通过父组件的两个事件控制子组件数据和视图变化。

而 sync 的作用就是:

  <Son
      :num1.sync="n1"
      :num2.sync="n2"
  />

相当于简化书写,但格式有规定。

$parent$children

用于获取当前组件的父组件和子组件。

注意:子组件挂载之后才可以访问到。

子组件可以直接修改父组件的数据。

$slots$scopedSlots

ref

父组件获取子组件的实例。

子组件挂载之后才可以访问(获取)到。

<template>
  <Son
      :num1.sync="n1"
      :num2.sync="n2"
      ref="son"
  />
</template>

<script>
import Son from './components/Son.vue'

export default {
  name: 'App',
  components: {
    Son
  },
  data(){
    return {
      n1: 1,
      n2: 2
    }
  },
  mounted() {
    console.log(this.$refs.son)
  },
  methods: {

  }
}
</script>

<style>

</style>

跨组件通信

事件总线 event bus

  1. 创建一个都能访问的事件总线 (空Vue实例)

    import Vue from 'vue'
    const Bus = new Vue()
    export default Bus
    
  2. A组件(接受方),监听Bus的 $on事件

    created () {
      Bus.$on('sendMsg', (msg) => {
        this.msg = msg
      })
    }
    
  3. B组件(发送方),触发Bus的$emit事件

    Bus.$emit('sendMsg', '这是一个消息')
    

在这里插入图片描述

provide 和 inject

  1. 父组件 provide提供数据
export default {
  provide () {
    return {
       // 普通类型【非响应式】
       color: this.color, 
       // 复杂类型【响应式】
       userInfo: this.userInfo, 
    }
  }
}

2.子/孙组件 inject获取数据

export default {
  inject: ['color','userInfo'],
  created () {
    console.log(this.color, this.userInfo)
  }
}
  • provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式。(推荐提供复杂类型数据)
  • 子/孙组件通过inject获取的数据,不能在自身组件内修改

router

一个组件改变了地址栏,其他监听地址栏的组件都会做出反应。

比如点击 router-link 组件改变了地址,router-view 组件就渲染其他内容。

vuex

数据仓库。

store 模式

缺点就是难以跟踪数据变化。

// store.js
const store = {
    loginUser: ...,
    settings: ...
}
// compA
const compA = {
    data(){
        return {
            store.loginUser
        }
    }
}

data 里面的数据都是响应式(递归响应)

Vue 2 中,父子组件之间的通信可以通过 Props 和事件来实现。 1. 使用 Props:父组件可以通过 Props 将数据传递给子组件。在父组件中定义一个属性,并将其绑定到子组件上,子组件可以直接访问和使用这些属性。 父组件: ```html <template> <div> <child-component :message="message"></child-component> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { message: 'Hello from parent' }; } }; </script> ``` 子组件: ```html <template> <div> <p>{{ message }}</p> </div> </template> <script> export default { props: ['message'] }; </script> ``` 2. 使用事件:子组件可以通过触发事件的方式将数据传递给父组件。在子组件中使用 $emit 方法触发一个自定义的事件,并将需要传递的数据作为参数。 父组件: ```html <template> <div> <child-component @message-updated="updateMessage"></child-component> <p>{{ message }}</p> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { message: '' }; }, methods: { updateMessage(message) { this.message = message; } } }; </script> ``` 子组件: ```html <template> <div> <button @click="sendMessage">Send Message</button> </div> </template> <script> export default { methods: { sendMessage() { this.$emit('message-updated', 'Hello from child'); } } }; </script> ``` 这样,父组件就能够接收到子组件发送的数据,并进行相应的处理。通过 Props 和事件的组合使用,可以实现灵活的父子组件通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秀秀_heo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值