vue3-应用规模化-路由和状态

news2024/11/25 16:34:28

客户端 vs. 服务端路由

服务端路由指的是服务器根据用户访问的 URL 路径返回不同的响应结果。当我们在一个传统的服务端渲染的 web 应用中点击一个链接时,浏览器会从服务端获得全新的 HTML,然后重新加载整个页面。

然而,在单页面应用中,客户端的 JavaScript 可以拦截页面的跳转请求,动态获取新的数据,然后在无需重新加载的情况下更新当前页面。这样通常可以带来更顺滑的用户体验,尤其是在更偏向“应用”的场景下,因为这类场景下用户通常会在很长的一段时间中做出多次交互。

在这类单页应用中,“路由”是在客户端执行的。一个客户端路由器的职责就是利用诸如 History API 或是 hashchange 事件这样的浏览器 API 来管理应用当前应该渲染的视图。

官方路由

Vue Router (https://router.vuejs.org/zh/)

状态管理

什么是状态管理?

理论上来说,每一个 Vue 组件实例都已经在“管理”它自己的响应式状态了。我们以一个简单的计数器组件为例:

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

// 状态
const count = ref(0)

// 动作
function increment() {
  count.value++
}
</script>

<!-- 视图 -->
<template>{{ count }}</template>

它是一个独立的单元,由以下几个部分组成:

状态:驱动整个应用的数据源;

视图:对状态的一种声明式映射;

交互:状态根据用户在视图中的输入而作出相应变更的可能方式。

下面是“单向数据流”这一概念的简单图示:

然而,当我们有多个组件共享一个共同的状态时,就没有这么简单了:

  • 多个视图可能都依赖于同一份状态。

  • 来自不同视图的交互也可能需要更改同一份状态。

对于情景 1,一个可行的办法是将共享状态“提升”到共同的祖先组件上去,再通过 props 传递下来。然而在深层次的组件树结构中这么做的话,很快就会使得代码变得繁琐冗长。这会导致另一个问题:Prop 逐级透传问题。

对于情景 2,我们经常发现自己会直接通过模板引用获取父/子实例,或者通过触发的事件尝试改变和同步多个状态的副本。但这些模式的健壮性都不甚理想,很容易就会导致代码难以维护。

一个更简单直接的解决方案是抽取出组件间的共享状态,放在一个全局单例中来管理。这样我们的组件树就变成了一个大的“视图”,而任何位置上的组件都可以访问其中的状态或触发动作。

用响应式 API 做简单状态管理

如果你有一部分状态需要在多个组件实例间共享,你可以使用 reactive() 来创建一个响应式对象,并将它导入到多个组件中:

// store.js
import { reactive } from 'vue'

export const store = reactive({
  count: 0
})
<!-- ComponentA.vue -->
<script setup>
import { store } from './store.js'
</script>

<template>From A: {{ store.count }}</template>
<!-- ComponentB.vue -->
<script setup>
import { store } from './store.js'
</script>

<template>From B: {{ store.count }}</template>

现在每当 store 对象被更改时,<ComponentA> 与 <ComponentB> 都会自动更新它们的视图。现在我们有了单一的数据源。

然而,这也意味着任意一个导入了 store 的组件都可以随意修改它的状态:

<template>
  <button @click="store.count++">
    From B: {{ store.count }}
  </button>
</template>

虽然这在简单的情况下是可行的,但从长远来看,可以被任何组件任意改变的全局状态是不太容易维护的。为了确保改变状态的逻辑像状态本身一样集中,建议在 store 上定义方法,方法的名称应该要能表达出行动的意图:

// store.js
import { reactive } from 'vue'

export const store = reactive({
  count: 0,
  increment() {
    this.count++
  }
})
<template>
  <button @click="store.increment()">
    From B: {{ store.count }}
  </button>
</template>

请注意这里点击的处理函数使用了 store.increment(),带上了圆括号作为内联表达式调用,因为它并不是组件的方法,并且必须要以正确的 this 上下文来调用。

除了我们这里用到的单个响应式对象作为一个 store 之外,你还可以使用其他响应式 API 例如 ref() 或是 computed(),或是甚至通过一个组合式函数来返回一个全局状态:

import { ref } from 'vue'

// 全局状态,创建在模块作用域下
const globalCount = ref(1)

export function useCount() {
  // 局部状态,每个组件都会创建
  const localCount = ref(1)

  return {
    globalCount,
    localCount
  }
}

事实上,Vue 的响应性系统与组件层是解耦的,这使得它非常灵活。

Pinia (推荐)

虽然我们的手动状态管理解决方案在简单的场景中已经足够了,但是在大规模的生产应用中还有很多其他事项需要考虑:

  • 更强的团队协作约定

  • 与 Vue DevTools 集成,包括时间轴、组件内部审查和时间旅行调试

  • 模块热更新 (HMR)

  • 服务端渲染支持

Pinia(https://pinia.vuejs.org/zh/) 就是一个实现了上述需求的状态管理库,由 Vue 核心团队维护,对 Vue 2 和 Vue 3 都可用。

现有用户可能对 Vuex 更熟悉,它是 Vue 之前的官方状态管理库。由于 Pinia 在生态系统中能够承担相同的职责且能做得更好,因此 Vuex 现在处于维护模式。它仍然可以工作,但不再接受新的功能。对于新的应用,建议使用 Pinia。

事实上,Pinia 最初正是为了探索 Vuex 的下一个版本而开发的,因此整合了核心团队关于 Vuex 5 的许多想法。最终,我们意识到 Pinia 已经实现了我们想要在 Vuex 5 中提供的大部分内容,因此决定将其作为新的官方推荐。

相比于 Vuex,Pinia 提供了更简洁直接的 API,并提供了组合式风格的 API,最重要的是,在使用 TypeScript 时它提供了更完善的类型推导。

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

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

相关文章

CSS设置盒子阴影

语法 box-shadow: *h-shadow v-shadow blur spread color* inset; 注释: box-shadow向框添加一个或多个阴影. 该属性是由逗号分隔的阴影列表,每个阴影由2-4个长度值、可选的颜色值及可选的inset关键词来规定。省略长度的值是0。 外阴影 a、给元素右边框和下边框加外阴影——把…

生活篇——华为手机去除负一屏

华为手机去除如下图的恶心负一屏 打开华为的应用市场app 进入&#xff1a;我的-设置-国家/地区&#xff08;改为俄罗斯&#xff09;-进入智慧助手检查更新并更新智慧助手。 然后重复开始的操作&#xff0c;将地区改回中国&#xff0c;这样就没有负一屏了。

python自学...

一、稍微高级一点的。。。 1. 闭包&#xff08;跟js差不多&#xff09; 2. 装饰器 就是spring的aop 3. 多线程

拟合案例2:matlab实现分段函数拟合(分段点未知)及源码

案例介绍: 本案是针对一个分段函数中的参数进行拟合,使用的拟合工具是matlab中的lsqcurvefit或nlinfit。函数形式和待拟合参数如下所示。该案例的特殊之处在于分段点也是待拟合参数,因此如何自定义拟合函数,实现分段点的拟合是本案例最大的难点。本案例提供了三种分段函数…

双端队列,优先队列,单调队列

单调队列 单调队列是指一个队列内部元素具有单调性的数据结构 分为单调递增队列和单调递减队列 单调队列满足三个性质&#xff1a; 单调队列也是队列&#xff0c;满足先进先出单调队列必须满足从队头到队尾的单调性排在队列前面的元素比排在队列后面的元素要先进队 代码实现上…

excel统计分析——多组数据的秩和检验

单因素资料不完全满足方差的基本假定时&#xff0c;可进行数据转换后再进行方差分析&#xff0c;但有时数据转换后仍不满足方差分析的基本假定&#xff0c;就只能进行秩和检验了。 多组数据秩和检验的主要方法为Kruskal-Wallis检验&#xff0c;也称为Kruskal-Wallis秩和方差分析…

分布式文件系统 SpringBoot+FastDFS+Vue.js【二】

分布式文件系统 SpringBootFastDFSVue.js【二】 六、实现上传功能并展示数据6.1.创建数据库6.2.创建spring boot项目fastDFS-java6.3.引入依赖6.3.fastdfs-client配置文件6.4.跨域配置GlobalCrosConfig.java6.5.创建模型--实体类6.5.1.FastDfsFile.java6.5.2.FastDfsFileType.j…

__attribute__ ---Compile

Section for attribute attribute_&#xff1f;嵌入式C代码属性怎么定义 https://www.elecfans.com/d/2269222.html section 属性的主要作用是&#xff1a;在程序编译时&#xff0c;将一个函数或者变量放到指定的段&#xff0c;即指定的section 中。 一个可执行文件注意由代…

STM32——菜单(二级菜单)

文章目录 一.补充二. 二级菜单代码 简介&#xff1a;首先在我的51 I2C里面有OLED详细讲解&#xff0c;本期代码从51OLED基础上移植过来的&#xff0c;可以先看完那篇文章&#xff0c;在看这个&#xff0c;然后按键我是用的定时器扫描不会堵塞程序,可以翻开我的文章有单独的定时…

BUGKU-WEB 矛盾

题目描述 进入场景看看&#xff1a; 代码如下&#xff1a; $num$_GET[num]; if(!is_numeric($num)) { echo $num; if($num1) echo flag{**********}; }解题思路 需要读懂一下这段PHP代码的意思明显是一道get相关的题目&#xff0c;需要提供一个num的参数,然后需要传入一个不…

【数据结构】顺序栈和链式栈的简单实现和解析(C语言版)

数据结构——栈的简单解析和实现 一、概念二、入栈&#xff08;push&#xff09;三、出栈&#xff08;pop&#xff09;四、顺序栈简单实现 &#xff08;1&#xff09;进栈操作&#xff08;2&#xff09;出栈操作 一、概念 本篇所讲解的栈和队列属于逻辑结构上的划分。逻辑结构…

GPDB - 高可用 - FTS机制(一):探测成功

GPDB - 高可用 - FTS机制&#xff08;一&#xff09;&#xff1a;探测成功 作为GreenPlum高可用的核心功能&#xff0c;FTS&#xff08;Fault Tolerance Server&#xff09;进程负责故障检测。该进程是master上的一个子进程&#xff0c;可以快速检测到primary或者mirror是否宕机…

PyTorch深度学习快速入门教程 - 【小土堆学习笔记】

小土堆Pytorch视频教程链接 声明&#xff1a; 博主本人技术力不高&#xff0c;这篇博客可能会因为个人水平问题出现一些错误&#xff0c;但作为小白&#xff0c;还是希望能写下一些碰到的坑&#xff0c;尽力帮到其他小白 1 环境配置 1.1 pycharm pycharm建议使用2020的&…

【C语言】指针的进阶篇,深入理解指针和数组,函数之间的关系

欢迎来CILMY23的博客喔&#xff0c;本期系列为【C语言】指针的进阶篇&#xff0c;深入理解指针和数组&#xff0c;函数之间的关系&#xff0c;图文讲解其他指针类型以及指针和数组&#xff0c;函数之间的关系&#xff0c;带大家更深刻理解指针&#xff0c;以及数组指针&#xf…

LeetCode Python - 16.最接近的三数之和

目录 题目答案运行结果 题目 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;nums [-1,2,1,-4],…

Vulnhub靶场 DC-6

目录 一、环境搭建 二、主机发现 三、漏洞复现 1、wpscan工具 2、后台识别 dirsearch 3、爆破密码 4、rce漏洞利用 activity monitor 5、rce写shell 6、新线索 账户 7、提权 8、拿取flag 四、总结 一、环境搭建 Vulnhub靶机下载&#xff1a; 官网地址&#xff1a…

凭证获取:Linux凭证获取

目录 shadow文件详解 1.Shadow文件的组成与作用 2.破解Shadow文件内容 利用strace记录密码 shadow文件 1.Shadow文件的组成与作用 在Linux中&#xff0c;/etc/shadow文件又被称为“影子文件”&#xff0c;主要用于存储Linux文件系统中的用户凭据信息。该文件只能由root权…

【日常聊聊】新年新征程:迎接学习的挑战

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 结语 我的其他博客 前言 随着新的一年的到来&#xff0c;程序员们站在了全新的起点。这是一个充满机遇和挑战的时刻&#xff0…

【C++初阶:类和对象(下篇)】初始化列表 | static成员 | 友元

目录 一、构造函数构造函数体赋值&#x1f43e;初始化列表&#x1f43e;&#x1f4a6; explicit关键字 二、static成员&#x1f43e;概念**&#x1f4a6; 关于静态的特性** 三、友元&#x1f4a6; **友元函数**&#x1f4a6; **友元类** **四、内部类** 一、构造函数 构造函数…

Spring 事务原理总结四

作为一名认知有限的中国人&#xff0c;我对年的喜爱&#xff0c;胜过其他一切&#xff0c;因为它给了我拒绝一切的合理理由。每到这个时候&#xff0c;我都会用各种理由来为自己的不作为开脱&#xff0c;今年亦是如此。看着频频发出警报的假期余额&#xff0c;我内心的焦躁变得…