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,你可以直接导入并在 actions 和 getters 中调用 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)
  • 开启数据持久化
  • 代码中persist为true,就可以开启数据持久化了。如下:
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>
相关推荐
子兮曰5 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰5 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万5 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝5 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋5 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁5 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95275 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大5 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师5 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学5 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端