Vue3的7种种组件通信详情

目录
  • 1、Vue3 组件通信方式
  • 2、Vue3 通信使用写法
    • 2.1 props
    • 2.2 $emit
    • 2.3 expose / ref
    • 2.4 attrs
    • 2.5 v-model
    • 2.6 provide / inject
    • 2.7 Vuex

1、Vue3 组件通信方式

  • props
  • $emit
  • expose / ref
  • $attrs
  • v-model
  • provide / inject
  • Vuex

2、Vue3 通信使用写法

2.1 props

props 传数据给子组件有两种方法,如下

方法一:混合写法

// Parent.vue 传送
<child :msg1="msg1" :msg2="msg2"></child>
<script>
import child from "./child.vue"
import { ref, reactive } from "vue"
export default {
    data(){
        return {
            msg1:"这是传级子组件的信息1"
        }
    },
    setup(){
        // 创建一个响应式数据

        // 写法一 适用于基础类型  ref 还有其他用处,下面章节有介绍
        const msg2 = ref("这是传级子组件的信息2")

        // 写法二 适用于复杂类型,如数组、对象
        const msg2 = reactive(["这是传级子组件的信息2"])

        return {
            msg2
        }
    }
}
</script>

// Child.vue 接收
<script>
export default {
  props: ["msg1", "msg2"],// 如果这行不写,下面就接收不到
  setup(props) {
    console.log(props) // { msg1:"这是传给子组件的信息1", msg2:"这是传给子组件的信息2" }
  },
}
</script>

方法二:纯 Vue3 写法

// Parent.vue 传送
<child :msg2="msg2"></child>
<script setup>
    import child from "./child.vue"
    import { ref, reactive } from "vue"
    const msg2 = ref("这是传给子组件的信息2")
    // 或者复杂类型
    const msg2 = reactive(["这是传级子组件的信息2"])
</script>

// Child.vue 接收
<script setup>
    // 不需要引入 直接使用
    // import { defineProps } from "vue"
    const props = defineProps({
        // 写法一
        msg2: String
        // 写法二
        msg2:{
            type:String,
            default:""
        }
    })
    console.log(props) // { msg2:"这是传级子组件的信息2" }
</script>

注意:

如果父组件是混合写法,子组件纯 Vue3 写法的话,是接收不到父组件里 data 的属性,只能接收到父组件里 setup 函数里传的属性

如果父组件是纯 Vue3 写法,子组件混合写法,可以通过 props 接收到 data setup 函数里的属性,但是子组件要是在 setup 里接收,同样只能接收到父组件中 setup 函数里的属性,接收不到 data 里的属性

官方也说了,既然用了 3,就不要写 2 了,所以不推荐混合写法。下面的例子,一律只用纯 Vue3 的写法,就不写混合写法了

2.2 $emit

// Child.vue 派发
<template>
    // 写法一
    <button @click="emit('myClick')">按钮</buttom>
    // 写法二
    <button @click="handleClick">按钮</buttom>
</template>
<script setup>
   
    // 方法一 适用于Vue3.2版本 不需要引入
    // import { defineEmits } from "vue"
    // 对应写法一
    const emit = defineEmits(["myClick","myClick2"])
    // 对应写法二
    const handleClick = ()=>{
        emit("myClick", "这是发送给父组件的信息")
    }
   
    // 方法二 不适用于 Vue3.2版本,该版本 useContext()已废弃
    import { useContext } from "vue"
    const { emit } = useContext()
    const handleClick = ()=>{
        emit("myClick", "这是发送给父组件的信息")
    }
</script>

// Parent.vue 响应
<template>
    <child @myClick="onMyClick"></child>
</template>
<script setup>
    import child from "./child.vue"
    const onMyClick = (msg) => {
        console.log(msg) // 这是父组件收到的信息
    }
</script>

2.3 expose / ref

父组件获取子组件的属性或者调用子组件方法

// Child.vue
<script setup>
    // 方法一 不适用于Vue3.2版本,该版本 useContext()已废弃
    import { useContext } from "vue"
    const ctx = useContext()
    // 对外暴露属性方法等都可以
    ctx.expose({
        childName: "这是子组件的属性",
        someMethod(){
            console.log("这是子组件的方法")
        }
    })

    // 方法二 适用于Vue3.2版本, 不需要引入
    // import { defineExpose } from "vue"
    defineExpose({
        childName: "这是子组件的属性",
        someMethod(){
            console.log("这是子组件的方法")
        }
    })
</script>

// Parent.vue  注意 ref="comp"
<template>
    <child ref="comp"></child>
    <button @click="handlerClick">按钮</button>
