Vue3 状态管理-Pinia

574 阅读2分钟

一. pinia简介

  • 版本

    • pinia(2):vue2、vue3(都中)

    • vuex(3、4):3→vue2、4→vue3

  • 个人理解

    Pinia它作为vue3里面主推的状态管工具相比较vuex而言 pinia更简洁没有了mutalions(同步),只有 state gettes actions(二合一:Mutations+Actions)) ,actions 里面可以写异步也可以写同步.然后它的打包体积也变的更小.对 ts 的支持也更好而且没有了模块化的概念里面在实现的时候.只需要传入一个唯一的id 就可以区分开

二. 大菠萝的基础使用

  1. 安装pinna

npm install pinia -S

  1. pinna挂载到main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
// 创建 Pinia 实例 
const pinia = createPinia()
// 创建 Vue 实例
const app = createApp(App)
//挂载到vue根实例
app.use(pinia)
app.mount('#app')

3.src 创建store文件夹 ,添加index.ts

// store/index.ts
import { defineStore } from 'pinia'
export const useMainStore =  defineStore('main',{    

  //state:在此定义变量,以箭头函数包裹,防止数据状态污染,也更好为Ts推导
    state:()=>{
    
        return {
            selectManger:"我是客户经理"
        }
    },
    //getters:一种计算属性,逻辑操改变state,抽离每个组件对于存储的数据过滤的逻辑封装->gettters
    getters:{},
    //action 同步和异步请求 
    actions:{}
})

4.大菠萝-数据取出

 <template>
  <div class="box">
    <Header :info="title" :toleft="direction"> </Header>
    <div class="body">
      <!-- 1 -->
      <div class="item" @click.stop="router.push('/chooseMangers')">
        <dl >
          <dt><span>*</span> 客户经理</dt>
          <dd><input type="text" placeholder=" 请选择客户经理" 
              :value="selectManger.userName"/>
          </dd>
        </dl>
      </div>     
    </div>
    <!-- 底部 -->
    <footer>
      <p><van-icon name="comment-circle-o" /></p>
      <van-button round type="primary">提交</van-button>
    </footer>
  </div>
</template>

//引入store下的index.ts文件


import { storeToRefs } from 'pinia'
// storeToRefs:对数据结构做—响应式处理 
import { useMainStore } from "@/store/index";

//const {selectManger} = storeToRefs(mainStore);直接这样结构等同于reactive 只能做一次调用不具备响应式


//正确借助pinna工具的结构方式 ↓
const mainStore = useMainStore();
const { selectManger } = storeToRefs(mainStore);

5.大菠萝的数据操作

  1. 常规方法
  const changeShow1 = () => {
  //常规单个修改↓
  //1. selectManger.value='我是张三';
  
  //2. mainStore.selectManger='我是张三';
  
  //批量进行修改pinia中的数据↓
  //3.mainStore.$patch(state => { 
   console.log(state)//打印state 可展示所有的pinia中的变量
   state.selectManger='我是张三'
  })
  
  //重置所有的值↓
   mainStore.$reset();
};
  1. pinia actions定义进行修改
    //在store下index.ts中的actions定义方法
export const useMainStore =  defineStore('main',{    
state:()=>{

    return {
        selectManger:"我是客户经理"
    }
},
getters:{},
actions:{
    changeDate (date){
        this.selectManger =date
    },
    changeDate2 (){
        this.selectManger ="李四"               
    }

    }
})


//4.组件中调用我们在actions中的 changeDate方法
mainStore.changeDate('额是张三')
mainStore.changeDate2()

6.大菠萝的数据持久化

  1. 单个组件调用存储
import { useMainStore } from "@/store/index";

//正确借助pinna工具的结构方式 ↓
const mainStore = useMainStore();
//const {selectManger} = storeToRefs(mainStore);直接这样结构等同于reactive 只能做一次调用不具备响应式



//组件中 直接调用存储
mainStore.$subscribe((mutation: any, store: any) => {  
  localStorage.setItem("store"JSON.stringify(store));  
});


  1. 全局覆盖

安装插件:cnpm i pinia-plugin-persist --save

//main.js中引入
  import piniaPluginPersist from 'pinia-plugin-persist';
  const pinia = createPinia(); 
  pinia.use(piniaPluginPersist);                                                                                                                            
// store/index.ts 中 添加persist
import { defineStore } from 'pinia'
const useMainStore =  defineStore('main',{    
    //state:在此定义变量,以箭头函数包裹,防止数据状态污染,也更好为Ts推导
    state:()=>{

            return {
                selectManger:"我是客户经理"
            }
    },
    //getters:一种计算属性,逻辑操改变state,抽离每个组件对于存储的数据过滤的逻辑封装->gettters
    getters:{},
    //action 同步和异步请求 
    actions:{},
    // 开启数据缓存
    persist:{
        enabled: true,
        strategies:
            [ 
               {
                // 自定义名称 存储的键名
                key: 'mystore',
                // 存储位置,默认sessionStorage,
                storage: localStorage,
                // 默认存储所有state在中的字段 , 可填写指定字段名,专项存储
                paths: [''],
               }
            ]
          }
}   

//else 不借助第三方插件 利用单项存储的方法 直接存储
//1.存储数据
const instance = useMainStore();
instance.$subscribe((_, state) => {
  localStorage.setItem('mystore', JSON.stringify({ ...state }));
});
// 2. 获取数据
const stroage = localStorage.getItem('mystore');
if (stroage) {
  instance.$state = JSON.parse(stroage);
}
export default useMainStore


三.关于大菠萝和vux的选择

Pinia虽然是新推荐的状态管理库,但是某一些项目还是得用Vuex处理状态应用。 性能而言:如果此时你构建的是大型的SPA项目,这里更推荐vuex,而对于中小型应用且不算太复杂应用项目(不支持调试功能,如时间旅行和编辑)推荐大菠萝,毕竟它的重量只有 1kb