> 技术文档 > 前端开发 Vue 状态优化

前端开发 Vue 状态优化

Vue 项目中的状态优化一般都会用Pinia替代Vuex,Pinia 是 Vue 生态系统中的一个轻量级状态管理库,作为 Vuex 的替代品,它提供了更简洁的 API 和更好的性能。

  • 模块化管理:使用 Pinia 时,建议将状态拆分为多个 store 模块,以避免单一状态树过于庞大和复杂。这不仅有助于维护,还能提升性能。

  • 加载 Store:通过 Pinia 的 defineStore 动态创建 store,当某个 store 仅在特定页面或组件中需要时,可以延迟加载它。这样可以减少应用的初始加载时间。

  • State 持久化:如果某些状态需要在页面刷新后保持,可以使用 Pinia 的插件功能将状态持久化到 localStorage 或 sessionStorage,避免不必要的网络请求或重新计算。

  • 避免不必要的深度响应:Pinia 允许你明确哪些状态需要响应式,哪些不需要。对于不需要响应式的复杂对象,可以使用 shallowRef 或 shallowReactive 来减少响应式开销。

1. 安装 Pinia 与配置

npm install pinia

设置 Pinia:

import { createApp } from \'vue\'import { createPinia } from \'pinia\'import App from \'./App.vue\'const app = createApp(App)// 创建 Pinia 实例const pinia = createPinia()app.use(pinia)app.mount(\'#app\')

 2. 创建模块化 Store

创建两个 Store 模块:userStore 和 productStore。其中 userStore 将使用状态持久化,productStore 将演示懒加载和避免不必要的深度响应。

stores/userStore.js:

// stores/userStore.jsimport { defineStore } from \'pinia\'import { ref, computed, watch } from \'vue\'export const useUserStore = defineStore(\'user\', () => { // 初始化状态,如果 localStorage 中有存储,优先使用存储的状态 const name = ref(localStorage.getItem(\'user-name\') || \'John Doe\') const age = ref(parseInt(localStorage.getItem(\'user-age\')) || 25) const doubleAge = computed(() => age.value * 2) // 监听状态变化,并将其保存到 LocalStorage watch( () => name.value, (newValue) => { localStorage.setItem(\'user-name\', newValue) } ) watch( () => age.value, (newValue) => { localStorage.setItem(\'user-age\', newValue.toString()) } ) return { name, age, doubleAge, }})

stores/productStore.js:

// stores/productStore.jsimport { defineStore } from \'pinia\'import { shallowRef } from \'vue\'export const useProductStore = defineStore(\'product\', () => { // 使用 shallowRef 来避免不必要的深度响应 const products = shallowRef([]) const addProduct = (product) => { products.value.push(product) } return { products, addProduct, }})

3. 懒加载 Store

productStore 仅在需要时加载,例如在某个特定组件中。

components/ProductList.vue:

 

Product List

  • {{ product.name }}
import { useProductStore } from \'@ stores/productStore\'import { onMounted } from \'vue\'// 懒加载 productStoreconst productStore = useProductStore()const products = productStore.productsconst addNewProduct = () => { productStore.addProduct({ id: Date.now(), name: `Product ${products.length + 1}` })}onMounted(() => { console.log(\'ProductList component mounted.\')})

4. 在其他组件中使用 userStore

components/UserProfile.vue:

 

User Profile

Name: {{ name }}

Age: {{ age }}

Double Age: {{ doubleAge }}

import { useUserStore } from \'@/store/userStore\'// 使用 userStore,这个 Store 状态会被持久化const userStore = useUserStore()const { name, age, doubleAge } = userStore

5. 手动实现状态持久化

我们在 userStore 中通过 localStorage 手动实现了状态持久化。如果你需要更加通用的状态持久化插件,可以创建一个简单的 Pinia 插件。

plugins/persistedState.js:

// plugins/persistedState.jsexport function createPersistedStatePlugin(options = {}) { return ({ store }) => { const { key = store.$id } = options // 从 LocalStorage 初始化状态 const fromStorage = localStorage.getItem(key) if (fromStorage) { store.$patch(JSON.parse(fromStorage)) } // 订阅状态变化,并将其保存到 LocalStorage store.$subscribe((mutation, state) => { localStorage.setItem(key, JSON.stringify(state)) }) }}

注册插件

import { createPinia } from \'pinia\'import { createPersistedStatePlugin } from \'./plugins/persistedState\'const pinia = createPinia()pinia.use(createPersistedStatePlugin())const app = createApp(App)app.use(pinia)app.mount(\'#app\')