</template>
<script setup>
    import child from "./child.vue"
    import { ref } from "vue"
    const comp = ref(null)
    const handlerClick = () => {
        console.log(comp.value.childName) // 获取子组件对外暴露的属性
        comp.value.someMethod() // 调用子组件对外暴露的方法
    }
</script>

2.4 attrs

attrs包含父作用域里除 class style 除外的非 props 属性集合

// Parent.vue 传送
<child :msg1="msg1" :msg2="msg2" title="3333"></child>
<script setup>
    import child from "./child.vue"
    import { ref, reactive } from "vue"
    const msg1 = ref("1111")
    const msg2 = ref("2222")
</script>

// Child.vue 接收
<script setup>
    import { defineProps, useContext, useAttrs } from "vue"
    // 3.2版本不需要引入 defineProps,直接用
    const props = defineProps({
        msg1: String
    })
    // 方法一 不适用于 Vue3.2版本,该版本 useContext()已废弃
    const ctx = useContext()
    // 如果没有用 props 接收 msg1 的话就是 { msg1: "1111", msg2:"2222", title: "3333" }
    console.log(ctx.attrs) // { msg2:"2222", title: "3333" }

    // 方法二 适用于 Vue3.2版本
    const attrs = useAttrs()
    console.log(attrs) // { msg2:"2222", title: "3333" }
</script>

2.5 v-model

可以支持多个数据双向绑定

// Parent.vue
<child v-model:key="key" v-model:value="value"></child>
<script setup>
    import child from "./child.vue"
    import { ref, reactive } from "vue"
    const key = ref("1111")
    const value = ref("2222")
</script>

// Child.vue
<template>
    <button @click="handlerClick">按钮</button>
</template>
<script setup>

    // 方法一  不适用于 Vue3.2版本,该版本 useContext()已废弃
    import { useContext } from "vue"
    const { emit } = useContext()

    // 方法二 适用于 Vue3.2版本,不需要引入
    // import { defineEmits } from "vue"
    const emit = defineEmits(["key","value"])

    // 用法
    const handlerClick = () => {
        emit("update:key", "新的key")
        emit("update:value", "新的value")
    }
</script>

2.6 provide / inject

provide / inject 为依赖注入

  • provide:可以让我们指定想要提供给后代组件的数据或
  • inject:在任何后代组件中接收想要添加在这个组件上的数据,不管组件嵌套多深都可以直接拿来用
// Parent.vue
<script setup>
    import { provide } from "vue"
    provide("name", "沐华")
</script>

// Child.vue
<script setup>
    import { inject } from "vue"
    const name = inject("name")
    console.log(name) // 沐华
</script>

2.7 Vuex

// store/index.js
import { createStore } from "vuex"
export default createStore({
    state:{ count: 1 },
    getters:{
        getCount: state => state.count
    },
    mutations:{
        add(state){
            state.count++
        }
    }
})

// main.js
import { createApp } from "vue"
import App from "./App.vue"
import store from "./store"
createApp(App).use(store).mount("#app")

// Page.vue
// 方法一 直接使用
<template>
    <div>{{ $store.state.count }}</div>
    <button @click="$store.commit('add')">按钮</button>
</template>

// 方法二 获取
<script setup>
    import { useStore, computed } from "vuex"
    const store = useStore()
    console.log(store.state.count) // 1

    const count = computed(()=>store.state.count) // 响应式,会随着vuex数据改变而改变
    console.log(count) // 1
</script>

