vue存储库-----pinia

发布时间 2023-08-31 14:35:21作者: chichi0002

vue存储库-----pinia和vuex

pinia与vuex的区别

(1)pinia它没有mutation,他只有state,getters,action【同步、异步】使用他来修改state数

(2)pinia他默认也是存入内存中,如果需要使用本地存储,在配置上比vuex麻烦一点

(3)pinia语法上比vuex更容易理解和使用,灵活。

(4)pinia没有modules配置,没一个独立的仓库都是definStore生成出来的

(5)pinia state是一个对象返回一个对象和组件的data是一样的语法

pinia与vuex的优缺点

Pinia的优点:

  1. 完整的 TypeScript 支持:与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易
  2. 极其轻巧(体积约 1KB)
  3. store 的 action 被调度为常规的函数调用,而不是使用dispatch 方法或 MapAction 辅助函数,这在 Vuex 中很常见
  4. 支持多个Store
  5. 支持 Vue devtools、SSR 和 webpack 代码拆分

Pinia的缺点:

  1. 不支持时间旅行和编辑等调试功能

Vuex的优点:

  1. 支持调试功能,如时间旅行和编辑
  2. 适用于大型、高复杂度的Vue.js项目

Vuex的缺点:

  1. 从 Vue 3 开始,getter 的结果不会像计算属性那样缓存
  2. Vuex 4有一些与类型安全相关的问题

pinia与vuex的使用选择

  • 由于Pinea是__轻量级的,体积很小__,它适合于中小型应用。它也适用于低复杂度的Vue.js项目,因为一些调试功能,如时间旅行和编辑仍然不被支持。
  • Vuex 用于中小型 Vue.js 项目是过度的,因为它__重量级的,对性能降低有很大影响__。因此,Vuex 适用于大规模高复杂度的 Vue.js 项目
  • pinia和vuex在vue2和vue3都可以使用,一般来说vue2使用vuex,vue3使用pinia。

pinia的使用

  1. 安装pinia:

    // npm 安装
    npm install pinia
    
    // yarn 安装
    yarn add pinia
    
  2. 创建一个store

    src/stores/index.ts

    import { createPinia } from 'pinia';
    
    const pinia = createPinia();
    
    export default pinia;
    
  3. 挂载到vue实例上

    src/main.ts

    import { createApp } from 'vue'
    import App from './App.vue'
    
    import pinia from './stores'
    import router from './router'
    
    const app = createApp(App)
    
    app.use(pinia)
      .use(router)
      .mount('#app')
    
    
  4. 创建store状态管理库

    • defineStore():第一个参数,为容器的一个别名且此名字必须唯一,不能重复,第二个参数理解为配置对象
    • state:用来存储全局状态
    • getters:用来监听或者计算状态变化的,有缓存功能
    • actions:用来对 state 里数据变化的业务逻辑,个人理解为,修改 state 全局状态数据的
    import { defineStore } from 'pinia'
    export const mainStore = defineStore('main', {
        state: ()=>{
            return {}
        },
        getters: {},
        actions: {}
    })
    

    src/store/app.ts

    import Cookies from 'js-cookie'
    import { defineStore } from 'pinia'
    
    export const useAppStore = defineStore({
      id: 'app', // 容器名字
      state: () => ({
        sidebar: {
          opened: Cookies.get('sidebarStatus') ? !!+(Cookies.get('sidebarStatus') as string) : true,
          withoutAnimation: false
        },
        device: 'desktop'
      }),
      
      actions: {
    
        toggleSidebar () {
          this.sidebar.opened = !this.sidebar.opened
          this.sidebar.withoutAnimation = false
          if (this.sidebar.opened) {
            Cookies.set('sidebarStatus', '1')
          } else {
            Cookies.set('sidebarStatus', '0')
          }
        },
    
        closeSidebar(withoutAnimation: boolean) {
          Cookies.set('sidebarStatus', '0')
          this.sidebar.opened = false
          this.sidebar.withoutAnimation = withoutAnimation
        },
    
        toggleDevice(device: string) {
          this.device = device
        }
      }
    })
    
  5. 组件中使用

    import { defineStore } from 'pinia';
    // 获取store实例
    import type { UserInfoState } from './interface';
    
    export const useUserInfoStore = defineStore('userInfo', {
    
    	state: (): UserInfoState => ({
    			...
      }),
    	actions: {
            // 关于登录的方法
            async login ( username: string, password: string ) {
              const {token} = await loginApi(username,password)
              this.token = token
              setToken(token)
            },
    	  },
    });
    
    
    
    <script lang="ts" setup>
    import { useUserInfoStore } from '@/stores/userInfo';
    .....
    /* 
    点击登陆的回调
    */
    const handleLogin = async () => {
      await formRef.value?.validate()
      loading.value = true
      const {username, password} = loginForm.value
      
      try {
          // 使用pinia仓库中actions的login方
        await userInfoStore.login(username, password)
          
        router.push({ path: redirect.value || '/' })
      } finally {
        loading.value = false
      }
        
    }
    </script>
    
    

vuex的使用

  1. 安装

    npm install vuex --save
    
    yarn add vuex
    
  2. 在项目中,安装

    src/store/index.ts

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    
    export default new Vuex.Store({
        state:{
            pathName: "",
            currDbSource: {},
            currJobData: {},
            DbSource: []
        },
        // 注意:
        //actions.js :暴露给用户使用,借此触发mutations中的方法,保存数据(可执行异步操作)
        //mutation中不能解决异步问题,用来修改state数据
        mutations:{
            // 保存当前菜单栏的路径
            savePath(state,pathName){
                state.pathName = pathName;
            },
            // 保存当前点击的数据源
            saveCurrDbSource(state,currDbSource){
                state.currDbSource = currDbSource;
            }
            }
        }
    })
    
  3. 引入创建的vuex的store,vue注册后全局使用

    src/main.ts

    // 引入vuex-store
    import store from './store/index';
     
    new Vue({
      el: '#app',
      router,
      store,
      render: h => h(App)
    });
    
  4. 组件中使用

    使用vuex中的方法: this.$store.commit('事件名',传递的数据)

    
    methods:{
     click(){
        // 点击按钮进行一些操作,然后保存数据
        this.$store.commit('saveCurrDbSource',this.db)
      }
    
    

    获取变量:

    this.$store.state.变量名
     
    // 例如
    this.$store.state.currDbSource