尤大大:理论上来说,每一个 Vue 组件实例都已经在“管理”它自己的响应式状态了。
🤦♂️:不会吧🤡!既然Vue本身具备状态管理的能力,我们还有必要引入Pinia🍍或者Vuex等状态管理工具吗?
Vue实例作为状态管理器应该怎么实现?按照vue官网我们来实践一次。
我们以Vue3为例,实现一个状态管理。首先创建一个名为auth.ts
的ts文件,这文件将用来定义状态管理器。
ts
复制代码
`import { reactive, readonly } from 'vue';
export interface Account {
name: string;
}
export interface AuthStore {
account: Account | null;
isAuthed: boolean;
}
const auth = reactive<AuthStore>({
isAuthed: false,
account: null,
});
export const useAuthStore = () => {
return {
state: readonly(auth),
actions: {
login(account: Account) {
auth.isAuthed = true;
auth.account = account;
},
logout() {
auth.isAuthed = false;
auth.account = null;
},
},
};
};
export default useAuthStore;`
接下来创建两个组件Info.vue
和Login.vue
,在这两个组件中使用我们自定义的useAuthStore
状态管理器。
使用import { useAuthStore } from '../auth';
来引入这个store
,通过useAuthStore()
获取store
实例。
html
复制代码
`<script setup lang="ts">
import { ref } from 'vue';
import { useAuthStore } from '../auth';
const username = ref('');
const { state, actions } = useAuthStore();
</script>
<template>
<div>
<div v-if="!state.isAuthed">
<div>
<span>用户名:</span>
<input v-model="username" />
</div>
<button @click="actions.login({ name: username })">登录</button>
</div>
<button v-if="state.isAuthed" @click="actions.logout">退出</button>
</div>
</template>`
html
复制代码
`<script setup lang="ts">
import { useAuthStore } from '../auth';
const { state } = useAuthStore();
</script>
<template>
<div>
<div v-if="!state.isAuthed">
<h1>请登录</h1>
</div>
<div v-if="state.isAuthed">
<h1>欢迎:{{ state.account?.name }}</h1>
</div>
</div>
</template>`
使用reactive()
是因为State
是一个对象,当然也可以使用ref()
。但是,就必须使用.value
来访问数据,这并不是想要的效果。
为了实现单向数据流useAuthStore
中的State
采用Vue3的readonly
API将状态对象置为只读的对象,这样避免了在使用该状态对象时直接操作State
的情况。因此想要修改State
就只能通过Actions
,就像下图这样:
虽然 Vue2 中没有reactive()
或ref()
API,但是事实是 Vue2 也实现简单的状态管理。利用 Vue2 中的Vue.observable()
可以将一个普通对象转换为响应式对象,从而实现当State
变更时驱动View
更新。
🤔需要注意的是 Vue2 中没有 readonly()
API,因此在这个例子中,我们直接使用 auth
作为状态。要确保状态不被意外修改,你需要确保只在 actions
对象中的方法内修改状态。
ts
复制代码
`import Vue from 'vue';
export interface Account {
name: string;
}
export interface AuthStore {
account: Account | null;
isAuthed: boolean;
}
const auth = Vue.observable<AuthStore>({
isAuthed: false,
account: null,
});
export const useAuthStore = () => {
return {
state: auth,
actions: {
login(account: Account) {
auth.isAuthed = true;
auth.account = account;
},
logout() {
auth.isAuthed = false;
auth.account = null;
},
},
};
};
export default useAuthStore;`
在vue2中将useAuthStore()
解构进组件的data
中即可。
html
复制代码
`<template>
...
</template>
<script>
import { useAuthStore } from '../auth';
export default {
data() {
const { state, actions } = useAuthStore();
return {
authState: state,
login: actions.login,
logout: actions.logout,
};
},
};
</script>`
首先从 useAuthStore
文件中导入 useAuthStore
函数。然后,在组件的 data
选项中,我们调用 useAuthStore()
并将返回的 state
和 actions
解构。接下来,我们将 state
、login
和 logout
添加到组件的响应式数据中,以便在模板中使用。最后,在模板中,我们根据 authState.isAuthed
的值显示不同的内容,并使用 login
和 logout
方法处理按钮点击事件。
在 SSR 环境下,应用模块通常只在服务器启动时初始化一次。同一个应用模块会在多个服务器请求之间被复用,而我们的单例状态对象也一样。如果我们用单个用户特定的数据对共享的单例状态进行修改,那么这个状态可能会意外地泄露给另一个用户的请求。我们把这种情况称为跨请求状态污染。
如果使用 SSR,则需要避免所有请求共享同一存储。在这种情况下,需要为每个请求创建一个单独的存储并提供/注入它。
ts
复制代码
`// app.js (在服务端和客户端间共享)
import { createSSRApp } from 'vue'
import { createStore } from './store.js'
// 每次请求时调用
export function createApp() {
const app = createSSRApp(/ ... /)
// 对每个请求都创建新的 store 实例
const store = createStore(/ ... /)
// 提供应用级别的 store
app.provide('store', store)
// 也为激活过程暴露出 store
return { app, store }
}`
开发 Vue 应用时,状态管理是一个重要的考虑因素。Vue 自身提供了一些状态管理工具,如 ref
和 reactive
,但在某些情况下,引入专门的状态管理库(如 Pinia 或 Vuex)可能会带来更多的便利和优势。那么,在什么情况下你真的需要 Pinia?让我们来总结一下。
在以下场景下,使用 Vue 自身的状态管理就可以完美解决问题:
在这些场景下,使用 Vue 自身的状态管理,如 ref
和 reactive
,可以满足应用的需求,而无需引入额外的状态管理库。
小型项目通常具有以下特点:
这些小型项目可能包括个人博客、简历网站、小型企业网站、原型和概念验证等。
选择是否一开始就使用 Pinia 取决于项目的需求和预期的复杂性。以下是一些建议:
总之,在决定是否从一开始就使用 Pinia 时,您应该权衡项目的需求、预期的复杂性和团队的经验。如果您认为 Pinia 可以为您的项目带来长期的好处,那么从一开始就使用它是合理的。
没有最好的架构,只有最合适的选择。对于小型项目和初学者,简单的状态管理方法可能是一个合适的选择。然而,在大型、复杂的应用程序中,使用像 Pinia 这样的专门的状态管理库可能更加合适,因为它们提供了更强大的功能、更好的开发体验和更强的约定。
关于项目是否应该使用第三方的状态管理库,完全取决于项目自身和开发团队的选择!
如果您有不同的看法,以自身看法为准
原网址: 访问
创建于: 2023-10-10 09:20:13
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论