挂载 Pinia 插件至 Vue 实例上

  1. // main.js 以 Vue 插件的形式挂载 pinia 的实例
  2. import { createApp } from 'Vue';
  3. import { createPinia } from 'pinia';
  4. import App from './App.vue';
  5. const pinia = createPinia();
  6. createApp(App).use(pinia).mount('#app');

创建 Store

  1. 定义状态容器和数据
  2. 修改容器的 state
  3. 仓库中 action 的使用

defineStore 定义 Store

  • id
  • options
    • state
    • getters
    • actions
  • return function ```javascript import { defineStore } from ‘pinia’;

export const mainStore = defineStore(‘main’, { state: () => ({ helloWorld: ‘Hello World!’, count: 0, phone: ‘15000000888’ }), getters: { phoneHidden(state) { // 可以使用 this // return this.phone.toString().replace(/^(\d{3})\d{4}(\d{4})$/, ‘$1**$2’);

  1. return state.phone.toString().repleace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2');
  2. }

}, actions: { changeState() { this.count ++; this.helloWorld = ‘ByeBye’; } }, });

  1. <a name="gUCHi"></a>
  2. # 在 Vue 中引用 Store
  3. ```vue
  4. <template>
  5. <div>{{ store.helloWorld }}</div>
  6. </template>
  7. <script setup>
  8. import { mainStore } from '../store/index';
  9. const store = mainStore();
  10. </script>

改变状态数据

直接修改 store 对应的 state

  1. <template>
  2. <div>{{ store.count }}</div>
  3. <button @click="handleClick">修改状态数据</button>
  4. <hr />
  5. <div>{{ count }}</div>
  6. <div>{{ helloWorld }}</div>
  7. </template>
  8. <script setup>
  9. import { storeToRefs } from 'pinia';
  10. import { mainStore } from '../store/index';
  11. const store = mainStore();
  12. const handleClick = () => {
  13. store.count ++;
  14. }
  15. // 和 Vue Reactive 一样,使用 ES6 解构方式会失去响应性,要使用 Pinia 提供的 storeToRefs
  16. const { helloWorld, count } = storeToRefs(store);
  17. </script>

$patch 方法

  • 支持并优化适合多个 state 的修改
  • 参数可以为对象或函数

    1. <template>
    2. <div>{{ store.count }}</div>
    3. <button @click="handleClick1">修改状态数据 $patch 对象</button>
    4. <button @click="handleClick2">修改状态数据 $patch 函数</button>
    5. </template>
    6. <script setup>
    7. import { storeToRefs } from 'pinia';
    8. import { mainStore } from '../store/index';
    9. const store = mainStore();
    10. const handleClick1 = () => {
    11. store.$patch({
    12. count: store.count ++,
    13. helloWorld: store.helloWorld === 'ByeBye' ? 'Hello World!' : 'ByeBye'
    14. });
    15. }
    16. // 这种方式更像使用 immer 的 react-saga
    17. const handleClick2 = () => {
    18. store.$patch(
    19. (state) => {
    20. state.count ++;
    21. state.helloWorld = state.helloWorld === 'ByeBye' ? 'Hello World!' : 'ByeBye';
    22. }
    23. )
    24. }
    25. </script>

    使用 action

    1. <template>
    2. <div>{{ phoneHidden }}</div>
    3. </template>
    4. <script setup>
    5. import { storeToRefs } from 'pinia';
    6. import { mainStore } from '../store/index';
    7. const store = mainStore();
    8. const { phoneHidden } = storeToRefs(store);
    9. </script>

    Getters 使用

    和 Vuex 一样,Getters 与 Vue 中的 Computed 计算属性作用相似,具有缓存的特性

    1. <template>
    2. <div>{{ store.phone }}</div>
    3. </template>
    4. <script setup>
    5. import { mainStore } from '../store/index';
    6. const store = mainStore();
    7. </script>

    Store 相互调用

    1. import { defineStore } from 'pinia';
    2. import { otherStore } from './other';
    3. export const masterStore = defineStore('master', {
    4. state: () => ({
    5. phone: '1111111111',
    6. }),
    7. actions: {
    8. getList(){
    9. console.log(otherStore().list);
    10. }
    11. }
    12. });

    ```javascript import { defineStore } from ‘pinia’;

export const otherStore = defineStore(‘other’, { state: () => ({ list: [‘a’, ‘b’, ‘c’] }), }); ```

Vue-devtools 调用

image.png
定义 Store 的 ID 会在这里显示作为识别