• Pinia 与 Vuex 使用区别


    官网:https://pinia.web3doc.top/

    从 Vuex 迁移:Migrating from Vuex ≤4

    其实在使用上区别不大,但是有几点需要改变:

    • 如下示例为 Vuex4.x 和 Pinia 代码

    没有 mutations(使用 actions 替代)

    Vuex 如何使用 actionsPinia 这里做了两点改变

    1. 第一个参数 context 被移除

      // vuex index.js
      import appModule from './modules/app
      const store = createStore({
        modules: {
          appModule
        }
      })
      
      // vuex modules/app.js
      const useAppStore = createStore({
        state: {
          count: 0
        },
        mutations: {
          increment (state, num) {
            state.count += num
          }
        },
        actions: {
          increment (context, num) {
            // 或是直接把 context 里的 commit 解构出来
            context.commit('increment', num)
          }
        }
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
    2. 不再使用 dispatch 调用 actions

      // .vue 文件
      this.$store.dispatch('app/increment', 2)
      
      • 1
      • 2

    Pinia 如何使用 actions

    • actions 里直接使用 this 获取到 state 的值
    // pinia modules/app.js
    const useAppStore = defineStore('app', {
      state: {
        count: 0
      },
      actions: {
        increment (num) {
          this.state.count += num
        }
      }
    })
    
    // .vue 文件
    import useAppStore from '@/store/modules/app'
    useAppStore().increment(2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    没有 modules 的嵌套结构

    # Vuex
    src
    └── store
        ├── index.js 
        └── modules
            ├── module1.js
            └── nested
                ├── index.js
                ├── module2.js
                └── module3.js
    
    # Pinia
    src
    └── stores
        ├── index.js
        ├── module1.js
        ├── nested-module2.js
        ├── nested-module3.js
        └── nested.js
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Vuex 需要有一个主要的 Store,最终会形成一个树形引用结构

    Pinia 不再需要一个主要的 Store,是一个平面的结构,可创建不同的 Store

    const useAppStore = defineStore('app', { /* ... */ })
    
    • 1
    • 注意:Pinia 每一个文件都需要有一个唯一的命名,类似于 Vuex 的命名空间(namespaced: true
     import appModule from './modules/app
     const store = createStore({
       modules: {
         appModule
       }
     })
     
     // vuex modules/app.js
     const useAppStore = createStore({
       namespaced: true
     })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    getters 用法改变

    Vuex 里一个 getters 想使用其他 getters,需要借助其第二个参数

    • 如下示例为:统计所有书折扣后的总价钱
    const useBookStore = createStore({
      state() {
        return {
          books: [
            { name: 'book1', count: 3, price: 10 },
            { name: 'book2', count: 1, price: 20 },
            { name: 'book3', count: 2, price: 15 }
          ],
          discount: 0.9
        }
      },
      getters: {
        totalPrice(state, getters) {
          const totalPrice = state.books.reduce((acc, cur) => {
            return (acc += cur.count * cur.price)
          }, 0)
          return totalPrice * getters.currentDiscount
        },
        currentDiscount(state) {
          return state.discount
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    Pinia 去掉了第二个参数,可以在里面使用 this 取到其他 getters

    const useBookStore = createStore({
      state() {
        return {
          books: [
            { name: 'book1', count: 3, price: 10 },
            { name: 'book2', count: 1, price: 20 },
            { name: 'book3', count: 2, price: 15 }
          ],
          discount: 0.9
        }
      },
      getters: {
        totalPrice(state) {
          const totalPrice = state.books.reduce((acc, cur) => {
            return (acc += cur.count * cur.price)
          }, 0)
          return totalPrice * this.currentDiscount
        },
        currentDiscount(state) {
          return state.discount
        }
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    这里补充一点:由于 getters 是无法接受参数的,如果想要接受参数可以使用闭包

    • 如下示例为:统计所有数量大于 2 的书折扣后总价钱(示例为 Vuex 的)
    const useBookStore = createStore({
      getters: {
        totalPriceGreaterN(state, getters) {
          return n => {
            let totalPrice = 0
            const totalPrice = state.books.reduce((acc, cur) => {
              if (cur.count > n) {
                return (acc += cur.count * cur.price)
              } else {
                return acc
              }
            }, 0)
            return totalPrice * getters.currentDiscount
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在模板中可以这样使用(只是单方面举例)

    <h2>{{ $store.getters.totalPriceGreaterN(2) }}h2>
    
    • 1
  • 相关阅读:
    毫无基础的人如何入门 Python ?
    【数字人】4、AD-NeRF | 使用 NeRF 来实现从声音到数字人人脸的直接驱动(ICCV2021)
    【GPT‑4o】完整教程:LORA微调LLaMA3并结合RAG和Agent技术实现Text2SQL任务
    2023年09月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试
    Java学习笔记——接口
    CH455G驱动数码管
    微信发送接受消息测试用例
    Python:torch.nn.Conv1d(), torch.nn.Conv2d()和torch.nn.Conv3d()函数理解
    榜样访谈——曾钰倬:从讲座中收获经验
    第三章 索引
  • 原文地址:https://blog.csdn.net/qq_38689395/article/details/126545045