2024-02-22
Vue
0
请注意,本文编写于 87 天前,最后修改于 82 天前,其中某些信息可能已经过时。

目录

搭建 pinia 环境
存储 / 读取数据
存储数据
读取数据
修改数据
storeToRefs
getters
订阅
store 组合式写法
Pinia

完成效果:

GIF 2024-2-22 19-33-50.gif

搭建 pinia 环境

  1. 安装 pinia:npm i pinia

  2. main.ts 中配置:

    typescript
    import { createApp } from 'vue'; import App from './App.vue'; import { createPinia } from 'pinia'; const pinia = createPinia(); createApp(App).use(pinia).mount('#app');

 

存储 / 读取数据

存储数据

@/store/count.ts

typescript
import { defineStore } from 'pinia'; export const useCountStore = defineStore('count', { state() { return { count: 1 } } });

@/store/sentence.ts

typescript
import { defineStore } from 'pinia'; export const useSentenceStore = defineStore('sentence', { state() { return { sentenceList: [ { id: 'xxx1', content: '长河千嶂,大荒孤城,历历在目。' }, { id: 'xxx2', content: '回首某个瞬间,下个瞬间即告消逝。' }, { id: 'xxx3', content: '无欲无求,笑口常开。' } ] } } });

读取数据

@/component/Count.vue

vue
<template> <div class="count"> <h2>当前计数为:{{ countStore.count }}</h2> <select v-model.number="n"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <button @click="add">加</button> <button @click="sub">减</button> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import { useCountStore } from '@/store/count'; const countStore = useCountStore(); // countStore 是一个 reactive 对象 // console.log('countStore',countStore) // 以下都可以拿到 state 数据 // console.log('countStore.count', countStore.count) // console.log('countStore.$state.count',countStore.$state.count) let n = ref(1); function add() { } function sub() { } </script> <style scoped> .count { background-color: skyblue; border-radius: 10px; box-shadow: 0 0 10px; padding: 20px; } select,button { margin: 0 5px; height: 26px; } </style>

@/component/Sentence.vue

vue
<template> <div class="sen"> <button @click="getSen">获取一句话</button> <ul> <li v-for="sen in sentenceStore.sentenceList" :key="sen.id">{{sen.content}}</li> </ul> </div> </template> <script setup lang="ts"> import { useSentenceStore } from '@/store/sentence'; const sentenceStore = useSentenceStore(); function getSen() { } </script> <style scoped> .sen { background-color: orange; border-radius: 10px; box-shadow: 0 0 10px; padding: 20px; } </style>

修改数据

  1. store.sum += 1

  2. store.$patch({ sum: 888, name: '小明'})

  3. 配置 actions (配置项式),常用于公共代码较多可以封装的情况

    typescript
    /* @/store/count.ts */ export const useCountStore = defineStore('count', { actions: { increment(value: number) { this.count += value; } }, state() { return { count: 1 } } }); /* @/component/Count.vue */ countStore.increment(1);

 

storeToRefs

直接解构会丢失响应式,而直接使用 toRefs 会将 store 中的所有属性全部转为 ref 对象

typescript
const { count } = storeToRefs(countStore); function add() { countStore.$patch({count: count.value + n.value}) } function sub() { count.value -= n.value; }

getters

getters 为一个对象,相当于可共享的计算属性,可以被 storeToRefs 拿到

typescript
export const useCountStore = defineStore('count', { state() { return { count: 1 } }, getters: { bigCount: state => state.count * 10, largeCount(): number { return this.count * 10; } } });

订阅

类比 watch 监视

typescript
sentenceStore.$subscribe((mutate, state) => { console.log('sentenceStore变化了', mutate, state) })

store 组合式写法

defineStore 封装成组件的 setup 写法

typescript
import { defineStore } from 'pinia'; import { ref } from 'vue'; export const useCountStore = defineStore('count', () => { let count = ref(1); function increment(value: number) { count.value += value; } return { count, increment }; });

如果两个或更多的 store 相互使用,它们不可以通过 gettersactions 创建一个无限循环。它们也不可以同时在它们的 setup 函数中直接互相读取对方的 state

本文作者:Morales

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!