Vue3 完整学习笔记 - 第四部分

Vue3 完整学习笔记 - 第四部分

4. Pinia 状态管理与组件通信

4.1 Pinia 基础

重点掌握:

  • Store 的创建和使用
  • State、Getters、Actions 的定义
  • 组合式风格的 Store

基础 Store 示例:

// stores/counter.ts
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {// 状态state: () => ({count: 0,name: 'Eduardo',items: []}),// 计算属性getters: {doubleCount: (state) => state.count * 2,// 使用this访问其他getterdoubleCountPlusOne(): number {return this.doubleCount + 1}},// 方法actions: {increment() {this.count++},async fetchItems() {const response = await fetch('/api/items')this.items = await response.json()}}
})// 组合式写法
export const useCounterStore = defineStore('counter', () => {const count = ref(0)const name = ref('Eduardo')const doubleCount = computed(() => count.value * 2)function increment() {count.value++}return { count, name, doubleCount, increment }
})

在组件中使用:

<template><div><p>Count: {{ counter.count }}</p><p>Double: {{ counter.doubleCount }}</p><button @click="counter.increment">+1</button><button @click="increment">+1 (Destructured)</button></div>
</template><script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'const counter = useCounterStore()// 解构时保持响应性
const { count, doubleCount } = storeToRefs(counter)
const { increment } = counter// 批量修改状态
function updateState() {counter.$patch({count: counter.count + 1,name: 'John'})// 或者使用函数形式counter.$patch((state) => {state.count++state.name = 'John'})
}// 监听状态变化
counter.$subscribe((mutation, state) => {console.log(mutation.type, mutation.payload)
})
</script>

4.2 Pinia 进阶使用

重点掌握:

  • 插件开发
  • 持久化存储
  • 状态重置

示例代码:

// stores/plugins/persistence.ts
import { PiniaPluginContext } from 'pinia'export function persistencePlugin({ store }: PiniaPluginContext) {// 从localStorage恢复状态const savedState = localStorage.getItem(`${store.$id}-state`)if (savedState) {store.$state = JSON.parse(savedState)}// 监听状态变化并保存store.$subscribe(({ storeId, state }) => {localStorage.setItem(`${storeId}-state`, JSON.stringify(state))})
}// main.ts
const pinia = createPinia()
pinia.use(persistencePlugin)// 自定义 Store 属性
pinia.use(({ store }) => {store.customProperty = 'my custom value'store.customMethod = () => console.log('hello')
})

4.3 组件通信方式一:Props 与 Emit

重点掌握:

  • Props 定义与验证
  • 事件发射与监听
  • v-model 的使用

示例代码:

<!-- ChildComponent.vue -->
<template><div><input:value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/><button @click="handleClick">Click Me</button></div>
</template><script setup lang="ts">
const props = defineProps<{modelValue: stringlabel?: string
}>()const emit = defineEmits<{(e: 'update:modelValue', value: string): void(e: 'customEvent',  { id: number, value: string }): void
}>()const handleClick = () => {emit('customEvent', { id: 1, value: 'test' })
}
</script><!-- ParentComponent.vue -->
<template><div><ChildComponentv-model="inputValue"label="Username"@customEvent="handleCustomEvent"/></div>
</template><script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'const inputValue = ref('')const handleCustomEvent = (data) => {console.log('Custom event received:', data)
}
</script>

4.4 组件通信方式二:Provide/Inject

重点掌握:

  • 跨层级组件通信
  • 响应式数据传递
  • 作用域插槽替代方案

示例代码:

<!-- ParentComponent.vue -->
<template><div><slot :data="data" :updateData="updateData"></slot><ChildComponent /></div>
</template><script setup>
import { provide, ref } from 'vue'const data = ref({ count: 0 })// 提供响应式数据
provide('data', data)// 提供方法
const updateData = () => {data.value.count++
}
provide('updateData', updateData)// 提供只读数据
provide('readonlyData', readonly(data))
</script><!-- ChildComponent.vue -->
<template><div><p>Count: {{ data.count }}</p><button @click="updateData">Update</button></div>
</template><script setup>
import { inject } from 'vue'// 注入数据和方法
const data = inject('data')
const updateData = inject('updateData')// 使用默认值
const theme = inject('theme', 'light')
</script>

4.5 组件通信方式三:Event Bus (mitt)

重点掌握:

  • 事件总线的使用
  • 事件监听与清理
  • 适用场景

示例代码:

