Pinia(三)了解和使用state

发布于:2023-01-11 ⋅ 阅读:(174) ⋅ 点赞:(0)

Pinia(三)了解和使用state

  1. state 就是我们要定义的数据, 如果定义 store 时传入的第二个参数是对象, 那么 state 需要是一个函数, 这个函数的返回值才是状态的初始值.
    • 这样设计的原因是为了让 Pinia 在客户端和服务端都可以工作
    • 📕官方推荐使用箭头函数(()=>{})获得更好的类型推断
    • import { defineStore } from 'pinia';
      
      const userStore = defineStore('user', {
        state: () => {
          return {
            user: {
              name: 'tom',
              age: 18
            },
            color: 'red',
            userList: [],
          }
        }
      })
      
  2. TypeScript
    • 可以定义 interface 来标记类型
    • import { defineStore } from 'pinia';
      
      interface UserInfo {
        name: string;
        age: number;
      }
      
      export const userStore = defineStore('user', {
        state: () => {
          return {
            color: 'red' as string,
            userList: [] as UserInfo[],
            user: {
              name: 'tom',
              age: 18
            } as UserInfo | null
          }
        }
      })
      
  3. 访问 state
    • 默认可以直接通过 store 实例访问和修改 state.
    • const user = userStore();
      function changeColor() {
        user.color = 'black'
      }
      function changeAge() {
        user.user.age++;
      }
      
  4. 重置 state
    • 调用 store$reset()
    • function resetStore() {
        user.$reset();
      }
      
  5. 修改 state
    • 除了直接通过 store 修改 state, 还可以调用 store$patch 方法. 这个方法允许一次进行多处修改
    • function patchChange() {
        user.$patch({
          color: 'skyblue',
          user: {
            age: user.user.age + 10
          }
        })
      }
      
    • 但是这种语法有时会很麻烦, 比如我们想要对数组进行增删时, 这种语法会要求创建一个新的数组. 所以 $patch 方法可以接收一个函数为参数.
    • function patchChangeFunction() {
        user.$patch((state) => {
          state.userList.push({ name: 'mike', age: 19 });
          state.user.age++;
          state.color = 'pink';
        });
      }
      
    • 📕也直接通过 store$state 属性修改 state, 因为其内部会调用 $patch
    • function stupidChange() {
        user.$state = {
          color: 'hahha'
        }
        // 实际上内部调用了
        // user.$patch({ color: 'hahha' })
      }
      
  6. 订阅状态
    • 我们可以通过 store$subscribe 方法侦听 state 的改变. 使用 $subscribe 而不是 watch() 的好处是 $subscribe 总是在 state 修改之后执行一次.
    • user.$subscribe((mutation, state) => {
        console.log('mutation', mutation);
      })
      
    • 请添加图片描述
    • 参数 state: 最新的 state
    • 参数 mutation
      • type: 表示通过那种方式修改的值
        • direct: 直接修改, 例如 user.user.age++
        • patch object: 通过 $patch({...}) 传递对象的方式修改
        • patch function: 通过 $patch(() => {...}) 传递对象的方式修改
      • storeId: 定义 defineStore 的第一个参数, 也就是 store.$id 属性
      • payload: 只有 type 值为 plain object 才会有这个值, 即为传递给 $patch 的对象参数.
      • $subscribe 的返回值是一个函数, 调用这个函数将取消订阅
        • const stopSubscribeFunc = user.$subscribe((mutation, state) => {
            console.log('mutation', mutation);
            console.log('state', state);
          })
          function stopSubscribe() {
            stopSubscribeFunc()
          }
          
    • 📕如果在组件内调用 store.$subscribe(), 那么组件卸载时会自动清理定于, 除非将 detached 设置为 true
      • user.$subscribe((mutation, state) => {
          // do something...
        }, {
          detached: true
        })
        
    • 如果要实现保存数据到 localStorage, 可以使用 watch
      • main.js
      • const pinia = createPinia();
        app.use(pinia);
        
        watch(
          pinia.state,
          (state) => {
            console.log(state)
            localStorage.setItem('piniaState', JSON.stringify(state));
          },
          {
            deep: true,
            immediate: true
          }
        )
        
本文含有隐藏内容,请 开通VIP 后查看