状态管理技术选型

目录

状态管理技术选型

1. Pinia概述

2. Vuex的应用

2.1 Vuex 的使用

2.2 测试组件

3. Pinia 的应用

3.1 Pinia 的使用

3.2 Pinia 的持久化

3.3 测试组件

4. Pinia 与 Vuex的比较总结


状态管理技术选型

1. Pinia概述

前端项目需要使用到状态管理框架,目前社区流行的有Vuex和Pinia两个框架。经过对比后,我们选择Pinia作为我们的状态管理库。下面将分点说明Pinia特点。

  • 背景

Pinia是根据Vue3而设计的,相比于Vuex来说历史包袱更少,它吸收了Vuex下个版本的很多核心概念以及项目开发经验而产生。

  • 框架量级

Pinia是轻量级的,体积很小。

  • 开发体验

Pinia有完整的 TypeScript 支持,与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易。

在使用上可以使用贴近Vuex的API风格来编写代码,也可以使用Vue3组合式API的风格来编写代码。

Store 的 action 被调度为常规的函数调用,而不是使用 dispatch 方法或 MapAction 辅助函数,这在 Vuex 中很常见。

  • 社区和生态系统

Pinia目前是Vue.js生态系统中增长最快的状态管理库之一,社区正在快速增长。然而Vuex毕竟是Vue.js核心团队推荐的状态管理库,拥有庞大的社区,核心团队成员做出了重大贡献。 Stack Overflow 上很容易找到 Vuex 错误的解决方案。

  • Pinia能力评估

接下来是评估Pinia是否能满足我们项目对于状态管理库的要求。

  1. 跨组件/页面数据共享(支持)

  2. 热更新(支持)

  3. 插件机制(支持)

  4. Devtools(支持)

  5. 数据持久化(支持,可通过插件机制实现)

2. Vuex的应用

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

2.1 Vuex 的使用

  • 安装Vuex

yarn add vuex@next --save
# 或者使用 npm
npm install vuex@next --save
  • 安装Vuex 后在main.ts入口文件注册Vuex

import { createApp } from 'vue';
import App from './App.vue';
import router from './router/index';
import store from './vuex/store'; // 引入store对象
​
const app = createApp(App);
app.use(router);
app.use(store); // 把store对象添加到vue实例上
app.mount('#app');
  • src文件夹下新建store文件夹,然后在store文件夹下新建store.ts文件

import { Store, createStore } from 'vuex';
// 配置vue+ts的项目里面使用vuex
declare module '@vue/runtime-core' {
  // declare your own store states
  interface State {
    count: number;
    list: string[];
    msg: string;
  }
​
  // provide typings for `this.$store`
  interface ComponentCustomProperties {
    $store: Store;
  }
}
​
const store = createStore({
  // 数据
  state() {
    return {
      count: 1,
      list: ['马总', '刘总'],
      msg: '你好vue',
    };
  },
  // 方法 Mutations里面的函数必须是同步操作
  mutations: {
    // 方法的作用修改state中的变量,state是必须默认参数
    increment(state: any) {
      state.count++;
    },
    // 增加一个带参数的mutations方法
    setCount(state: any, num: number) {
      state.count = num;
    },
    setMsg(state: any, msg: string) {
      state.msg = msg;
    },
  },
  // 计算属性
  getters: {
    // 获取修饰后的name,第一个参数state为必要参数,必须写在形参上
    reverseMsg(state: any) {
      return state.msg.split('').reverse().join('');
    },
    num(state: any) {
      return state.count + 10;
    },
  },
  // 执行mutations里面的方法 异步操作放在actions
  actions: {
    // 默认第一个参数是context,其值是复制的一份store
    increment(context) {
      // 执行mutations里面的increment
      context.commit('increment');
    },
    // action就是去提交mutation的,什么异步操作都在action中消化了,最后再去提交mutation的
    // 直接将context结构掉,解构出commit,下面就可以直接调用了
    setMsg({ commit }, msg: string) {
      // 执行mutations里面的increment
      setTimeout(() => {
        commit('setMsg', msg);
      }, 1000);
    },
  },
});
​
// vuex的模块
// import storeModule1 from './storeModule1';
// import storeModule2 from './storeModule2';
​
// const store = createStore({
//   modules: {
//     storeModule1: storeModule1,
//     storeModule2: storeModule2,
//   },
// });
​
export default store;

2.2 测试组件

新建test.vue的测试组件,使用Vuex



 

3. Pinia 的应用

Pinia 是 Vue 的状态管理库,它允许您跨组件/页面共享状态。

3.1 Pinia 的使用

  • 安装Pinia

yarn add pinia# 
#或者使用 npm
npm install pinia
  • 安装pinia后在main.ts入口文件注册pinia

import { createApp } from 'vue';
import App from './App.vue';
import router from './router/index';
import { createPinia } from 'pinia';
​
const app = createApp(App);
app.use(router);
const pinia = createPinia();
app.use(pinia);
app.mount('#app');
  • src文件夹下新建store文件夹,然后在store文件夹下新建mian.ts文件

import { defineStore } from 'pinia';
​
type User = {
  name: string;
  age?: number;
  sex?: string;
  msg?: string;
};
​
const login = (user: User): Promise => {
  return new Promise(resolve => {
    setTimeout(() => {
      user.msg = '登陆成功';
      resolve(user);
    }, 2000);
  });
};
​
export const useMainStore = defineStore({
  id: 'mian',
  state: () => ({
    name: '超级管理员',
    count: 0,
    user: {},
  }),
​
  // computed 计算属性
  getters: {
    nameLength: state => state.name.length,
    newName(): string {
      return `$-${this.name}--${this.nameLength}`;
    },
  },
​
  // methods 可以做同步、异步 提交state
  actions: {
    setCount(count: number) {
      this.count = count;
    },
    setUser(user: User) {
      this.user = user;
    },
    async setUserLogin(user: User) {
      const result = await login(user);
      this.user = result;
      this.setSex('女');
    },
    setSex(sex: string) {
      this.user.sex = sex;
    },
  },
});
​

3.2 Pinia 的持久化

  • 在store文件夹下封装一个Pinia 插件,文件名为piniaPlugin.ts

import { PiniaPluginContext } from 'pinia';
import { toRaw } from 'vue';
​
type Options = {
  key?: string;
};
​
const _piniaKey_ = 'pinia';
const setStorage = (key: string, value: any) => {
  localStorage.setItem(key, JSON.stringify(value));
};
const getStorage = (key: string) => {
  return localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string) : {};
};
​
export const piniaPlugin = (options: Options) => {
  return (context: PiniaPluginContext) => {
    const { store } = context;
    const data = getStorage(`${options?.key ?? _piniaKey_}-${store.$id}`);
    store.$subscribe(() => {
      setStorage(`${options?.key ?? _piniaKey_}-${store.$id}`, toRaw(store.$state));
    });
    return {
      ...data,
    };
  };
};

  • 在main.ts入口文件注册Pinia 持久化插件

import { createApp } from 'vue';
import App from './App.vue';
import router from './router/index';
import { createPinia } from 'pinia';
import { piniaPlugin } from './store/piniaPlugin';
​
const app = createApp(App);
app.use(router);
const pinia = createPinia();
pinia.use(piniaPlugin({ key: 'pinia' }));
app.use(pinia);
app.mount('#app');

3.3 测试组件

新建test.vue的测试组件,使用Pinia

状态管理技术选型_第1张图片

4. Pinia 与 Vuex的比较总结

状态管理技术选型_第2张图片

你可能感兴趣的:(前端方案,javascript,前端,typescript,vue.js)