首页 > 其他分享 >第三十五篇 vue - 应用规模化 - 状态管理 - Pinia

第三十五篇 vue - 应用规模化 - 状态管理 - Pinia

时间:2023-04-02 11:57:02浏览次数:34  
标签:count 状态 第三十五 vue Vue Pinia 组件 store

什么是状态管理

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

<script>
export default {
  // 状态
  data() {
    return {
      count: 0
    }
  },
  // 动作
  methods: {
    increment() {
      this.count++
    }
  }
}
</script>

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

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

  1、状态:驱动整个应用的数据源;
  
  2、视图:对状态的一种声明式映射;
  
  3、交互:状态根据用户在视图中的输入而作出相应变更的可能方式。
然而,当我们有多个组件共享一个共同的状态时,就没有这么简单了

1、多个视图可能都依赖于同一份状态

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

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

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

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

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

在选项式 API 中,响应式数据是用 data() 选项声明的。在内部,data() 的返回值对象会通过 reactive() 这个公开的 API 函数转为响应式

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

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

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

export default {
  data() {
    return {
      store
    }
  }
}
</script>

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

export default {
  data() {
    return {
      store
    }
  }
}
</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

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

1、更强的团队协作约定

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

3、模块热更新 (HMR)

4、服务端渲染支持
Pinia 就是一个实现了上述需求的状态管理库,由 Vue 核心团队维护,对 Vue 2 和 Vue 3 都可用。

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

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

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

标签:count,状态,第三十五,vue,Vue,Pinia,组件,store
From: https://www.cnblogs.com/caix-1987/p/17280189.html

相关文章

  • 第三十四篇 vue - 应用规模化 - 服务端渲染 - SSR
    总览什么是SSRSSR-服务端渲染Vue.js是一个用于构建客户端应用的框架。默认情况下,Vue组件的职责是在浏览器中生成和操作DOMVue也支持将组件在服务端直接渲染成HTML字符串,作为服务端响应返回给浏览器,最后在浏览器端将静态的HTML“激活”(hydrate)为能够交互的客户端......
  • 第三十六篇 vue - 应用规模化 - 路由
    客户端vs服务端路由服务端路由指的是服务器根据用户访问的URL路径返回不同的响应结果。当我们在一个传统的服务端渲染的web应用中点击一个链接时,浏览器会从服务端获得全新的HTML,然后重新加载整个页面。然而,在单页面应用中,客户端的JavaScript可以拦截页面的跳转请求,动......
  • 第三十七篇 vue - 应用规模化 - 测试
    为什么需要测试自动化测试能够预防无意引入的bug,并鼓励开发者将应用分解为可测试、可维护的函数、模块、类和组件。这能够帮助你和你的团队更快速、自信地构建复杂的Vue应用。与任何应用一样,新的Vue应用可能会以多种方式崩溃,因此,在发布前发现并解决这些问题就变得十分重要......
  • vue3 directive自定义指令
    importstorefrom'../store'//新建jsexportdefault{install(app){//权限控制,没有相关的权限,则删除模块app.directive('permission',{mounted(el,val){if(el&&!store.state.rule.includes(val.valu......
  • vue+webSocket+springCloud消息推送交互
    一、后台代码:1、pom里面加上依赖;<!--webSocket坐标依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>2.2.4.RE......
  • Vue3学习笔记(7.0)
    Vue3计算属性计算属性关键词:computed计算属性在处理一些复杂逻辑时是很有用的。可以看下以下反转字符的例子:<!--*@Author:[email protected]*@Date:2023-03-3008:30:35*@LastEditors:Mei*@LastEditTime:2023-03-3008:33:36*@FilePath:\vscode\vue_co......
  • Vue3学习笔记(4.0)
    vue.js为两个最为常用的指令提供了特别的缩写://全称<av-bind:href="url"></a>//缩写<a:href="url"></a>v-on缩写//全称<av-on:click="doSomething"></a>//缩写<a@click="doSonthing"></a>条件判断条件判断使......
  • vue之表单处理
    vue之表单处理(一)实验介绍基本用法文本多行文本单选按钮复选框多个复选框选择框实验介绍在日常的开发中,表单随处都被使用到,如:登录,问题反馈功能等。对表单的数据收集和绑定也是很常规的工作。在一般开发中处理表单,需要通过操作DOM来实现,是一个相对繁琐且低效率的工作......
  • 使用vue四种方法写一个计算器
    第一种:使用computed计算属性1.创建项目,引入vue<scripttype="text/javascript"src="js/vue.js"></script>2.实例化vue<divid="app"></div><script>varvm=newVue({el:"#app",//通过el与di......
  • VueRouter中的滚动行为
    参考:https://github.com/vuejs/vue-router/blob/dev/docs/zh/guide/advanced/scroll-behavior.md滚动行为观看VueSchool的如何控制滚动行为的免费视频课程(英文)使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。vue-router......