Vue3组件通信概览

组件通信分为树组件跨组件通信

树组件就是有直接关联关系的组件,比如:父子组件、祖孙组件

跨组件没有关联关系的组件:在层级较深的组件调用顶级的组件,比如某个组件传值定义在App.vue里面的组件,比如全局弹窗组件

组件树通信有:

props/emit

父组件

<template>
  <div class="home">
    <user-card :user="user" @update-user="updateUser" />
  </div>
</template>
​
<script setup>
import { ref } from 'vue'
import userCard from '@/components/userCard.vue'
const user = ref({
  username: '张三',
  age: 18
})
const updateUser = (data) => {
  user.value = {
    ...user.value,
    ...data
  }
}
</script>

子组件

<template>
  <div class="user-card">
    <h2>用户信息</h2>
    <p>姓名:{{ user.username }}</p>
    <p>年龄:{{ user.age }}</p>
    <div class="info">
      <button @click="$emit('updateUser', { username: 'Alan', age: 23 })">修改用户信息</button>
    </div>
  </div>
</template>
​
<script setup>
defineProps({
  user: {
    type: Object,
    default: () => {}
  }
})
</script>

proive/inject和emit

父组件

<template>
  <div class="home">
    <user-card @updateUser="updateUser" />
  </div>
</template>
​
<script setup>
import { ref, provide } from 'vue'
import userCard from '@/components/userCard.vue'
const user = ref({
  username: '张三',
  age: 18
})
const updateUser = (data) => {
  user.value = {
    ...user.value,
    ...data
  }
}
provide('user', user)

子组件

<template>
  <div class="user-card">
    <h2>用户信息</h2>
    <p>姓名:{{ user.username }}</p>
    <p>年龄:{{ user.age }}</p>
    <div class="info">
      <button @click="$emit('updateUser', { username: 'Alan', age: 23 })">修改用户信息</button>
    </div>
  </div>
</template>
​
<script setup>
import { inject } from 'vue'
​
const user = inject('user', { username: 'xxx', age: 12 })
</script>

proive/inject和mitt

安装import mitt from 'mitt'

utils/emitter.js

import mitt from 'mitt'
const emitter = mitt()
export default emitter
父组件
<template>
  <div class="home">
    <user-card />
  </div>
</template>
​
<script setup>
import { ref, provide, onMounted, onUnmounted } from 'vue'
import userCard from '@/components/userCard.vue'
import emitter from '@/utils/mitter'
const user = ref({
  username: '张三',
  age: 18
})
onMounted(() => {
  emitter.on('updateUser', (data) => {
    user.value = {
      ...user.value,
      ...data
    }
  })
})
onUnmounted(() => {
  emitter.off('updateUser')
})
​
provide('user', user)
</script>

子组件

<template>
  <div class="user-card">
    <h2>用户信息</h2>
    <p>姓名:{{ user.username }}</p>
    <p>年龄:{{ user.age }}</p>
    <div class="info">
      <button @click="updateUser">修改用户信息</button>
    </div>
  </div>
</template>
​
<script setup>
import { inject } from 'vue'
import emitter from '@/utils/mitter'
const user = inject('user', { username: 'xxx', age: 12 })
const updateUser = () => {
  emitter.emit('updateUser', { username: 'Alan', age: 23 })
}
</script>
跨组件通信

使用mitt

使用mitt里面的on、emit、off等方法,组件树里面有介绍

使用pinia

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

A组件

<template>
  <div class="home">
    <h1>数值是:{{ useCounter.count }}</h1>
  </div>
</template>

<script setup>
import { useCounterStore } from '@/stores/counter'
const useCounter = useCounterStore()
</script>

B组件

<template>
  <div class="user-card">
    <h2>数值变化</h2>
    <div class="info">
      <button @click="useCounter.increment()">+1</button>
    </div>
  </div>
</template>

<script setup>
import { useCounterStore } from '@/stores/counter'
const useCounter = useCounterStore()
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值