// eventBus.ts
import mitt from 'mitt'export const emitter = mitt()// 类型定义
type Events = {'item-click': { id: number; data: any }'data-updated': void
}export const typedEmitter = mitt<Events>()// ComponentA.vue
<script setup>
import { onMounted, onUnmounted } from 'vue'
import { emitter } from './eventBus'// 监听事件
onMounted(() => {emitter.on('item-click', (event) => {console.log('Item clicked:', event)})
})// 清理事件监听
onUnmounted(() => {emitter.off('item-click')
})// 发送事件
const handleClick = () => {emitter.emit('item-click', { id: 1,  'test' })
}
</script>// ComponentB.vue
<script setup>
import { emitter } from './eventBus'// 发送事件
const notifyUpdate = () => {emitter.emit('data-updated')
}
</script>

4.6 异步组件与动态组件

重点掌握:

  • 异步组件的加载
  • 动态组件切换
  • 加载状态处理

示例代码:

<template><div><!-- 异步组件 --><Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template></Suspense><!-- 动态组件 --><component :is="currentComponent"@change="handleChange"/><button @click="toggleComponent">Switch Component</button></div>
</template><script setup>
import { ref, defineAsyncComponent } from 'vue'// 异步组件定义
const AsyncComponent = defineAsyncComponent({loader: () => import('./HeavyComponent.vue'),loadingComponent: LoadingComponent,errorComponent: ErrorComponent,delay: 200,timeout: 3000
})// 动态组件
const components = {'comp-a': defineAsyncComponent(() => import('./ComponentA.vue')),'comp-b': defineAsyncComponent(() => import('./ComponentB.vue'))
}const currentComponent = ref('comp-a')const toggleComponent = () => {currentComponent.value = currentComponent.value === 'comp-a' ? 'comp-b' : 'comp-a'
}
</script>

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

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

相关文章

sql表的增删改、替换

一、增加 1、向原表的字段中插入多条记录的方法 # mysql中常用的三种插入数据的语句: # insert into表示插入数据&#xff0c;数据库会检查主键&#xff0c;如果出现重复会报错&#xff1b; # replace into表示插入替换数据&#xff0c;需求表中有PrimaryKey&#xff0c; # 或…

执行策略更改

执行策略三种模式&#xff1a; Restricted&#xff1a;不允许运行任何脚本&#xff08;这是默认设置&#xff09;。RemoteSigned&#xff1a;允许本地脚本运行&#xff0c;但从互联网下载的脚本需要有效的签名才能运行。Unrestricted&#xff1a;允许所有脚本运行&#xff0c;…

如何创建折叠式Title

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了SliverGrid组件相关的内容&#xff0c;本章回中将介绍SliverAppBar组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的SliverAppBar和普通的AppBar类似&#xff0c;它们的…

[Proteus仿真]基于51单片机的智能温控系统

[Proteus仿真]基于51单片机的智能温控系统 基于51单片机的智能温控系统&#xff1a;DS18B20精准测温LCD1602双屏显示三键设置上下限声光报警&#xff0c;支持温度校准、抗干扰设计、阈值记忆。 一.仿真原理图 ​​ 二.模块介绍 温度采集模块&#xff08;DS18B20&#xff0…

RAG 与历史信息相结合

初始化模型 # Step 4. 初始化模型, 该行初始化与 智谱 的 GLM - 4 模型进行连接&#xff0c;将其设置为处理和生成响应。 chat ChatZhipuAI(model"glm-4",temperature0.8, ) 此提示告诉模型接收聊天历史记录和用户的最新问题&#xff0c;然后重新表述问题&#x…

【Redis】安装配置Redis超详细教程 / Linux版

Linux安装配置Redis超详细教程 安装redis依赖安装redis启动redis停止redisredis.conf常见配置设置redis为后台启动修改redis监听地址设置工作目录修改密码监听的端口号数据库数量设置redis最大内存设置日志文件设置redis开机自动启动 学习视频&#xff1a;黑马程序员Redis入门到…

神经网络参数量和运算量的计算- 基于deepspeed库和thop库函数

