pinia与vuex的区别

Vuex和Pinia的一些区别

  • pinia支持组合式api
  • pinia更好的支持TS
  • pinia没有了mutation,pinia的action可直接修改state。
  • pinia无需再使用dispatch分发action,也不需要使用commit提交mutation,可直接调用action。
  • vuex只能创建一个store实例, pinia可以创建任意个。
  • pinia没有了modules,可直接创建一个新的store作为module。

Vuex

  • vuex 3.x 通过Vuex.Store()创建一个store;
  • Vuex.Store()接受一个对象作为参数;
  • 参数对象上的key值只能是stategettersmutationsactionsmodules
  • state上定义的是共享的状态/变量
  • getters上定义的是根据state派生出的状态
  • mutation上定义的是可以同步修改状态的方法
  • actions上定义的是可以异步/同步执行mutaions上的方法的方法
  • modules上定义的是模块,可以根据业务将状态分模块存放,一个模块就是一个对象,该对象上的key值也是stategettersmutationsactionsmodulesmodules上可以继续嵌套modules

Vuex实践

  • 定义store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

interface Object {
  [key: string]: any
}

const womanModule = {
  state: {
    pregnant: false //是否怀孕
  },
  mutations: {
    setPregnant(state : Object, value: boolean) {
        state.pregnant = value
    }
  },
  actions: {
    setPregnant(context : Object, value : boolean) {
      context.commit('setPregnant', value)
    }
  }
}
const personModule = {
  state: {
    id: 0,
    name: '',
    age: 0
  },
  mutations: {
    setId(state: Object, id: number) {
      state.id = id
    },
    setName(state: Object, name: string) {
      state.name = name
    },
    setAge(state: Object, age: number) {
      state.age = age
    }
  },
  actions: {
    setId(context: Object, id: number) {
      context.commit('setId', id)
    },
    setName(context: Object, name: string) {
      context.commit('setName', name)
    },
    setAge(context: Object, age: number) {
      context.commit('setAge', age)
    }
  },
  modules: {
    womanModule
  }
}

export default new Vuex.Store({
  state: {
    
  },
  getters: {},
  mutations: {

  },
  actions: {

  },
  modules: {
    personModule
  }
})

使用store

<template>
    <div>
        <div>{{  personModule.id  }}</div>
        <div>{{  personModule.name  }}</div>
        <div>{{  personModule.age  }}</div>
        <div>{{ personModule?.womanModule?.pregnant }}</div>
    </div>
</template>

<script setup lang="ts">
import store from '../store/index'
const state  : {[key: string]: any} = store.state;
const personModule : {[key: string]: any}= state.personModule;
store.dispatch('setId', 1)
store.dispatch('setName', 'role')
store.dispatch('setAge', personModule.age || 18)
store.dispatch('setPregnant', true)
</script>

Pinia

  • Pinia的 Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字
  • defineStore() 的第二个参数可接受两类值:Setup 函数或 Option 对象。
  1. 与 Vue 的选项式 API 类似,我们也可以传入一个带有 stateactions 与 getters 属性的 Option 对象

  2. 也存在另一种定义 store 的可用语法。与 Vue 组合式 API 的 setup 函数 相似,我们可以传入一个函数,该函数定义了一些响应式属性和方法,并且返回一个带有我们想暴露出去的属性和方法的对象。
    在 Setup Store 中:

       `ref()` 就是 `state` 属性
       `computed()` 就是 `getters`
       `function()` 就是 `actions`
    

Pinia实践

定义store

import { ref, computed } from 'vue'
import type {Ref} from 'vue'
import { defineStore } from 'pinia'

// 选项式定义一个store
export  const useTestPerson = defineStore('person', {
  state: () => ({
    id: 0,
    name: '',
    age: 0
  }),
  getters: {
    adult() : boolean {
      return this.age >= 18
    }
  },
  actions: {
    setId(value: number) {
      this.id = value
    },
    setName(value: string) {
      this.name = value
    },
    setAge(value: number) {
      this.age = value
    }
  }
})

// 组合式定义一个store
export const useWoman = defineStore('woman', () => {
  let pregnant: Ref<boolean> = ref(false)

  const changePregnant = () => {
    pregnant.value = !pregnant.value
  }
  return {
    pregnant,
    changePregnant
  }
})

使用store

<template>
    <div>
        <div>编号:{{ person.id }}</div>
        <div>名称:{{ person.name }}</div>
        <div>年龄:{{ person.age }}<el-button @click="changeAge">change age</el-button></div>
        <div>是否成年:{{ person.adult }}</div>
    </div>

    <div>
        <div>是否生育: {{ woman.pregnant }}<el-button @click="changePregnant">change</el-button> </div>
    </div>
</template>

script setup lang="ts">
    import { ref, computed, watch, onMounted } from 'vue'
    import type {Ref} from 'vue'
    import { ElButton, ElInput } from 'element-plus'
    import { useTestPerson, useWoman } from '../stores/test'

    // 
    const person = useTestPerson()
    person.setId(1)
    person.setName('lily')
    person.setAge(18)

    const changeAge = () => {
        person.setAge(11)
    }

    // 
    const woman = useWoman();
    const changePregnant = () => {
        woman.changePregnant()
    }
    
</script>

推荐

juejin.cn/post/698654…

原文链接:https://juejin.cn/post/7347905312478969919 作者:yanessa_yu

(1)
上一篇 2024年3月19日 下午4:12
下一篇 2024年3月19日 下午4:22

相关推荐

发表回复

登录后才能评论