Quasar 使用 Pinia 进行状态管理

官方文档:使用 Pinia 进行状态管理 |Quasar 框架
视频教程:quasar框架store-状态管理库pinia介绍_哔哩哔哩_bilibili

使用 Quasar CLI 创建一个新的store

quasar new store date --format js

Pinia存储模板详解解

基本结构解析

import { defineStore, acceptHMRUpdate } from 'pinia'

// 定义存储
export const useMyStore = defineStore('myStore', {
  state: () => ({}),  // 状态定义
  getters: {},        // 计算属性
  actions: {}         // 操作方法
})

// HMR (热模块替换)支持
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useMyStore, import.meta.hot))
}

如何扩展模板

1. 定义状态 (state)

state 是存储的核心数据部分:

state: () => ({
  count: 0,
  user: null,
  items: [],
  loading: false
})

2. 添加 getters

getters 类似于计算属性,用于派生状态:

getters: {
  doubleCount: (state) => state.count * 2,
  isAuthenticated: (state) => state.user !== null,
  activeItems: (state) => state.items.filter(item => item.active)
}

3. 添加 actions

actions 用于修改状态和执行异步操作:

actions: {
  increment() {
    this.count++
  },
  async fetchUser(userId) {
    this.loading = true
    try {
      const response = await api.getUser(userId)
      this.user = response.data
    } catch (error) {
      console.error('Failed to fetch user:', error)
    } finally {
      this.loading = false
    }
  },
  reset() {
    this.$reset() // 内置方法,重置到初始状态
  }
}

[!INFO]
Pinia也支持类似Vue3的组合式API写法

在组件中使用 Pinia Store

在 Vue 组件中使用 Pinia Store 非常简单,以下是几种常见的使用方式:

在组件 setup 中使用

<script setup>
import { useCounterStore } from '@/stores/counter'

// 在setup中获取store实例
const counterStore = useCounterStore()

// 访问状态
console.log(counterStore.count)

// 使用getter
console.log(counterStore.doubleCount)

// 调用action
function increment() {
  counterStore.increment()
}
</script>

<template>
  <div>
    <p>Count: {{ counterStore.count }}</p>
    <p>Double: {{ counterStore.doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

使用 storeToRefs 解构保持响应式

<script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'

const counterStore = useCounterStore()

// 使用storeToRefs解构可以保持响应式
const { count, doubleCount } = storeToRefs(counterStore)
// actions不需要解构,可以直接从store调用
const { increment } = counterStore
</script>

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

选项式 API 中使用

如果你使用的是选项式 API,可以在 setup() 中使用:

<script>
import { useCounterStore } from '@/stores/counter'

export default {
  setup() {
    const counterStore = useCounterStore()
    return { counterStore }
  },
  methods: {
    increment() {
      this.counterStore.increment()
    }
  }
}
</script>

<template>
  <div>
    <p>Count: {{ counterStore.count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

在模板中直接使用

<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>

<template>
  <div>
    <!-- 直接访问store属性 -->
    <h1>{{ counter.count }}</h1>
    
    <!-- 直接调用action -->
    <button @click="counter.increment()">+</button>
    <button @click="counter.decrement()">-</button>
    
    <!-- 使用getter -->
    <p>Double: {{ counter.doubleCount }}</p>
  </div>
</template>

监听状态变化

<script setup>
import { useCounterStore } from '@/stores/counter'
import { watch } from 'vue'

const counter = useCounterStore()

// 监听count的变化
watch(
  () => counter.count,
  (newValue, oldValue) => {
    console.log(`Count changed from ${oldValue} to ${newValue}`)
  }
)

// 或者使用store的$subscribe方法
counter.$subscribe((mutation, state) => {
  console.log('Store changed:', mutation, state)
})
</script>

重置 store 状态

<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()

function reset() {
  counter.$reset() // 重置到初始状态
}
</script>

<template>
  <button @click="reset">Reset Store</button>
</template>

最佳实践建议

  1. 命名一致性:store 变量命名建议使用 xxxStore 格式,如 userStore, productStore
  2. 避免直接修改状态:尽量通过 actions 修改状态,而不是直接赋值
  3. 合理使用解构:使用 storeToRefs 解构状态和 getters,但不要解构 actions
  4. 模块化:将大型应用的状态拆分到多个 store 中
  5. TypeScript:如果使用 TS,可以为 store 添加类型定义以获得更好的类型支持
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值