阅读视图

发现新文章,点击刷新页面。

pinia的使用和封装

前言

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

pinia的使用

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

  • 安装
 npm install pinia
 或
 yarn add pinia
  • 引入到项目 --简单引入 后面有介绍类似的vuex似引入方式
 // 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文件夹,可以不区分模块,个人习惯觉得区分模块会让代码阅读起来更加清晰,结构如下:

image.png

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

  • 选项式

import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0}),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})
  • setup函数格式
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 }
})
  • 页面使用
 <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。

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**

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

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
  • 开启数据持久化
  • 代码中persisttrue,就可以开启数据持久化了。如下:
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

//引入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
 // 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
  • 使用
<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>

❌