vue3组件常用的通信方式

本文介绍了在Vue3中,如何通过props实现父子组件的数据传递,$emit处理自定义事件以及如何使用pinia进行状态管理,以实现不同组件之间的通信

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue3组件常用的通信方式(父传子、子传父、pinia)

1.porps:实现父子组件通信,子组件接收的数据还是只读
父组件中,引入子组件并给子组件绑定一个money参数

<template>
  <div id="app"> 
    <h1>父组件</h1>
    <h3>富一代资产{{ money }}元</h3>
    <index1 :money="money"></index1>
  </div>
</template>
 
<script lang="ts" setup>
 
  import index1 from './view/index.vue'
  import { ref } from 'vue'
 
  let money = ref(1000000000000)
 
</script>
 
<style scoped>
#app {
  width: 100vw;
  height: 100vh;
  color: #000;
  padding: 50px;
  box-sizing: border-box;
}
</style>

子组件中,使用defineProps接收,在template中,可以直接使用money,

<template>
  <div class="index1">
    <h1>子组件1</h1>
    <h3>儿子不知道父亲有{{ porps.money }}元</h3> 
     <h3>
      儿子知道了{{ money }}元
    </h3>
  </div>
</template>
 
<script setup lang="ts">
  import { ref } from 'vue'
 
  const porps = defineProps(['money'])
  console.log(porps)
 
</script>
 
<style lang="scss" scoped>
.index1 {
  background-color: azure;
  padding: 12px;
}
</style>

2.$emit
在vue框架中事件分为两种:一种是原生的DOM事件,另外一种自定义事件。原生DOM事件可以让用户与网页进行交互,比如click、dbdlick、change、mouseenter、mouseleave...自定义事件可以实现子组件给父组件传递数据。

父组件

<template>
  <div id="app"> 
    <h1>父组件</h1>
    <h3>富一代资产{{ money }}元</h3>
    <index1 :money="money" @xxx="handlerXXX"></index1>
    <h3>{{ son }}</h3>    
  </div>
</template>
 
<script lang="ts" setup>
 
  import index1 from './view/index.vue'
  import { ref } from 'vue'
 
  let money = ref(1000000000000)
  let son = ref('')
  const handlerXXX = (value: string) => {
    son.value = value
  }
 
</script>
 
<style scoped>
#app {
  width: 100vw;
  height: 100vh;
  color: #000;
  padding: 50px;
  box-sizing: border-box;
}
</style>

子组件

<template>
  <div class="index1">
    <h1>子组件1</h1>
    <h3>儿子不知道父亲有{{ porps.money }}元</h3> 
     <h3>
      儿子知道了{{ money }}元
    </h3>
     <el-button @click="handlerClick">自定义事件</el-button>
  </div>
</template>
 
<script setup lang="ts">
  import { ref } from 'vue'
  
  const porps = defineProps(['money'])
  console.log(porps)
 
  
  const $emit = defineEmits(['xxx'])
  const handlerClick = () => {
    console.log('触发事件')
    $emit('xxx', '富二代上交9999元给富一代') 
  }
 
</script>
 
<style lang="scss" scoped>
.index1 {
  background-color: azure;
  padding: 12px;
}
</style>

3.pinia :集中管理状态容器,可以实现任意组件之间的通信

需先安装

npm install pinia
# 或者使用 yarn 
yarn add pinia

新建store文件夹作为共享仓库 对仓库进行配置

// 创建仓库 index.ts
import { createPinia } from 'pinia'
 
// createPinia
let store =createPinia();
export default store

main.js  : 引入 "./store"

import { createApp } from 'vue'
import App from "@/App.vue"
import "@/assets/style/common.scss"
 
import store from "./store"
 
const app = createApp(App)
 
app.use(store)
 
app.mount('#app')

定义仓库


import { defineStore } from "pinia";
import { ref, computed } from "vue"
 
let infoStore = defineStore("info", () => {
   
    let num = ref(34233)
    const updateNum = (value: number) => {
        num.value = value
    }
    const newNum = computed(() => {
        return num.value * 1000
    })
    return {
        num,
        newNum,
        updateNum
    }
})
export default infoStore

使用示例

<template>
  <div class="index7">
    <h1>子组件7</h1>
    <h3>名字:{{ userInfo.name }}</h3>
    <h3>{{ userInfo.totalMoney }}</h3>
    <h4>组合式api:{{ info.num }}</h4>
    <h4>组合式api使用计算属性:{{ info.newNum }}</h4>
    <el-button @click="changeName">点击改名字</el-button>
    <el-button @click="changeInfo">点击改num</el-button>
  </div>
</template>
<script setup lang="ts">
import userStore from '@/store/modules/user' 
import infoStore from '@/store/modules/info'

let userInfo = userStore()
 
const changeName = () => {
  userInfo.updateName('库里南')
}
 
let info = infoStore()
console.log(info)
 
const changeInfo = () => {
  info.updateNum(77777)
}
</script>
<style lang="scss" scoped>
.index7 {
  background-color: rgb(115, 244, 175);
  padding: 12px;
  margin: 12px 0;
}
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值