Vue3组件通讯有哪些方式

目前最常用是props/$emitvuex/pinia ,接下来是 provide/inject,其他不建议使用;
实际项目中,简单父子组件传递采用props/$emit ,涉及全局共享的数据一般采用 vuex/pinia 结合存储对象localStorage/sessionStorage使用

1.props/$emit

1.props 单向数据流,父组件向子组件传递数据,不允许子组件修改props
2.支持传递静态或者动态prop,支持多种数据类型,包含数组,复杂对象
3.支持prop验证类型检查

静态prop

<blog-post title="My journey with Vue"></blog-post>  //不加冒号

动态prop

<blog-post:author="{name: 'Veronica',company: 'Veridian Dynamics'}"
></blog-post>

传递对象所有property

post: {id: 1,title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>

类型检查校验

app.component('my-component', {props: {// 基础的类型检查 (`null` 和 `undefined` 值会通过任何类型验证)propA: Number,// 多个可能的类型propB: [String, Number],// 必填的字符串propC: {type: String,required: true},// 带有默认值的数字propD: {type: Number,default: 100},// 带有默认值的对象propE: {type: Object,// 对象或数组的默认值必须从一个工厂函数返回default() {return { message: 'hello' }}},// 自定义验证函数propF: {validator(value) {// 这个值必须与下列字符串中的其中一个相匹配return ['success', 'warning', 'danger'].includes(value)}},// 具有默认值的函数propG: {type: Function,// 与对象或数组的默认值不同,这不是一个工厂函数——这是一个用作默认值的函数default() {return 'Default function'}}}
})

子组件通过自定义事件传递给父组件

<template><div>{{title}}<event-view @updateTitle="changeTitle"></event-view></div>
</template>
<script lang="ts">
import {defineComponent, ref} from 'vue';
import EventView from "@/views/test/EventView.vue";export default defineComponent({components: {EventView},setup() {const title = ref("我是父组件")return {title,};},methods:{changeTitle(val){this.title = val;}},
})
</script>

子组件

<template><div><a-button type="primary" @click="$emit('updateTitle','子组件修改了组件')">我是子组件</a-button></div>
</template>
<script setup lang="ts">import {defineExpose, ref} from "vue";defineEmits(['updateTitle']);
</script>

2.Vuex/Pinia

vuex 是针对vue的一个状态管理插件,vue3 匹配vuex4,vue2匹配vuex 3的版本,包含六个核心概念:state getter mutations actions modules

  • actions 可以包含任意异步操作, mutations 是同步操作,modules为了分割大状态
    主要针对多个组件共享状态时:
  • 多个视图组件依赖统一状态
  • 来自不同的视图的行为需要变更同一状态

1.定义state数据

import { createStore } from 'vuex'
interface User{name:string,age:number,status:boolean
}
const usersModule = {state: () => ({users :[{name: 'test111',age: 231,status: true,}],}),getters: {getActiveUsers:(state) => {return state.users.filter(user => user.status);},},mutations: {addUser(state,user:User){state.users.push(user);}},actions: {addUser(context,user:User){context.commit('addUser',user)}},}
export const vueStore = createStore({modules: {users: usersModule,}
})
  1. 绑定实例全局
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
app.use(vueStore)
···

3.组件使用

<template v-for="user in users" :key="user.name"><div>{{user.name}}|{{user.age}}|{{user.status}}</div>
</template>
<script setup lang="ts">import {computed} from "vue";import { useStore } from 'vuex'const store = useStore();// 在 computed 函数中访问 state//const users = computed(() => store.state.users),const users = computed(()=> store.getters.getActiveUsers);//使用gettersconst changeMsg = function (){// 使用 mutationstore.commit('addUser',{name:"dddfas",age:33,status:true});// 使用 actionstore.dispatch('addUser',{name:"111111",age:33,status:true});}
</script>

Pinia 是 Vue 的存储库,也是为了实现跨组件/页面共享状态,但是Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持;

1.创建Pinia实例

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'const pinia = createPinia()
const app = createApp(App)app.use(pinia)
app.mount('#app')
  1. 定义状态数据
import { defineStore } from 'pinia'interface User{name:string,age:number,status:boolean
}export const useUsersStore = defineStore({id: 'todo',state: () => ({     //定义共享状态usersusers :[{name: 'test1',age: 23,status: true,}]}),getters: {   //主要用于读取数据,默认是响应式的getActiveUsers(state){return state.users.filter(user => user.status)}},actions: { //主要用于更新数据addUser(user:User){this.users.push(user);}},})

3.在组件/页面中使用

<template v-for="user in users" :key="user.name"><div>{{user.name}}|{{user.age}}|{{user.status}}</div>
</template>
<script setup lang="ts">import {computed} from "vue";import {useUsersStore} from "@/store/users";const usersStore = useUsersStore();const users = computed(()=>usersStore.getActiveUsers); //使用computed
</script>

Vuex与Pinia 默认存储在浏览器内存中,可以其它存储 比如localStorage/sessionStorage
推荐使用Pinia,更加简单便捷,只提供三个概率stategettersactions,据说Pina已经实现了Vuex5 规划的大部分内容

3.provide/inject

主要适合父子组件,父和子孙组件通讯, 可以看作是长距离的 prop,支持在setup()中使用

  • 父组件不需要知道哪些子组件使用了它 provide 的 property
  • 子组件不需要知道 inject 的 property 来自哪里
<template><MyMarker />
</template><script>
import { provide } from 'vue'
import MyMarker from './MyMarker.vue'export default defineComponent({components: {MyMarker},setup() {provide('location', 'North Pole')provide('geolocation', {longitude: 90,latitude: 135})}
})
</script>

使用inject

<!-- src/components/MyMarker.vue -->
<script>
import { inject } from 'vue'export default defineComponent({setup() {const userLocation = inject('location', 'The Universe') // The Universe 默认值const userGeolocation = inject('geolocation')return {userLocation,userGeolocation}}
})
</script>

当需要支持响应式注入,只需要在provide值使用ref 或着reactive

...setup() {const location = ref('North Pole')const geolocation = reactive({longitude: 90,latitude: 135})provide('location', location)provide('geolocation', geolocation)}
...

4. 内置属性 ref/$refs $children/$parent $attrs $listeners

  • ref 用于引用子组件,this.$refs 指向子组件
  • $children Vue3 已经废弃不支持了,采用$refs 方式
  • $attrs 现在包含了所有传递给组件的 attribute,包括 class 和 style
  • $listeners 对象在 Vue3 中已被移除。事件监听器现在是 $attrs 的一部分
<template><div>{{title}}<a-button type="primary" @click="changeMsg">父组件</a-button><event-view ref="event"></event-view></div>
</template>
<script lang="ts">
import {defineComponent, ref} from 'vue';
import EventView from "@/views/test/EventView.vue";export default defineComponent({components: {EventView},setup() {const title = ref("我是父组件")return {title,};},methods:{changeMsg(){//this.$refs.event.msg = "父组件改变了子组件"  // Object is of type 'unknown'.(this.$refs.event as any).msg ="父组件改变了子组件";}},
});
</script>

子组件:

<template><div>{{msg}}<a-button type="primary" @click="changeParent">子组件</a-button></div>
</template>
<script lang="ts">
import {defineComponent,ref} from "vue";export default defineComponent({setup(){let msg = ref('我是子组件');return {msg}},methods:{changeParent(){this.$parent.title = "子组件改变了父组件"}}})
</script>

$attrs 方式:

<template><label><input type="text" v-bind="$attrs" /></label>
</template>
<script>
export default {inheritAttrs: false
}
</script>

如果这个组件接收一个 id attribute 和一个 v-on:close 监听器,那么 $attrs 对象现在将如下所示:

{id: 'my-input',onClose: () => console.log('close 事件被触发')
}

应该尽量避免在<script setup> 使用this,即setup 入口函数引用this

5.localStorage/sessionStorage

  • localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空

  • localStorage 解决了cookie存储空间不足的问题(每条cookie为4k),一般浏览器支持的是5M,不同浏览器中会有所区别

  • 只支持字符串类型的存储,推荐getItem\setItem这两种方法对其进行存取

会话级别是标签级别的,新标签页面sessionStorage继承自之前页面的sessionStorage,但是后续两个页面的sessionStorage是单独控制的

//设置缓存
localStorage.setItem('key','value')
sessionStorage.setItem('key','value')//获取缓存
localStorage.getItem('key')
sessionStorage.getItem('key')//删除缓存
localStorage.removeItem('key')
sessionStorage.removeItem('key')//清空缓存
localStorage.clear()
sessionStorage.clear()

6.eventBus

Vue2.x 使用 EventBus 事件总线进行兄弟组件通信,而在Vue3中事件总线模式已经被移除,官方建议使用外部的、实现了事件触发器接口的库,例如 mitt 或 tiny-emitter

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/14374.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python——基于共享单车使用量数据的可视化分析(1)

目录 &#x1f9fe; 1、数据集&#xff08;部分数据&#xff09; ✏️ 2、导入数据集与必要模块 1️⃣ 2.1 导入库以及字体包 2️⃣ 2.2 读取数据集 3️⃣ 2.3 查看数据集基本信息 ⌨️ 3、数据预处理 1️⃣ 3.1删除无关字段 2️⃣ 3.2对各字段进行中文标识 3️⃣ 3.3…

Open3D-Geometry-3:RGBD图像的数据处理

文章目录 0. 引言1. Redwood 数据集2. SUN 数据集3. NYU 数据集4. TUM 数据集0. 引言 Open3D 有图像的数据结构。它支持各种功能,例如read_image、write_image、filter_image和draw_geometries。 Open3D 图像可以直接与 numpy 数组相互转换。 Open3D RGBDImage由两个图像组成…

EI会议的社交活动有哪些?

EI会议&#xff08;Engineering Index会议&#xff09;不仅是一个展示最新研究成果的平台&#xff0c;也为与会者提供了丰富的社交活动机会。以下是一些常见的社交活动形式及其内容&#xff1a; 常见社交活动 1. 欢迎酒会&#xff08;Welcome Reception&#xff09; 时间和地…

图像超分辨率重建相关概念、评价指标、数据集、模型

1、图像超分辨率概念 1.1 基本定义 超分辨率&#xff08;Super-Resolution&#xff09;&#xff0c;简称超分&#xff08;SR&#xff09;。是指利用光学及其相关光学知识&#xff0c;根据已知图像信息恢复图像细节和其他数据信息的过程&#xff0c;简单来说就是增大图像的分辨…

【openpcdet中yaml文件的MODEL学习】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、代码二、详细解释MODEL: NAME: PointPillarMAP_TO_BEV (Mapping to Birds Eye View):BACKBONE_2D (2D Backbone Network): 总结 前言 提示&#xff1a;这里…

光照模型技术在AI去衣中的重要作用

引言&#xff1a; 在数字图像处理和计算机视觉领域&#xff0c;AI去衣技术正逐渐成为研究和应用的热点。这项技术依赖于人工智能算法&#xff0c;尤其是深度学习模型&#xff0c;来识别和处理图像或视频中的衣物。在这个过程中&#xff0c;光照模型技术扮演着至关重要的角色。本…

派可数据助力制造企业数字化生产管理新能力提升

生产管理是现代企业运营的核心之一&#xff0c;它决定了产品的质量、生产效率和企业的竞争力。在一个日益竞争激烈、市场需求多变的商业环境中&#xff0c;如何高效地组织和管理生产过程成为了企业不容忽视的重要课题。 过去&#xff0c;生产管理可能主要侧重于物理工厂的运作…

2024-5-6-从0到1手写配置中心Config之实现配置中心客户端

配置加载原理 在Spring中PropertySource类实现了所有属性的实例化。 启动赋值&#xff1a; 定义自定义属性配置源&#xff0c;从config-server获取全局属性&#xff1b;Spring启动时&#xff0c;插入自定义属性配置源&#xff1b;绑定属性会优先使用&#xff0c;给自定义属性…

宁盾与深信服发布联合方案,解决云桌面及微软AD完整替代

自 Citrix 退出中国市场后&#xff0c;不少中大型企业关心国产云桌面脱离微软 AD 域是否还能正常工作。在2024年3月初&#xff0c;宁盾身份目录与深信服桌面云完成兼容互认证&#xff0c;对于企业的疑问给出了官方回应。 5月10日&#xff0c;在深信服《Citrix离场背景下&#…

【设计模式】JAVA Design Patterns——Balking(止步模式)

&#x1f50d;目的 止步模式用于防止对象在不完整或不合适的状态下执行某些代码。 &#x1f50d;解释 真实世界例子 洗衣机中有一个开始按钮&#xff0c;用于启动衣物洗涤。当洗衣机处于非活动状态时&#xff0c;按钮将按预期工作&#xff0c;但是如果已经在洗涤&#xff0c;则…

类中属性赋值的过程——Java学习笔记

类中属性赋值过程 非静态属性的赋值 可以通过: 默认初始化显示初始化构造器中初始化通过对象.属性或对象.方法的方法进行赋值代码块中初始化 执行先后顺序&#xff1a;默认初始化–>显式初始化–>代码块中初始化–>构造器初始化–>通过方法进行赋值 关于字节码…

Spring中Bean的作用域有哪些?

在Spring框架中&#xff0c;Bean的作用域定义了由Spring IoC容器创建的Bean实例的可见范围和生命周期。Spring提供了几种不同的Bean作用域供我们根据需求选择使用&#xff0c;每种作用域都有其特定的用途。常用的作用域包括&#xff1a; Singleton&#xff08;单例&#xff09;…

企业签名有什么优点?

企业签名具有以下优点&#xff1a; 1.自定义企业分发&#xff1a;为企业提供更大的灵活性和控制权 2.加强企业安全性&#xff1a; 控制分发 减少潜在风险、数据泄露 3.内部应用更新和管理&#xff1a;企业可自主更新和管理内部分发。灵活发布新版本应用程序&#xff0c;修复bug…

大型语言模型(LLM)论文串烧

近期把各家大型语言模型的论文过了一遍&#xff0c;包括&#xff1a; Qwen Llama 2 BlueLM GLM-130B Baichuan2 Yi 刚好趁着刚看完还有印象稍微做下总结。

「动态规划」地下城游戏

力扣原题链接&#xff0c;点击跳转。 有一个地下城&#xff0c;我们用mn大小的二维数组dungeon表示。dungeon[i][j]如果为正&#xff0c;该位置有血包&#xff0c;可以加血量&#xff1b;如果为负&#xff0c;该位置有恶魔&#xff0c;会扣掉相应的血量。有一个骑士在左上角&a…

科技产业园3D探秘:未来科技之城的奇幻之旅

在数字时代的浪潮中&#xff0c;科技产业园区成为了推动城市经济发展、科技创新的重要引擎。 当我们打开科技产业园的3D可视化模型&#xff0c;仿佛穿越时空&#xff0c;来到了一个充满奇幻色彩的科技世界。在这里&#xff0c;高楼大厦鳞次栉比&#xff0c;绿色植被点缀其间&am…

【文末附gpt升级方案】革新多模态学习:哈工大团队推出“Uni-MoE”统一多模态大模型的跨域MoE研究

革新多模态学习&#xff1a;哈工大团队推出“Uni-MoE”统一多模态大模型的跨域MoE研究 摘要&#xff1a;随着人工智能技术的飞速发展&#xff0c;多模态学习已成为机器学习领域的重要研究方向。然而&#xff0c;传统的多模态学习方法往往存在信息融合困难、模型复杂度高等问题…

深度学习模型keras第二十三讲:在KerasCV中使用SAM进行任何图像分割

1 SAM概念 ###1.1 SAM定义 Segment Anything Model&#xff08;SAM&#xff09;是一种基于深度学习的图像分割模型&#xff0c;其主要特点包括&#xff1a; 高质量的图像分割&#xff1a;SAM可以从输入提示&#xff08;如点、框、文字等&#xff09;生成高质量的对象掩模&am…

我爱我家:租赁下位替代买房,能行吗?

我爱我家&#xff0c;凭什么五天四板&#xff1f; 上周五的楼市组合拳出台后&#xff0c;地产板块迎来高潮。 这其中最火的不是我们常说的“招宝万金”&#xff0c;而是——我爱我家。 五天四板&#xff0c;一个月不到&#xff0c;股价轻松翻翻。 公司有什么变化吗&#xff1…

Flutter 页面布局 Flex Expanded弹性布局

题记 —— 执剑天涯&#xff0c;从你的点滴积累开始&#xff0c;所及之处&#xff0c;必精益求精&#xff0c;即是折腾每一天。 什么是弹性布局&#xff08;Flex&#xff09;&#xff1f; 弹性布局&#xff08;Flex&#xff09;是一种基于弹性盒子模型的布局方式&#xff0c;类…