Vue 状态管理:从Vuex到Pinia,Vue 3官方推荐的状态管理库深度解析

news2024/10/5 22:00:38

大家好,我是前端宝哥。

在编程界有句老话:“命名和缓存失效是世上两大难题。” 我得说,在现代Web应用的状态管理上,这难题得排第三!

今天,咱们来深挖一下Vue的状态管理之道,并介绍一个超直观的解决方案——Pinia。

Vue状态管理:那些坑和局限性

自Vue 2起,我们用data属性来定义组件的状态,就像这样:

<template>
  <div>{{ user.name }}</div>
</template>

<script>
export default {
  data() {
    return { user: { name: 'John', age: 25 } };
  }
};
</script>

这就是所谓的 选项 API,在Vue 3中依然可用。Vue 3还带来了 组合式 API,它用reactiveref等新招数来定义状态。用这新API,我们可以这样写组件脚本:

<script setup>
import { reactive } from 'vue'

const user = reactive({ name: 'John', age: 25 });
</script>

但如果要跨组件访问状态,比如在导航栏显示用户名,在个人资料页展示详细信息,这就尴尬了。通常,我们用props逐层传递,但层级一多,就得在每个组件里加props,不管用不用得上。这叫prop 穿透,真不推荐。

更新共享数据时,子组件不能直接改props,得发事件让父组件来更新,再传下去。这...感觉有点笨。

Vue 3的救星来了:组合式 API 让我们能在任何脚本里用refreactive,还能导出状态,整个应用都能用。

我们可以把这状态叫做存储 (store)。比如,创建个store/user.js

import { reactive } from 'vue'

const user = reactive({ name: 'John', age: 25 });

export { user };

然后在组件里这么用:

<script setup>
import { user } from './stores/user.js';
</script>

<template>
  <h1>Hello, {{ user.name }}! You are {{ user.age }} years old.</h1>
</template>

看,现在状态有单一来源,组件间还能共享。

但这种模式虽简单,却不适合服务器端渲染 (SSR),因为状态只创建一次,可能导致数据泄露。而且,随着应用变大,可能需要更强大的状态管理。

Pinia:现代Vue应用的存储解决方案

Pinia 不仅支持SSR,还有Vue Devtools集成、热更新、TypeScript友好等优点。

Pinia由Vue Router的开发者Eduardo打造,现已取代Vuex,成为Vue 3官方推荐的状态管理库。

安装和设置

安装Pinia就一行命令:

npm install pinia

然后创建Pinia实例,传给Vue应用:

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

现在,创建和管理存储就这么简单。

创建存储

defineStore方法创建Pinia存储,第一参数是名,第二参数是配置。比如,我们改写下user存储:

import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({ name: 'John', age: 25 }),

  getters: {
    canVote: (state) => state.age >= 18,
  },

  actions: {
    blowCandles() {
      this.age++;
    }
  }
});

这就是选项存储 (Option Stores)。

喜欢组合式 API?Pinia也支持。用设置存储 (Setup Stores),用refcomputed定义状态和计算属性,函数返回要公开的:

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useUserStore = defineStore('user', () => {
  const name = ref('John');
  const age = ref(25);

  const canVote = computed(() => age.value >= 18);

  const blowCandles = () => age.value++;

  return { name, age, canVote, blowCandles };
});

设置存储的好处包括定义观察器、使用其他组合函数、注入属性等。

使用存储

定义了Pinia存储后,就可以在组件或组合函数里导入使用了:

<script setup>
import useUserStore from './stores/user.js'

const user = useUserStore();
</script>

<template>
  <button @click="user.blowCandles">
    I am {{ user.name }} and it's my birthday!
  </button>
</template>

通过user对象访问状态和操作,简单直观。解构时,用storeToRefs保持反应性。

真实例子

实际应用中,我们不会用固定值初始化存储。来看个登录示例:

import { ofetch } from 'ofetch'
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', () => {
  const data = ref();
  const token = ref();

  const isLoggedIn = computed(() => Boolean(token.value));

  async function login({ email, password }) {
    const { data, token: tok } = await ofetch('https://example.com/login', {
      method: 'POST',
      body: { email, password }
    });

    data.value = data;
    token.value = tok;
  }

  // ... logout, other methods
});

存储是封装应用逻辑的好地方。比如,登录操作请求API,保存用户数据和令牌。

然后在组件里这么用:

<script setup>
import useUserStore from './stores/user.js'

const user = useUserStore();
// ... form, error, handleSubmit
</script>

<template>
  <!-- ... template code -->
</template>

Pinia不仅管理用户会话,还能跟踪其他数据,减少服务器请求,让应用更快。

Pinia也适用于Vue 2

