pinia的使用和封装

前言

在使用vue3项目开发过程中通常会使用状态管理库来获取或存储数据已在其他页面上使用。vuex/pinia目前是主流方式。

pinia的使用

pinia官网文档:pinia.vuejs.org/zh/getting-...

  • 安装
js 复制代码
 npm install pinia
 或
 yarn add pinia
  • 引入到项目 --简单引入 后面有介绍类似的vuex似引入方式
js 复制代码
 // main.js
 import { createApp } from 'vue'
 import App from './App.vue'
 import router from './router'
 
 // 引入pinia
 import { createPinia } from 'pinia'
 
 // 创建pinia实例
 const pinia = createPinia()
 
 const app = createApp(App)
 app.use(pinia)
 app.use(router).mount('#app')

创建store文件夹,可以不区分模块,个人习惯觉得区分模块会让代码阅读起来更加清晰,结构如下:

  • pinia使用 pinia使用有两种格式 选项式格式setup函数格式

  • 选项式

js 复制代码
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0}),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})
  • setup函数格式
js 复制代码
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})
  • 页面使用
html 复制代码
 <script setup>
    import { useCounterStore } from '@/store/user.js'
    // 在组件内部的任何地方均可以访问变量 `store` 
    const store = useCounterStore()
</script>
  • state储存变量

  • actions 修改state的值或写异步调用的方法

  • getter 等同于 store 的 state 的计算值。可以通过 defineStore() 中的 getters 属性来定义它们。推荐 使用箭头函数,并且它将接收 state 作为第一个参数

  • 嵌套 store 如果一个 store 使用另一个 store,你可以直接导入并在 actionsgetters 中调用 useStore() 函数。然后你就可以像在 Vue 组件中那样使用 store。

js 复制代码
import { useUserStore } from './user'

export const useCartStore = defineStore('cart', () => {
  const user = useUserStore()
  const list = ref([])

  const summary = computed(() => {
    return `${user.name}${price.value}.`
  })

  function purchase() {
    return apiPurchase(user.id, this.list)
  }

  return { summary, purchase }
})

数据持久化

store中的数据,刷新页面后就丢失了,如果想保留这些数据,就要用到数据持久化了。

推荐使用**pinia-plugin-persistedstate**

  • 安装插件
js 复制代码
npm install pinia-plugin-persistedstate
  • 使用
js 复制代码
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
  • 开启数据持久化
  • 代码中persisttrue,就可以开启数据持久化了。如下:
js 复制代码
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
  state: () => {
    return {
      userName: '哈哈',
    }
  },
  //开启持久化
  persist: true,
  // 或者使用更详细的配置
  // persist: {
  //   key: 'my-user-store', // 自定义存储的键名
  //   storage: localStorage, // 指定存储方式 (默认是 localStorage)
  //   paths: ['name', 'isLoggedIn'] // 只持久化 state 中的特定字段
  // }
})

pinia封装

创建store/index.js

js 复制代码
//引入pinia
import { createPinia } from 'pinia'
//创建pinia实例
const pinia = createPinia()
//导出pinia 用来引入到main.js 来实现在项目中只需引入这一个文件
export default pinia

import { ElMessage, ElMessageBox } from 'element-plus'
//引入各个模块
import useUserStore from './modules/user'
import useHeadStore from './modules/head'
import useOnlineStore from './modules/online'
import useCommonStore from './modules/common'
import useIntegralStore from './modules/integral'
import useConversationStore from './modules/conversation'

//导出各个模块
export const userStore = useUserStore(pinia)
export const headStore = useHeadStore(pinia)
export const onlineStore = useOnlineStore(pinia)
export const commonStore = useCommonStore(pinia)
export const integralStore = useIntegralStore(pinia)
export const conversationStore = useConversationStore(pinia)

// 平台来源
export const platformSource = 'info_source_001'

// element消息弹窗
export const elMessage = ElMessage
export const elMessageBox = ElMessageBox
  • 注册到main.js
js 复制代码
 // main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

// 引入封装的pinia文件
import pinia from '@/store/index.js'

const app = createApp(App)
//注册封装的pinia
app.use(pinia)

app.use(router).mount('#app')

// 定义特性标志
window.__VUE_PROD_DEVTOOLS__ = false
window.__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ = false
  • 使用
html 复制代码
<template>
  <div class="helper-container"></div>
</template>

<script setup>
// 引入 store 
import { onlineStore } from "@/store";
import { ref } from "vue";
// -----------------------------------------------数据----------------------------------------
const timerId = ref(null);
// -----------------------------------------------方法----------------------------------------

// 打开在线咨询
function openOnline() {
   //使用 store
  onlineStore.setOnlineShow();
}
</script>

<style lang="scss" scoped>
</style>
相关推荐
星链引擎14 小时前
大模型4sapi智能聊天机器人 技术架构核心实现与行业赋能指南
前端
前端付豪14 小时前
为啥升Vue3 有啥优势?
前端·javascript·vue.js
夜雨深秋来14 小时前
BEM方法论:构建可维护的前端CSS架构
前端·css
举个栗子dhy14 小时前
第四章、路由配置
前端·javascript·react.js
XiaoYu200214 小时前
AI精准提问手册:从模糊需求到精准输出的核心技能(上)
前端·人工智能·程序员
东华帝君14 小时前
vue3组件通信
前端
windliang14 小时前
前端 AI 自动化测试:brower-use 调研
前端·agent·测试
小高00714 小时前
instanceof 和 typeof 的区别:什么时候该用哪个?
前端·javascript·面试
im_AMBER14 小时前
React 03
前端·笔记·学习·react.js·前端框架·react