引言 最近需要对神经网络的参数量和运算量进行统计。找到一个基于deepspeed库函数计算参数量和运算量的例子。而我之前一直用thop库函数来计算。 看到有一篇勘误博文写道使用thops库得到的运算量是MACs (Multiply ACcumulate operations&#xff0c;乘加累积操作次数&#xf…

小程序-基础加强

前言 这一节把基础加强讲完 1. 导入需要用到的小程序项目 2. 初步安装和使用vant组件库 这里还可以扫描二维码 其中步骤四没什么用 右键选择最后一个 在开始之前&#xff0c;我们的项目根目录得有package.json 没有的话&#xff0c;我们就初始化一个 但是我们没有npm这个…

HTMLCSS :下雪了

这段代码创建了一个动态的雪花飘落加载动画&#xff0c;通过 CSS 技术实现了雪花的下落和消失效果&#xff0c;为页面添加了视觉吸引力和动态感。 大家复制代码时&#xff0c;可能会因格式转换出现错乱&#xff0c;导致样式失效。建议先少量复制代码进行测试&#xff0c;若未能…

string例题

一、字符串最后一个单词长度 题目解析&#xff1a;由题输入一段字符串或一句话找最后一个单词的长度&#xff0c;也就是找最后一个空格后的单词长度。1.既然有空格那用我们常规的cin就不行了&#xff0c;我们这里使用getline,2.读取空格既然是最后一个空格后的单词&#xff0c;…

OpenGL学习笔记(六):Transformations 变换(变换矩阵、坐标系统、GLM库应用)

文章目录 向量变换使用GLM变换&#xff08;缩放、旋转、位移&#xff09;将变换矩阵传递给着色器坐标系统与MVP矩阵三维变换绘制3D立方体 & 深度测试&#xff08;Z-buffer&#xff09;练习1——更多立方体 现在我们已经知道了如何创建一个物体、着色、加入纹理。但它们都还…

NLP模型大对比:Transformer >Seq2Seq > LSTM > RNN > n-gram

结论 Transformer 大于 传统的Seq2Seq 大于 LSTM 大于 RNN 大于 传统的n-gram n-gram VS Transformer 我们可以用一个 图书馆查询 的类比来解释它们的差异&#xff1a; 一、核心差异对比 维度n-gram 模型Transformer工作方式固定窗口的"近视观察员"全局关联的&q…

登录认证(5):过滤器:Filter

统一拦截 上文我们提到&#xff08;登录认证&#xff08;4&#xff09;&#xff1a;令牌技术&#xff09;&#xff0c;现在大部分项目都使用JWT令牌来进行会话跟踪&#xff0c;来完成登录功能。有了JWT令牌可以标识用户的登录状态&#xff0c;但是完整的登录逻辑如图所示&…

【R语言】R语言安装包的相关操作

一、管理R语言安装包 1、安装R包 install.packages() 2、查看已安装的R包 installed.packages() 3、更新R包 update.packages() 4、卸载R包 remove.packages() 二、加载R语言安装包 打开R语言时&#xff0c;基础包&#xff08;base包&#xff09;会自动被加载到内存中…

Vue指令v-on

目录 一、Vue中的v-on指令是什么&#xff1f;二、v-on指令的简写三、v-on指令的使用 一、Vue中的v-on指令是什么&#xff1f; v-on指令的作用是&#xff1a;为元素绑定事件。 二、v-on指令的简写 “v-on&#xff1a;“指令可以简写为”” 三、v-on指令的使用 1、v-on指令绑…

javaEE-8.JVM(八股文系列)

目录 一.简介 二.JVM中的内存划分 JVM的内存划分图: 堆区:​编辑 栈区:​编辑 程序计数器&#xff1a;​编辑 元数据区&#xff1a;​编辑 经典笔试题&#xff1a; 三,JVM的类加载机制 1.加载: 2.验证: 3.准备: 4.解析: 5.初始化: 双亲委派模型 概念: JVM的类加…

物业管理系统源码提升社区智能化管理效率与用户体验

内容概要 物业管理系统源码是一种针对社区管理需求而设计的软件解决方案&#xff0c;通过先进的智能化技术&#xff0c;使物业管理变得更加高效和人性化。随着城市化进程的加快&#xff0c;社区的管理复杂性不断增加&#xff0c;而这一系统的推出恰好为物业公司提供了极大的便…

读算法简史:从美索不达米亚到人工智能时代05天气预报

1. 天气预报 1.1. 自古以来&#xff0c;生命就与变幻莫测的天气息息相关 1.1.1. 在很多情况下&#xff0c;只要能提前一天得知天气情况&#xff0c;人类就可以避免灭顶之灾 1.1.2. 公元前2000年&#xff0c;准确预测天气是众神的特权 1.2. 大约在公元前650年&#xff0c;巴…

整形的存储形式和浮点型在计算机中的存储形式

在计算机科学的底层世界里&#xff0c;数据存储是基石般的存在。不同数据类型&#xff0c;如整形与浮点型&#xff0c;其存储方式犹如独特的密码&#xff0c;隐藏着计算机高效运行的秘密。理解它们&#xff0c;是深入掌握编程与计算机原理的关键。 一、整形的存储形式 原码、反…

Python网络自动化运维---批量登录设备

文章目录 目录 文章目录 前言 实验准备 一.批量登录 IP 连续的设备 1.1.1 实验代码 1.1.2 代码分段分解 1.1.3 实验结果验证 二.批量登录 IP 不连续的设备 2.2.1 实验代码 2.2.2 代码分段分解 2.2.3 实验结果验证 前言 在生产环境中&#xff0c;我们通常需要登录多个设备…