快速入门vue3新特性和新的状态管理库pinia
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)
目录
Vue3.3新特性
defineOptions
defineModel
pinia
介绍
与 Vuex 3.x/4.x 的比较
安装
核心概念
定义 Store
Option Store
Setup Store
storeToRefs
State
Getter
Action
pinia-plugin-persistedstate
概述
安装
用法
Vue3.3新特性
defineOptions
背景说明:有 <script setup> 之前,如果要定义 props, emits 可以轻而易举地添加一个与 setup 平级的属性。但是用了 <script setup> 后,就没法这么干了 setup 属性已经没有了,自然无法添加与其平级的属性。为了解决这一问题,引入了 defineProps 与 defineEmits 这两个宏。但这只解决了 props 与 emits 这两个属性。如果我们要定义组件的 name 或其他自定义的属性,还是得回到最原始的用法——再添加一个普通的 <script> 标签。这样就会存在两个 <script> 标签。让人无法接受
所以在 Vue 3.3 中新引入了 defineOptions 宏。顾名思义,主要是用来定义 Options API 的选项。可以用 defineOptions 定义任意的选项, props, emits, expose, slots 除外(因为这些可以使用 defineXXX 来做到)
defineModel
在 Vue3 中,自定义组件上使用 v-model, 相当于传递一个 modelValue 属性,同时触发 update:modelValue 事件
我们需要先定义 props,再定义 emits 。其中有许多重复的代码。如果需要修改此值,还需要手动调用 emit 函数。
新的defineModel宏的使用。宏会自动注册一个Props,并返回一个可以直接突变的引用:
注意:直接使用 defineModel 宏会报错,需要开启。
pinia
介绍
Pinia 是 Vue 的最新状态管理工具,是vuex的替代品
与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的规范,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。
与 Vuex 3.x/4.x 的比较
Pinia API 与 Vuex ≤4 有很大不同,即:
- mutations 不再存在。他们经常被认为是 非常 冗长。他们最初带来了 devtools 集成,但这不再是问题。
- 无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
- 不再需要注入、导入函数、调用函数、享受自动完成功能!
- 无需动态添加 Store,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手动使用 Store 进行注册,但因为它是自动的,您无需担心。
- 不再有 modules 的嵌套结构。您仍然可以通过在另一个 Store 中导入和 使用 来隐式嵌套 Store,但 Pinia 通过设计提供平面结构,同时仍然支持 Store 之间的交叉组合方式。 您甚至可以拥有 Store 的循环依赖关系。
- 没有 命名空间模块。鉴于 Store 的扁平架构,“命名空间” Store 是其定义方式所固有的,您可以说所有 Store 都是命名空间的。
安装
1.使用vite创建一个空的vue3项目
npm create vue@latest
2.用你喜欢的包管理器安装pinia:
yarn add pinia
# 或者使用 npm
npm install pinia
3.创建一个 pinia 实例 (根 store) 并将其传递给应用:
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')
核心概念
定义 Store
在深入研究核心概念之前,我们得知道 Store 是用
defineStore()
定义的,它的第一个参数要求是一个独一无二的名字:
import { defineStore } from 'pinia'// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('alerts', {// 其他配置...
})
这个名字 ,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为 use... 是一个符合组合式函数风格的约定。
defineStore()
的第二个参数可接受两类值:Setup 函数或 Option 对象。
Option Store
与 Vue 的选项式 API 类似,我们也可以传入一个带有
state
、actions
与getters
属性的 Option 对象
export const useCounterStore = defineStore('counter', {state: () => ({ count: 0 }),getters: {double: (state) => state.count * 2,},actions: {increment() {this.count++},},
})
你可以认为
state
是 store 的数据 (data
),getters
是 store 的计算属性 (computed
),而actions
则是方法 (methods
)。
Setup Store
与 Vue 组合式 API 的 setup 函数相似,我们可以传入一个函数,该函数定义了一些响应式属性和方法,并且返回一个带有我们想暴露出去的属性和方法的对象。
export const useCounterStore = defineStore('counter', () => {const count = ref(0)function increment() {count.value++}return { count, increment }
})
在 Setup Store 中:
ref()
就是state
属性computed()
就是getters
function()
就是actions
storeToRefs
请注意,
store
是一个用reactive
包装的对象,这意味着不需要在 getters 后面写.value
,就像setup
中的props
一样,如果你写了,我们也不能解构它:
<script setup>
const store = useCounterStore()
// ❌ 这将不起作用,因为它破坏了响应性
// 这就和直接解构 `props` 一样
const { name, doubleCount } = store
name // 将始终是 "Eduardo"
doubleCount // 将始终是 0
setTimeout(() => {store.increment()
}, 1000)
// ✅ 这样写是响应式的
// 💡 当然你也可以直接使用 `store.doubleCount`
const doubleValue = computed(() => store.doubleCount)
</script>
为了从 store 中提取属性时保持其响应性,你需要使用
storeToRefs()
。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上:
<script setup>
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// `name` 和 `doubleCount` 是响应式的 ref
// 同时通过插件添加的属性也会被提取为 ref
// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { name, doubleCount } = storeToRefs(store)
// 作为 action 的 increment 可以直接解构
const { increment } = store
</script>
State
在大多数情况下,state 都是你的 store 的核心。人们通常会先定义能代表他们 APP 的 state。在 Pinia 中,state 被定义为一个返回初始状态的函数。这使得 Pinia 可以同时支持服务端和客户端。
import { defineStore } from 'pinia'const useStore = defineStore('storeId', {// 为了完整类型推理,推荐使用箭头函数state: () => {return {// 所有这些属性都将自动推断出它们的类型count: 0,name: 'Eduardo',isAdmin: true,items: [],hasChanged: true,}},
})
默认情况下,你可以通过
store
实例访问 state,直接对其进行读写。
const store = useStore()store.count++
Getter
Getter 完全等同于 store 的 state 的计算值。可以通过
defineStore()
中的getters
属性来定义它们。推荐使用箭头函数,并且它将接收state
作为第一个参数:
export const useStore = defineStore('main', {state: () => ({count: 0,}),getters: {doubleCount: (state) => state.count * 2,},
})
然后你可以直接访问 store 实例上的 getter 了:
<script setup>
import { useStore } from './counterStore'
const store = useStore()
</script>
<template><p>Double count is {{ store.doubleCount }}</p>
</template>
Action
Action 相当于组件中的 method。它们可以通过
defineStore()
中的actions
属性来定义,并且它们也是定义业务逻辑的完美选择。
export const useCounterStore = defineStore('main', {state: () => ({count: 0,}),actions: {increment() {this.count++},randomizeCounter() {this.count = Math.round(100 * Math.random())},},
})
类似 getter,action 也可通过
this
访问整个 store 实例,并支持完整的类型标注(以及自动补全)。不同的是,action
可以是异步的,你可以在它们里面await
调用任何 API,以及其他 action!下面是一个使用 Mande 的例子。请注意,你使用什么库并不重要,只要你得到的是一个Promise
,你甚至可以 (在浏览器中) 使用原生fetch
函数:
import { mande } from 'mande'const api = mande('/api/users')export const useUsers = defineStore('users', {state: () => ({userData: null,// ...}),actions: {async registerUser(login, password) {try {this.userData = await api.post({ login, password })showTooltip(`Welcome back ${this.userData.name}!`)} catch (error) {showTooltip(error)// 让表单组件显示错误return error}},},
})
Action 可以像函数或者通常意义上的方法一样被调用:
<script setup>
const store = useCounterStore()
// 将 action 作为 store 的方法进行调用
store.randomizeCounter()
</script>
<template><!-- 即使在模板中也可以 --><button @click="store.randomizeCounter()">Randomize</button>
</template>
pinia-plugin-persistedstate
概述
本插件兼容
pinia^2.0.0
,在使用之前请确保你已经 安装 Pinia。pinia-plugin-persistedstate
丰富的功能可以使 Pinia Store 的持久化更易配置:
安装
1.用你喜欢的包管理器安装依赖
- pnpm:
pnpm i pinia-plugin-persistedstate
- npm:
npm i pinia-plugin-persistedstate
- yarn:
yarn add pinia-plugin-persistedstate
2.将插件添加到 pinia 实例上
import { createPinia } from 'pinia' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'const pinia = createPinia() pinia.use(piniaPluginPersistedstate)
用法
创建 Store 时,将
persist
选项设置为true
。
使用组合式 Store 语法:
import { defineStore } from 'pinia'export const useStore = defineStore('main',() => {const someState = ref('你好 pinia')return { someState }},{persist: true,}
)
相关文章:

快速入门vue3新特性和新的状态管理库pinia
(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 Vue3.3新特性 defineOptions defineModel pinia 介绍 与 Vuex 3.x/4.x 的比较 安装 核心概念 定义…...

字符串经典问题
1. 验证回文串 验证回文串 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s,如果它是 回文串 ,返回 t…...

如何将图片应用于所有的PPT页面?
问题:如何快速将图片应用到所有PPT页面? 解答:有两种方法可以解决这个问题。第一种用母板。第二种用PPT背景功能。 解决有时候汇报的时候,ppt中背景图片修改不了以及不知道如何查找,今天按照逆向过程进行操作 方法1…...

打印技巧——word中A4排版打印成A3双面对折翻页
在进行会议文件打印时,我们常会遇到需要将A4排版的文件,在A3纸张上进行双面对折翻页打印,本文对设置方式进行介绍: 1、在【布局】选项卡中,点击右下角小箭头,打开页面设置选项卡 1.1在【页边距】中将纸张…...

2、手写模拟Spring底层原理
创建BeanDefinition bean定义 设置BeanDefinition 的类信息,作用域信息 创建beanDefinitionMap scope为原型: scope为单例: 总结: 扫描ComponentScan注解上的包扫描路径,将Component注解修饰的类,生成Bea…...

6篇 ICML 2023 杰出论文解析,涉及无学习率、LLM水印、域泛化等方向
ICML 全称 International Conference on Machine Learning,由国际机器学习学会(IMLS)举办,是计算机人工智能领域的顶级会议。今年的 ICML 大会已是第 40 届,共收到 6538 份投稿,有1827 份被接收,…...

linux第三阶段--第三方软件(一)MySQL的概述和二进制安装(官网版)
MySQL介绍及安装 一、MySQL概述 DB2 POSTGRE-SQL 1、关系型数据库与非关系型数据库 RDBMS(relational database management system),既关系型数据库管理系统。 简单来说,关系型数据库,是指采用了二维表格来组织数…...

AD域控制器将辅域控制器角色提升为主域控制器
背景 域控服务器迁移,已将新机器添加为该域的辅域控制器。 主域控制器:test-dc-01 辅域控制器:test-dc-02 需求将主辅域的角色进行互换,test-dc-01更换为辅域,test-dc-02更换为主域。 操作步骤 方法1 命令行修改AD域…...

Docker案例分析:创建并运行一个Redis容器
步骤一:到DockerHub搜索Redis镜像 步骤二:查看Redis镜像文档中的帮助信息 步骤三:利用docker run命令运行一个Redis容器 可以看到第二行的命令是支持数据持久化的创建容器命令,但是我们使用的命令如下: docker run -…...

银河麒麟服务器v10 sp1 .Net6.0 上传文件错误 access to the path is denied
上一篇:银河麒麟服务器v10 sp1 部署.Net6.0 http https_csdn_aspnet的博客-CSDN博客 .NET 6之前,在Linux服务器上安装 libgdiplus 即可解决,libgdiplus是System.Drawing.Common原生端跨平台实现的主要提供者,是开源mono项目。地址…...

钝感力:项目经理的隐形盾牌
钝感力的定义 钝感力的起源和意义 钝感力,或者说对外部刺激的不敏感性,起源于我们的生存本能。在古代,人们面对各种危险和挑战,需要有一定的抗压能力,才能在恶劣环境中生存下来。这种能力使得我们的祖先能够在面对猛兽…...

成集云 | 乐享问题邀请同步企微提醒 | 解决方案
源系统成集云目标系统 方案介绍 腾讯乐享是腾讯公司开发的一款企业社区化知识管理平台,它提供了包括知识库、问答、课堂、考试、活动、投票和论坛等核心应用。这个平台凝聚了腾讯10年的管理经验,可以满足政府、企业和学校在知识管理、学习培训、文化建…...

【TypeScript】基础类型
安装 Node.js 环境 https://nodejs.org/en 终端中可以查到版本号即安装成功。 然后,终端执行npm i typescript -g安装 TypeScript 。 查到版本号即安装成功。 字符串类型 let str:string "Hello"; console.log(str);终端中先执行tsc --init…...
c++控制台双人格斗小游戏(测试版)
嗨嗨嗨,又是我! 我又来发博客啦! 最近太闲了,又做了个small游戏:小人-格斗(测试版) 上代码! 记得加上gamesio.h哦 #include<cstring> #include<conio.h> #include"gamesio.h" //宏定义一些常量(可更改) #define BULLETNUM 300//子弹最大数量 #defin…...

flink jira 提交开源bug
注册apache issue账号,并申请flink空间的权限后. 提问题/bug 查看已经提交的问题:...
华为杯”研究生数学建模竞赛2018年-【华为杯】D题:基于卫星高度计海面高度异常资料 获取潮汐调和常数方法及应用(续)
目录 5.3 沿轨道各分潮的潮汐调和常数的正压潮和内潮的分离 5.3.1 数据处理 5.3.2 模型准备...

HTTP连接管理
基础知识:非持久连接 HTTP初始时1.0版本在浏览器每一次向服务器请求完资源都会立即断开TCP连接,如果想要请求多个资源,就必须建立多个连接,这就导致了服务端和客户端维护连接的开销。 例如:一个网页中包含文字资源也包…...

漏洞指北-VulFocus靶场专栏-初级02
漏洞指北-VulFocus靶场02-初级 初级005 🌸phpunit 远程代码执行 (CVE-2017-9841)🌸step1:进入漏洞页step2: burpsuite 抓包,等待请求页,获得flag 初级006 🌸splunk 信息泄露 (CVE-2018-11409&am…...

无论是小说、公文还是新闻稿,爱校对都是你的最佳选择
在这个数字化的时代,写作已经渗透到我们生活的方方面面。从小说家到政府官员,再到新闻记者,每个人都需要确保他们的文本内容无瑕疵、逻辑清晰。这就是“爱校对”进入舞台的地方。它不仅仅是一个校对工具,更是每个写作者都不可或缺…...
MySQL数据表的损坏及容灾解决方案
引言 在互联网应用中,MySQL是最常用的关系型数据库之一。然而,数据表的损坏可能会导致数据丢失或无法正常访问,给业务运营带来严重影响。本文将讨论MySQL数据表容易损坏的情况,并提供相应的容灾解决方案。 推荐阅读 AI文本 OCR…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...