Pinia完全兼容Vue 2,所以如果你的Vue 2应用用Vuex,迁移到Pinia是升级到Vue 3的好起点。

Pinia Vue Devtools 插件

如果你用Vue Devtools,Pinia会有个新标签让你浏览存储,检查状态,甚至导入导出JSON。

总结

状态管理可能看起来有点吓人,但一旦掌握了,就简单多了。Pinia帮你组织数据,轻松访问。开发体验棒,集成简单。想试试?去官网看看。


往期推荐

38个Vue、Nuxt 和 Vite 技巧、窍门和实践的合集

Vue 如何处理异步组件加载错误

Vue 3 将推出新特性,可以抛弃虚拟DOM了!

Vue 小技巧:何时使用可组合函数

怎么才能做出一个牛逼的Vue 组件库?

掌握插槽魔法,助你进阶 Vue 开发,赋予组件无限可能!

微软 Edge 推出 "WebUI 2.0":从 React 到 Web Components + HTML,速度提升了42%

我是前端宝哥,每日分享前端开发技术,关注下面二维码,围观我的朋友圈。

fe4904cb861de0d95c849b800e6b0243.png

备注【文章群】可以进文章分享群,

备注【技术群】可以进技术交流群,

备注【副业群】可以进程序员副业群。

关注下方公众号加星标,送我的电子书资料

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF

  • 回复「Vue脑图」获取 Vue 相关脑图

  • 回复「思维图」获取 JavaScript 相关思维图

  • 回复「简历」获取简历制作建议

  • 回复「简历模板」获取精选的简历模板

  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。

  • 回复「知识点」下载高清JavaScript知识点图谱

  • 回复「读书」下载成长的相关电子书

70a901bd42d40349a2a6cd0916cdbeee.png

觉得好看,请关注我,点“在看”ff91544ba26445ae43a46cc5b62f2b3c.gif

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

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

相关文章

汽车IVI中控开发入门及进阶(二十八):视频SERDES芯片

前言: SerDes不是很常见,SerDes是将Ser和Des两种产品组合在一起的名称。Ser是Serializer或“并串转换器”的缩写,Des是Deserializer或“串并转换器”的简写。 Serdes是不是必须的?上一节介绍了camera,上上节也研究了video decoder,那么带摄像头的应用应该具体选哪个方案…

从踢足球到数字孪生

前言 贵州“村超”的火热现象是一个多方面因素共同作用的结果,它不仅是一场体育赛事,更是一个文化现象,反映了时代的精神和人民的情感诉求,同时也推动了乡村振兴和地区发展。足球的魅力是多方面的,它不仅仅是一项运动,更是一种全球性的文化现象。 简单规则下的无限变化:…

MySQL数据操作与查询- select 数据查询

一、select 选择列表 1、select基本结构 select 字段列表 from 表名 where 条件表达式 说明&#xff1a; &#xff08;1&#xff09; 必须的子句只有 select 子句和 from 子句。 &#xff08;2&#xff09;where 子句用于对查询结果进行过滤。 2、选择&#xff08;查询&am…

【会议征稿,IEEE出版】第六届物联网、自动化和人工智能国际学术会议(IoTAAI 2024,7月26-28)

第六届物联网、自动化和人工智能国际会议&#xff08;IoTAAI 2024&#xff09;将于2024年07月26-28日在中国广州召开。 会议旨在拓展国际科技学术交流渠道&#xff0c;搭建学术资源共享平台&#xff0c;促进全球范围内的科技创新&#xff0c;提升中外学术合作。会议还鼓励不同领…

再谈软件设计中的抽象思维(下),从FizzBuzz到规则引擎

作为《程序员的底层思维》出版两年之后的再回顾&#xff0c;在上一篇《再谈软件设计中的抽象思维&#xff08;上&#xff09;&#xff0c;从封装变化开始》中&#xff0c;我介绍了抽象设计的本质是发现变化点&#xff0c;结合问题域&#xff0c;提炼共性&#xff0c;沉淀领域知…

Golang | Leetcode Golang题解之第151题反转字符串中的单词

题目&#xff1a; 题解&#xff1a; import ("fmt" )func reverseWords(s string) string {//1.使用双指针删除冗余的空格slowIndex, fastIndex : 0, 0b : []byte(s)//删除头部冗余空格for len(b) > 0 && fastIndex < len(b) && b[fastIndex]…

建造者模式(大话设计模式)C/C++版本

建造者模式 C 参考&#xff1a;https://www.cnblogs.com/Galesaur-wcy/p/15907863.html #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std;// Product Class&#xff0c;产品类&#xff0c;由多个…

【Java】Object类中的toString、equals方法

