vuex / pinia / redux、vue-router

165 阅读4分钟

一、Vuex4

Vuex4 匹配 Vue3,Vuex3 匹配 Vue2。

统一存储和管理应用中所有组件的共享状态。适用于:

  • 多个组件依赖于同一状态时,像兄弟组件、跨层级组件通信时,它们的共享数据传递会非常繁琐。
  • 不同组件的行为都需要改变同一状态时。 image.png Vuex 的 5 个核心概念:
  • state 用于存放响应式数据
  • getter 可以基于 state 进行一些计算操作。
  • mutation:同步任务,包含一个事件类型type和对应的回调函数来修改 state,通过store.commit触发。理论上是修改 state 的唯一途径。
  • action:异步任务,通过store.dispatch触发。
  • module:当应用的状态非常复杂时可以将 store 拆分成 module,每个模块都有自己的 state、getter、action 等。

1. Action 和 Mutation 的区别

  • Action 提交的是 Mutation,而不是直接改变状态。
  • Mutation 必须是同步函数,而 Action 可以包含异步操作。
  • 提交的方式不同:commit 和 dispatch。

2. vuex 和单纯的全局对象区别

  • vuex 存储的状态是响应式的。如果 store 中的 state 改变,那相应的组件也会更新。
  • vuex 中不能直接修改 state,改变 state 只能通过commit mutation,这有利于我们跟踪状态的变化。

3. 无法持久化

Vuex 只是在内存中保存状态,刷新后就会丢失,如果要持久化就需要保存起来。

  • 将 state 存入localStoragemutation触发时也会将相应的 state 变化更新到localStorage
  • 可以使用第三方插件vuex-persist实现 vuex 持久化存储。

4. 不能跨页面

vuex 的数据是保存在标签隔离的内存空间里面,跨页面的话就不是一个 vue 实例了,数据就没了。可以通过 localStorage 解决。

5. 怎么使用?举例一个流程

  1. createStore()定义一个 store,传入 state 和 mutations。
  2. 组合式 API 中要调用useStore才能在 setup 函数中访问 store。然后调用store.commit()方法触发 mutaion、用store.dispatch()触发 action。
// 定义一个 store,传入 state 和 mutations
import { createStore } from 'vuex';
const store = createStore({ 
    state,
    mutations
})
// 触发事件,更新state
import { useStore } from 'vuex';
const store = useStore();
store.commit("saveUserInfo", info);
store.dispatch('asyncFunction')

mapState 可以批量更新 Vuex 的 state。

二、Pinia

官方推荐 Vue3 搭配 Pinia。Pinia2 既支持 Vue2 也支持 Vue3。

1. vuex4 和 pinia2 区别

  • Pinia 比较轻巧,对TS的支持更友好,Pinia2 同时支持Vue2、Vue3。
  • Pinia 去除Mutation,Action 支持同异步。
  • 相比于 Vuex 应用的单一 store 和多个 module 的嵌套结构,Pinia 可以定义多个Store,每个 store 都是互相独立的、无需嵌套module,使得数据的结构更加扁平化。

2. 怎么使用?举例一个流程

// store 文件
import { defineStore } from 'pinia'; // 定义一个 store
export const useStore = defineStore('anime', {
    state:
    
    actions: {
    
});
// 使用
import { useStore } from '';

三、Redux

  • action:一个描述事件的对象,dispatch(action)可以理解为触发一个事件;
  • reducer:类似事件监听器,会根据接收到的 action 处理事件并返回新的 state ;
  • react 中数据是不可变的,因此 reducer 不能直接修改 state。

Redux 执行流程举例:

  • 当用户点击按钮后,会 dispatch 一个 action 到 store 里;
  • store 会将之前的 state 和当前的 action 传参到 reducer 函数中执行,reducer 会返回新的 state;
  • 然后相应的 store.subscribe 方法里的回调函数会执行,相关组件也会重新渲染。

四、vue-router

router 和 route 的区别

  • router 是 VueRouter 的实例对象,是一个全局的路由对象,包含了所有路由的对象和属性。
  • route 是一个当前激活的路由对象,每个路由都会有一个 route 对象,可以获取一些数据,如:name、path、params、query等。

动态路由

当我们需要将给定匹配模式的路由映射到同一个组件时,例如 User 组件需要对不同 ID 的用户进行渲染。那么在路径参数里可以用/users/:id来动态匹配,其中 :id就是动态路径参数

路由懒加载

路由懒加载:将不同路由对应的组件分割成不同的代码块进行打包,然后当路由被访问的时候才加载对应组件,有利于加快页面加载速度。

// 动态导入
const Home = () => import('../components/Home.vue');

router-view 组件

该标签会根据当前的 url 动态渲染出相对应的组件。

router-link 组件

<router-link>会被渲染成一个<a>标签,to 会渲染成 href 属性。

对比<a>标签,通过<router-link>进行跳转时不会跳转到新的页面,也不会重新渲染。只更新变化的部分从而减少了DOM性能消耗。

导航守卫

导航守卫就是路由跳转过程中的一些钩子函数,例如在路由切换前进行身份验证、权限检查等。

Vue Router 提供了多种导航守卫:

  • 全局前置守卫 beforeEach:会在每个路由切换前都执行;
  • 全局后置守卫 afterEnter:只在特定的路由切换前执行