到此这篇关于Vue3的7种种组件通信详情的文章就介绍到这了,更多相关Vue3的7种种组件通信内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue3结合TypeScript项目开发实践总结

    目录 概述 1.compositon Api 1.ref 和 reactive的区别? 2.周期函数 3.store使用 4.router的使用 2.关注点分离 3.TypeScript支持 概述 Vue3出来已经有一段时间了,在团队中,也进行了大量的业务实践,也有了一些自己的思考. 总的来说,Vue3无论是在底层的原理上,还是在业务的实际开发中,都有了长足的进步. 使用 proxy 代替之前的 Object.defineProperty 的API,性能更加优异,也解决了之前vue在处理对象.数

  • vue3 与 vue2 优点对比汇总

    目录 优点1:diff算法的优化 优点2:hoistStatic 静态提升 优点3:cacheHandlers 事件侦听器缓存 优点4:ssr渲染 优点5:更好的Ts支持 优点6:Compostion API: 组合API/注入API 优点7:更先进的组件 优点8:自定义渲染API 优点9:按需编译,体积比vue2.x更小 优点10:支持多根节点组件 ​​​​​​摘要: Vue3新版本的理念成型于 2018 年末,当时的 Vue 2 已经有两岁半了.比起通用软件的生命周期来这好像也没那么久,Vu

  • Vue3封装 Message消息提示实例函数详解

    目录 Vue3封装 消息提示实例函数 样式布局封装 message.vue 功能实现 message.js 注册 自定义指令 使用 : 总结 Vue3封装 消息提示实例函数 Vue2.0使用 Vue.prototype.$message = function () {} vue3.0使用app.config.globalProperties挂载原型方法app.config.globalProperties.$message = Message 也支持直接导入函数使用 import Message

  • Vue3结合TypeScript项目开发实战记录

    目录 概述 1.compositon Api 1.ref 和 reactive的区别? 2.周期函数 3.store使用 4.router的使用 2.关注点分离 3.TypeScript支持 总结 概述 Vue3出来已经有一段时间了,在团队中,也进行了大量的业务实践,也有了一些自己的思考. 总的来说,Vue3无论是在底层的原理上,还是在业务的实际开发中,都有了长足的进步. 使用 proxy 代替之前的 Object.defineProperty 的API,性能更加优异,也解决了之前vue在处理对

  • Vue3导航栏组件封装实现方法

    在Vue3中封装一个导航栏组件,并且实现,随着滚动条滚动实现一个吸顶效果,供大家参考 导航栏组件的效果图: 滚动条滚动以后的吸顶效果示意图: 具体代码展示: <template> <header class="app-header"> <div class="container"> <!-- 头部导航区域 --> <HeaderNavCommon /> <div class="search&

  • vue3 文档梳理快速入门

    目录 一.setup 1. setup 函数中的第一个参数 -- props 2.  contextcontext 二.setup 函数的返回值 1.setup 函数的返回值 -- 对象 三.响应式系统 API 1. reactive 2. ref 3. computed 4. readonly 5. watchEffect 5.1 停止侦听 5.2 清除副作用 5.3 副作用刷新时机 5.4  侦听器调试 6. watch 6.1 侦听多个数据源 6.2 与 watchEffect 共享的行为

  • Vue3中reactive函数toRef函数ref函数简介

    目录 reactive函数 用法: toRef函数(了解即可) 用法: ref函数 定义响应式数据 直接定义使用 获取dom 获取组件实例对象 reactive函数 reactive用于定义响应式数据(可以理解 成data的替代品) 用法: 导入 import {reactive} from 'vue' 使用: const state=reactive({ 参数名:参数值 }) 访问: state.参数名 访问: state.参数名 toRef函数(了解即可) toRef:将响应式数据中某个字段

  • Vue3.x使用mitt.js进行组件通信

    目录 快速开始 使用方式 核心原理 Vue2.x 使用 EventBus 进行组件通信,而 Vue3.x 推荐使用 mitt.js. 比起 Vue 实例上的 EventBus,mitt.js 好在哪里呢?首先它足够小,仅有200bytes,其次支持全部事件的监听和批量移除,它还不依赖 Vue 实例,所以可以跨框架使用,React 或者 Vue,甚至 jQuery 项目都能使用同一套库. 快速开始 npm install --save mitt 方式1,全局总线,vue 入口文件 main.js

  • Vue3父子组件传参有关sync修饰符的用法详解

    目录 单向数据流讲解 Vue2.x使用 定义事件的形式, 通知父组件修改 .sync 和 update: 的使用 父传子, 传递多个数据的简写 采用v-model简写(要求严格) Vue3.x使用 普通用法 简写 单向数据流讲解 单向数据流(堆可以修改,栈不可修改) 我们都知道, 父传子的数据, 是单向数据流,即子组件不能直接修改, 父组件传递过来的值 但实际上, 对于修改值, 真正是:基本数据类型不可修改,复杂数据类型不要修改引用地址(栈),它的值可以随便修改 Vue2.x使用 定义事件的形式

  • Vue3使用mitt进行组件通信的步骤

    Vue2.x使用EventBus进行组件通信,而Vue3.x推荐使用mitt.js. 比起Vue实例上的EventBus,mitt.js好在哪里呢?首先它足够小,仅有200bytes,其次支持全部事件的监听和批量移除,它还不依赖Vue实例,所以可以跨框架使用,React或者Vue,甚至jQuery项目都能使用同一套库. 1. 安装 推荐使用yarn安装(用过都知道有多丝滑) yarn add mitt 或者通过npm安装 npm install --save mitt 2. 引入到项目并挂载 可

随机推荐