pinia快速入门

pinia快速入门


pinia文章目录

  • pinia快速入门
  • 概念
  • 入门
    • 状态更改 actions
    • getters
    • 解构保持响应式
    • 不同的模块调用
    • 60s倒计时示例
  • 总结


概念

Pinia是一个用于Vue的状态管库, 类似于Vuex, 是Vue的另外一种状态管理方案;

Pinia优势

  • Vue2和Vue3都支持
  • 不需要嵌套模块, 符合Vue3的Composition api, 让代码更加扁平化, 没有命名空间的模块
  • 完整的TypeScript支持
  • 代码更加简洁, 可以实现很好的代码自动分割
  • 抛弃了Mutations的同步操作, 只有state, getters,和actions

入门

以Vue3为主

  1. 安装Pinia
yarn add pinia
# or with npm
npm install pinia
  1. 创建一个pinia并使用
import { createPinia } from 'pinia'
app.use(createPinia())
  1. 创建一个默认的store 如: 「countDown.ts」
  • defineStore(param1, param2)
    • param1 相当于为容器起一个名称,注意: 这个名字必须是唯一的, 不能重复
    • param2 是一个对象, 对象中有几个参数
      • state: () => ({}),
      • getters: {},
      • actions: {}
import { defineStore } from 'pinia';

interface todosModel {
	id: number;
	text: string;
	isFinished: boolean;
}

export const useCountDownStore = defineStore('countDown', {
  state: () => ({
	num: 1,
	todos: [] as todosModel[],
  }),
  getters: {},
  actions: {
	
  },
});
  1. 新建CountDown.vue文件






状态更改 actions

因为pinia抛弃了vuex中的mutations, 所以所有的方法都放在了actions中

// 方法1:
// 在任何地方直接更改
countDownStore.num++
// 方法2 
// 在countDown.ts的actions中新增如下函数
actions:  {
  addOne(text: number) {
 	if (text) {
	  this.num = text ? (this.num + text) : this.num + 1;
	}
  }
}
// 方法3
// 调用countDownStore的$patch方法,该方法可以同时修改多条数据 如:
countDownStore.$patch({ num: countDownStore.num + 1 })
// 同时$patch接受传递函数, 该方法接受复杂数据修改
countDownStore.$patch((state) => {
  state.num++;
  state.todos.push({ 
  	id: 1, 
  	text: 'hello, pinia!', 
  	isFinished: false
  })
})
// 方法4
// 直接整个更改state
countDownStore.$state = {
  num: 666,
  todos: [
    {id: 1, text: '全局更改state', isFinished: false}
  ]
}

getters

其实使用getters和直接使用state一样,类似于一个变量

state: () => ({
  card: '411000199001010203'
}),
getters: {
  hiddenCard(state): string {
	return state.card.replace(/(.{4}).*(.{2})/, "$1********$2")
  }
}

在.vue中使用

<template>
	<p>{{ countDownStore.hiddenCard }}</p>
<template>
<script setup lang="ts">
import { useCountDownStore } from '@/store/modules/countDown';
const countDownStore = useCountDownStore();
console.log(countDownStore.hiddenCard);
// 4110********03
</script>

解构保持响应式

在vue文件中解构pinia中的state会出现丢失响应式的问题,可以通过pinia出的 storeToRefs去进行解构可以保持变量的响应式

state: () => {
  return {
	num: 1
  }
}
import { storeToRefs } from 'pinia';
const countDownStore = useCountDownStore();
const { num } = storeToRefs(countDownStore);
// 这个时候num依旧保持响应式不会丢失

不同的模块调用

如以下有两个模块
「countDown.ts」, 「counter.ts」

countDown.ts

state: () => ({
   num: 1,
 }),
 actions: {
   changeNum(num: number): void {
     this.num = num;
   },
 },

counter.ts

import { useCountDownStore } from './countDown';
state: () => {
  return {
    count: 1,
  };
},
actions: {
  increment() {
    const countDownStore = useCountDownStore();
    countDownStore.changeNum(20);
    this.count++;
  },
},

在*.vue中调用 actions中的increment方法, 可以同时更改两个模块中的数据, 不需要像vuex一样还需要使用root:true

60s倒计时示例

import { defineStore } from 'pinia';

interface stateModel {
  countTime: number;
  isStart: boolean;
  timeId: ReturnType<typeof setInterval> | null;
}

export const useCountDownStore = defineStore('countDown', {
  state: (): stateModel => ({
    // 倒计时时间
    countTime: 10,
    // 是否开始倒计时
    isStart: false,
    // setInterval
    timeId: null,
  }),
  getters: {
    getBtnText(): string {
      return !this.isStart ? '获取验证码' : `${this.countTime}s`;
    },
  },
  actions: {
    clear() {
      this.timeId && window.clearInterval(this.timeId);
    },
    stopDown() {
      this.isStart = false;
      this.clear();
      this.timeId = null;
    },
    async startDown() {
      if (this.isStart || !!this.timeId) {
        return;
      }
      this.isStart = true;
      this.timeId = setInterval(() => {
        if (this.countTime === 1) {
          this.stopDown();
          this.countTime = 10;
        } else {
          this.countTime -= 1;
        }
      }, 1000);
    },
  },
});

在*.vue中使用如下

<template>
<button type="button" :disabled="isStart" @click="countDownStore.startDown">
  {{ getBtnText }}
</button>
</template>
<script setup lang="ts">
import { useCountDownStore } from '@/store/modules/countDown';
import { storeToRefs } from 'pinia';
const countDownStore = useCountDownStore();
// 对getters, state中的数据进行响应式解构
const { num, isStart, getBtnText } = storeToRefs(countDownStore);
</script>

总结

以上就是pinia的入门操作

你可能感兴趣的:(Pinia状态管理,typescript,vue.js)