vue3组件通信详解

vue3组件通信方式有以下几种:porps,$emit, bus,v-model,useAttrs,$ref/$parent,provide/inject,pinia,slot。下面将逐一讲解。

  

目录

1.porps:实现父子组件通信,子组件接收的数据还是只读 

2.$emit

3.全局事件总线 $bus,使用mitt

4.v-model传值

5. $attrs/useAttrs:获取组件标签身上属性与事件

6.$ref/$parent

7.provide/inject

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

9.slot 插槽分为默认插槽、具名插槽、作用域插槽(可以传递数据的插槽,子组件可以将数据回传给父组件的插槽)


 

1.porps:实现父子组件通信,子组件接收的数据还是只读

父组件中,引入子组件并给子组件绑定一个money参数






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





示例

vue3组件通信详解_第1张图片

2.$emit

说到$emit就要说一下自定义事件,在vue框架中事件分为两种:一种是原生的DOM事件,另外一种自定义事件。原生DOM事件可以让用户与网页进行交互,比如click、dbdlick、change、mouseenter、mouseleave...自定义事件可以实现子组件给父组件传递数据。vue2中的@click绑定的是自定义事件 ,可以通过.native修饰符变为原生DOM事件 。vue3中绑定的是原生事件,利用defineEmits方法返回函数触发自定义事件,不需要引入,直接使用。

父组件






子组件





 示例:

vue3组件通信详解_第2张图片

3.全局事件总线 $bus,使用mitt

Mitt是一个小巧的JavaScript发布-订阅库,用于在应用程序中实现事件监听和触发。

安装:npm install mitt -S

在src目录下新建bus文件夹,bus文件夹下新建index.ts

vue3组件通信详解_第3张图片

// 引入mitt插件  index.ts
import mitt from "mitt" 

const $bus = mitt();
export default $bus 

 接收组件:引入上面新建的bus,$bus.on  接收将来兄弟组件传递的数据





发送组件:$bus.emit 使用发送  




示例:

vue3组件通信详解_第4张图片

4.v-model传值

在vue2中v-model绑定了一个value值,和input事件,并且只能绑定一个v-model。

而在vue3中给子组件传递一个porps,并且绑定了一个自定义事件。

此处有两种用法,方法一 

 porps + @update:money 代表自定义事件。代码如下:

 父组件代码:




子组件




vue3组件通信详解_第5张图片

 方法二

1.相当于给子组件传递一个porps[modelValue]=666666 (一定叫modelValue)

2.相当于给子组件绑定了一个自定义事件,事件名一定是 update:modelValue,父组件不用自己写自定义事件

父组件代码




子组件:

注意:以v-model="money3"的形式传递时,使用defineProps 接收名字只能叫modelValue,默认写法。

传多个值时,父组件 以v-model:参数名="参数名" 形式传递,defineProps 接收名字就是参数名。

更改数据使用defineEmits,默认方式更改值 事件名字只能叫 “update:modelValue”,

更改指定名字的值时 事件名字 是 “update:参数名”




 vue3组件通信详解_第6张图片

5. $attrs/useAttrs:获取组件标签身上属性与事件

父组件




子组件: 

在 

示例 

vue3组件通信详解_第7张图片

6.$ref/$parent

ref:可以获取真实的DOM节点,可以获取子组件实例的VC

$parent:可以在子组件内部获取到父组件的实例

组件内部的数据对外是关闭的,不能直接访问。需要使用defineExpose对外暴露




子组件




示例

vue3组件通信详解_第8张图片

vue3组件通信详解_第9张图片

7.provide/inject

  1. vue3提供 provide (提供)与 inject (注入),事件隔辈组件数据传递。

  2. 父组件提供数据(provide)需要两个参数:
    第一个参数就是提供数据的key
    第二个参数是提供的数据

  3. 注入祖先组件提供的数据:提供的key

  4. inject获取的数据是指向同一个对象,可以进行修改




子组件




孙子组件




示例 

vue3组件通信详解_第10张图片

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

   Pinia | Pinia官网

 核心概念 state mutations actions getters modules

 pinia 核心概念 state actions getters

 pinia分为两种写法,选择式api 写法=>类似与vuex 和组合式api写法

8.1.安装

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

8.2.新建store文件夹,如下,分为两个模块讲解 选择式api写法 与 组合式api写法

vue3组件通信详解_第11张图片

8.3.index.ts 

// 创建大仓库 index.ts
import { createPinia } from 'pinia'

// createPinia
let store =createPinia();
// 对外暴露
export default store

8.4.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')

8.5.user.ts 选择式api写法

// 定义user仓库  选择式api写法   user.ts
import { defineStore } from "pinia";

// defineStore传入两个参数 第一个是小仓库的名字,第二个是小仓库配置对象。
// defineStore方法执行会返回一个函数,函数作用就是让组件可以获取到仓库的数据
let userStore = defineStore("user", {
    //  存储数据:state
    state: () => {
        return {
            name: "梅赛德斯",
            arr: [12, 234, 23434, 34534]
        }
    },
    actions: {
        // 注意函数没有context上下文对象,没有commit 没有mutation去修改数据 
        // 此处使用this就是小仓库对象--- 此处不能使用箭头函数
        updateName(value: string) {
            this.name = value
        }
    },
    getters: {
        totalMoney() {
            let M: any = this.arr.reduce((prev: number, next: number) => {
                return prev + next
            }, 0)
            return M
        }

    }
})

export default userStore

 8.6.info.ts 组合式api写法

// 定义info仓库  组合式api写法 info.ts
import { defineStore } from "pinia";
import { ref, computed } from "vue"

let infoStore = defineStore("info", () => {
    // 此处的箭头函数务必返回一个对象,属性与方法提供给组件使用
    // 主要用到了vue3中的组合式API函数
    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

使用:



示例

vue3组件通信详解_第12张图片

9.slot 插槽分为默认插槽、具名插槽、作用域插槽(可以传递数据的插槽,子组件可以将数据回传给父组件的插槽)

9.1 默认插槽 -父组件




 

子组件



 

vue3组件通信详解_第13张图片

 9.2 具名插槽 -父组件




 

子组件



 

vue3组件通信详解_第14张图片

  9.3 作用域插槽 -父组件




 

子组件



 

示例 

vue3组件通信详解_第15张图片

以上是总结的所有通信方式 

你可能感兴趣的:(vue3,vue.js,前端,javascript,vue3)