vue3+Pinia的使用

Pinia官网地址

https://pinia.vuejs.org/

Pinia的优势

Pinia是一个全新的Vue状态管理库,是Vuex的代替者,尤雨溪强势推荐

  1. Vue2 和 Vue3 都能支持
  2. 抛弃传统的 Mutation ,只有 state, getter 和 action ,简化状态管理库
  3. 不需要嵌套模块,符合 Vue3 的 Composition api,让代码扁平化
  4. TypeScript支持
  5. 代码简洁,很好的代码自动分割

Pinia的基本使用

初始化项目

npm init vite@latest

安装

npm install pinia
yarn add pinia

挂载Pinia

// src/main.ts
import { createPinia } from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount('#app')

创建store

//  src/store/index.ts

import { defineStore } from "pinia";
export const mainStore = defineStore("main", {
  state: () => {
    return {
      msg: "hello world",
    };
  },
  getters: {},
  actions: {},
});

注:这是官网上提供的常规写法,我个人还是更偏向于下面这种写法:

//  src/store/index.ts

import { defineStore } from "pinia";

interface State {
  msg: string;
  count: number;
}

const defaultState:State = {
  msg: "hello world!"
}

export const mainStore = defineStore("main", {
  state: () => {
    return defaultState;
  },
  getters: {},
  actions: {},
  },
});

使用Store

//  src/components/HelloWorld.vue






解构store

当store中的多个参数需要被使用到的时候,为了更简洁的使用这些变量,我们通常采用结构的方式一次性获取所有的变量名

  • ES传统方式解构(能获取到值,但是不具有响应性)
//  src/components/HelloWorld.vue






vue3+Pinia的使用_第1张图片

点击按钮,count的值+1,可以看到传统方式解构,count不会响应式更新。那要怎么解构呢?Pinia给我们提供了一个解构方法:

  • Pinia解构方法:storeToRefs
//  src/components/HelloWorld.vue






  • 多条数据修改

通过基础数据修改方式去修改多条数据也是可行的,但是在 pinia 官网中,已经明确表示$patch的方式是经过优化的,会加快修改速度,对性能有很大好处,所以在进行多条数据修改的时候,更推荐使用 $patch

$patch 方法可以接受两个类型的参数,函数 和 对象

  1. $patch + 对象
  2. $patch + 函数: 通过函数方式去使用的时候,函数接受一个 state 的参数,state 就是 store 仓库中的 state



  • 通过action修改
  1. Store.actions中添加 changeState 方法
import { defineStore } from "pinia";
import { reactive } from "vue";

interface State {
  msg: string;
  count: number;
}

const defaultState:State = {
  msg: "hello world!",
  count: 0,
}

export const mainStore = defineStore("main", {
  state: () => {
    return defaultState;
  },
  getters: {},
  actions: {
    changeState() {
        this.count++;
        this.msg = this.msg === "hello world!" ? "你好 世界!" : "hello world!";
    },
  },
});
  1. 组件方法调用 store.方法名



Pinia中的Getters

Pinia 中的 getter 和 Vue 中的计算属性几乎一样,在获取 State值之前做一些逻辑处理。
getter中的值有缓存特性,如果值没有改变,多次使用也只会调用一次

  • 添加 getter方法
import { defineStore } from "pinia";
import { reactive } from "vue";

interface State {
  msg: string;
  count: number;
}

const defaultState = reactive({
  msg: "hello world!",
  count: 0,
})

export const mainStore = defineStore("main", {
  state: () => {
    return defaultState;
  },
  getters: {
      getState(state) {
          console.log('getter被调用');
          return `${state.msg}---${state.msg}`
      }
  },
  actions: {
    changeState() {
        this.count++;
        this.msg = this.msg === "hello world!" ? "你好 世界!" : "hello world!";
    },
  },
});
  • 组件内多次调用



vue3+Pinia的使用_第3张图片

  • getter 中不仅可以传递 state 直接改变数据状态,还可以使用 this 来改变数据
import { defineStore } from "pinia";

interface State {
  msg: string;
  count: number;
}

const defaultState: State = {
    msg: "hello world!",
    count: 0,
  }

export const mainStore = defineStore("main", {
  state: () => {
    return defaultState;
  },
  getters: {
      getState():string {
          console.log('getter被调用');
          return `${this.msg}---${this.msg}`
      }
  },
  actions: {
    changeState() {
        this.count++;
        this.msg = this.msg === "hello world!" ? "你好 世界!" : "hello world!";
    },
  },
});

store之间的相互调用

Pinia 中,可以在一个 storeimport 另外一个 store ,然后通过调用引入 store 方法的形式,获取引入store 的状态

  • 新建 store
// src/store/music.ts
import { defineStore } from "pinia";

interface State {
  list: string[];
}

const defaultState: State = {
  list: ['晴天', '枫', '以父之名', '手写的从前', '明明就', '半岛铁盒', '稻香', '最长的电影']
};

export const musicStore = defineStore("music", {
  state: () => {
    return defaultState;
  },
  getters: {},
  actions: {},
});
  • 在原 store 中引入 musicStore,并获取 list
// src/store/index.ts

import { defineStore } from "pinia";
import {musicStore} from './music'

interface State {
  msg: string;
  count: number;
}

const defaultState: State = {
    msg: "hello world!",
    count: 0,
  }

export const mainStore = defineStore("main", {
  state: () => {
    return defaultState;
  },
  getters: {
    getState():string {
        console.log('getter被调用');
        return `${this.msg}---${this.msg}`
    },
    //   另一个Store引用,获取musicStore中的list
    getMusicStoreList(): string[] {
        return musicStore().list
    }
  },
  actions: {
    changeState() {
        this.count++;
        this.msg = this.msg === "hello world!" ? "你好 世界!" : "hello world!";
    },
  },
});
  • 组件中使用



vue3+Pinia的使用_第4张图片

总结

总得来说,Pinia 就是 Vuex 的替代版,可以更好的兼容 Vue2,Vue3以及TypeScript。
在Vuex的基础上去掉了 Mutation,只保留了 state, getter和action。
Pinia拥有更简洁的语法, 扁平化的代码编排,符合Vue3 的Composition api

当然,文章中如果有什么错误或不足,欢迎评论区指正!

你可能感兴趣的:(vue.js,typescript)