Object类 所有类都直接或间接的继承自Object类&#xff0c;Object类是所有Java类的根基类。 也就意味着所有的Java对象都拥有Object类的属性和方法。 如果在类的声明中未使用extends关键字指明其父类&#xff0c;则默认继承Object类。 toString()方法 【1】Object类的toStr…

植物大战僵尸杂交版 v2.0.88 mac版 Plants vs. Zombies 杂交版下载

特别注意&#xff1a;该游戏最低系统要求为macOS Sonoma 14.X&#xff0c;低于此系统版本的请勿下载&#xff01; 游戏介绍 植物大战僵尸杂交版是由B站UP主“潜艇伟伟迷”制作的一款结合了《植物大战僵尸》原有元素与创新玩法的游戏。这款游戏以其独特的“杂交”植物概念在B站…

【TypeScript】泛型工具

跟着 小满zs 学 ts&#xff1a;学习TypeScript24&#xff08;TS进阶用法-泛型工具&#xff09;_ts泛型工具-CSDN博客 Partial 所有属性可选的意思Required 所有属性必选的意思Pick 提取部分属性Exclude 排除部分属性emit 排除部分属性并且返回新的类型 Partial 属性变为可选。…

Python基础教程(二十):SMTP发送邮件

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

Python 小市值股票模型代码及回测分析

目录 一、模型介绍 二、代码详解 2.1 初始化函数 2.2 股票筛选过滤函数 2.3 止损函数 2.4 开盘时运行函数 2.5 调仓函数 三、回测结果分析 3.1 收益净值图与概述 3.2 模型收益概览 3.3 年度收益图 3.4 月度收益的时间序列 3.5 月度收益热力图 3.6 月度收益频次分…

CorelDraw 2024软件安装包下载 丨不限速下载丨亲测好用

​简介&#xff1a; CorelDRAW Graphics Suite 订阅版拥有配备齐全的专业设计工具包&#xff0c;可以通过非常高的效率提供令人惊艳的矢量插图、布局、照片编辑和排版项目。价格实惠的订阅就能获得令人难以置信的持续价值&#xff0c;即时、有保障地获得独家的新功能和内容、…

conda安装pytorch使用清华源

原命令&#xff0c;例&#xff1a; # CUDA 11.3 conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatoolkit11.3 -c pytorch使用清华源&#xff0c;例&#xff1a; # CUDA 11.3 conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatool…

Qwen2——阿里巴巴最新的多语言模型挑战 Llama 3 等 SOTA

引言 经过几个月的期待&#xff0c; 阿里巴巴 Qwen 团队终于发布了 Qwen2 – 他们强大的语言模型系列的下一代发展。 Qwen2 代表了一次重大飞跃&#xff0c;拥有尖端的进步&#xff0c;有可能将其定位为 Meta 著名的最佳替代品 骆驼3 模型。在本次技术深入探讨中&#xff0c;我…

【redis的基本数据类型】

基本数据类型 Redis的基本数据类型有五种&#xff0c;分别是 StringListHashSetSortedSet 这些基本的数据类型构成了其他数据类型的基石&#xff0c;而这些基本数据类型又对应着不同的底层实现&#xff0c;不同的底层实现往往是针对不同的使用场景做的特殊的优化&#xff0c;…

探索档案未来,尽在ARCHE-2024

2024年第三届上海国际智慧档案展览会暨高峰论坛&#xff08;ARCHE-2024&#xff09;将于2024年6月19日至21日在上海跨国采购会展中心隆重举行。深圳市铨顺宏科技有限公司应邀参展&#xff0c;将以全新形象盛装亮相&#xff0c;展示其在档案管理领域的最新技术和解决方案。 ARC…

Linux系统脚本开机自启动,开机自启动jar包vue前台等

脚本内容jiaobenname.sh #!/bin/bash # 设置环境变量 export JAVA_HOME/usr/local/java/jdk-17.0.10 export CLASSPATH.:$JAVA_HOME/lib/ export PATH.:$JAVA_HOME/bin:$PATHwhile true; doif ps aux | grep -v grep | grep "tomcat" > /dev/null; thenecho &quo…

Vue42-vc与vm的原型对象

一、普通函数与其对象的原型对象 显示原型属性&#xff0c;只有函数才有&#xff01;&#xff01;&#xff01; 实例对象只有隐式原型属性。 普通函数与其对象&#xff0c;指向同一个原型对象&#xff01;&#xff01;&#xff01; 这么写不推荐&#xff0c;建议直接如下格式&a…

C++初学者指南第一步---2. Hello world

C初学者指南第一步—2. Hello world 目录 C初学者指南第一步---2. Hello world1.源文件 “Hello.cpp”2.编译hello.cpp3.术语4.编译器标志5.不要使用 “using namespace std;” &#xff01; 1.源文件 “Hello.cpp” #include <iostream> // our first program int main…