vue3 + ts + pinia 网页端 和 移动端集中式状态管理

13 篇文章 1 订阅
7 篇文章 0 订阅

在这里插入图片描述

一、Pinia 介绍:

  • 官网
  • Pinia 是 Vue 的存储库,可以跨组件/页面全局共享,数据是存储在缓存中。

优点:
1、pinia 符合直觉,易于学习。
2、pinia 是轻量级状态管理工具,大小只有1KB。
3、pinia 模块化设计,方便拆分。
4、pinia 没有 mutations ,直接在 actions 中操作 state ,通过 this.xxx 访问响应的状态,尽管可以直接操作 state ,但是还是推荐在 actions 中操作,保证状态不被以外的改变。
5、store 的 actions 被调度为常规的函数调用,而不是使用 dispatch 方法或者是 MapAction 辅助函数,这是在 Vuex 中很常见的。
6、支持多个 store 。
7、支持 Vuex devtools(调试工具)、SSR、webpack 代码拆分。

二、移动端

  • uni-app 为例

1、安装 pinia 和 pinia-plugin-persistedstate

npm install pinia@2.0.30 --legacy-peer-deps
npm install pinia-plugin-persistedstate

2、创建 store

  • src 目录中创建 stores文件夹,并创建 index.ts文件,文件实例代码如下:
import { createPinia } from "pinia";
import persist from "pinia-plugin-persistedstate";  // 持续化插件

// 创建 Pinia 实例
const pinia = createPinia();

// 使用 持久化 插件
pinia.use(persist);

// 导出 pinia
export default pinia;

// 模块统一导出(业务 store)
export * from "./modules/user";

3、在 main.ts 中挂载 pinia,示例代码如下:

import { createSSRApp } from "vue";
import App from "./App.vue";

// 导入 pinia 实例
import pinia from "./store/index";

export function createApp() {
  // 创建 vue 实例
  const app = createSSRApp(App);

  // 使用 pinia
  app.use(pinia);

  return {
    app,
  };
}

4、创建业务 Store,示例代码如下:

  • 文件夹 Store 中创建 modules 文件夹,再文件夹中创建 user.ts 文件,文件代码如下:
import { defineStore } from "pinia";
import { ref } from "vue";

// 创建 store
export const userName = defineStore(
  "user",
  () => {
    // 定义默认用户名称
    const name = ref("欢迎使用 uni-app");

    // 修改用户名称方法
    const setUserName = (val: any) => {
        name.value = val;
    };

    // 返回
    return {
      name,
      setUserName,
    };
  },
  {
    // 移动端持久化配置
    persist: {
      storage: {
        getItem(key) {
          return uni.getStorageSync(key);
        },
        setItem(key, value) {
          uni.setStorageSync(key, value);
        },
      },
    },
  }
);

5、页面中使用 Store,示例代码如下:

<template>
  <view class="container">
    <view>用户名称:{{ userNameStore.name }}</view>
    <view>
      <button type="default" size="mini" @click="setUserNameHandle">修改用户名称</button>
    </view>
  </view>
</template>

<script setup lang="ts">
import { userName } from '@/store'
const userNameStore = userName()

// 修改用户名称
const setUserNameHandle = () => {
  userNameStore.setUserName('欢迎使用 uni-app')
}

</script>

<style lang="scss">
.container {
  padding: 30rpx;

  view {
    margin-top: 30rpx;
  }

  button {
    margin-right: 30rpx;
  }
}
</style>

二、网页端

1、安装 pinia 和 pinia-plugin-persistedstate

npm install pinia

2、创建 store

  • 1、在项目src目录中创建 stores文件夹,并创建index.ts文件,文件实例代码如下:
import { createPinia } from "pinia";

// 创建 pinia
const pinia = createPinia();

// 导出 pinia
export default pinia;

// 模块统一导出
export * from "./modules/userInfo";

3、在 main.ts 中挂载 pinia,示例代码如下:

import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";

// 导入 pinia
import pinia from "./stores/index";
// 持久化存储
import { createPersistedState } from 'pinia-plugin-persistedstate'
pinia.use(
  createPersistedState({
    auto: true	// 启动所有 Store 默认持久化
  })
)

// 挂载 pinia
const app = createApp(App);
app.use(pinia);
app.mount("#app");

4、创建业务 Store,示例代码如下:

import { defineStore } from 'pinia'

export const userStore = defineStore('user', {
  state: () => ({
    userInfo: {
      userName: '中华人民共和国',
      age: 30
    }
  }),
  actions: {
    /**
     * 修改用户信息方法
     * @param { string } userName  用户名称
     * @param { number } age 年龄
     */
    changeUserInfo(userName: string, age: number) {
      this.userInfo.userName = userName
      this.userInfo.age = age
    }
  },
  getters: {
    /**
     * 获取用户信息方法
     * @param state
     * @returns
     */
    getUserInfo: (state) => state.userInfo
  }
})

5、页面中使用 Store,示例代码如下:

<template>
  <el-row class="mb-4">
    <el-button type="primary">{{ age }}</el-button>
    <el-button type="warning" @click="changeAge">新增</el-button>
    <el-button type="warning" @click="resetPiniaHandle">重置</el-button>
  </el-row>
</template>

<script setup lang="ts">
import { userStore } from '@/stores'
const userInfo = userStore()
const { age, changeAge } = toRefs(userInfo)

// 重置方法
const resetPiniaHandle = () => {
  userInfo.$reset()
}
</script>

<style lang="scss" scoped></style>

6、持久化配置

import { defineStore } from 'pinia'

export const userStore = defineStore('user', {
  state: () => ({
    userName: '中华人民共和国',
    age: 30
  }),
  actions: {
    /**
     * 修改用户信息方法
     * @param { string } userName  用户名称
     */
    changeUserName(userName: string) {
      this.userName = userName
    },
    /**
     * 修改年龄方法
     * @param { number } age  年龄
     */
    changeAge() {
      this.age++
    }
  },
  getters: {
    /**
     * 获取用户信息方法
     * @param state
     * @returns
     */
    getUserName: (state) => state.userName,
    /**
     * 获取年龄方法
     * @param state
     * @returns
     */
    getAge: (state) => state.age
  },
  // persist: true  // 默认全部字段持久化
  //按需配置数据持久化 这里指定变量num保持持久化
  persist: {
    //默认名称为当前store唯一标识 这里即home
    key: 'ageStore',
    //默认localStorage 本地储存
    //这里建议临时储存sessionStorage 也可写成window.sessionStorage
    storage: sessionStorage,
    //默认当前store里的所有变量都持久化
    paths: ['age']
  }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W.Y.B.G

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值