Pinia使用与详解

303 阅读2分钟
  • pinia 是vue官方推荐的全局状态管理工具,pinia只能在vue3中使用,不能再vue2中使用。

image.png

Pinia与Vuex的区别

  • pinia只有store、getter、actions,么有mutations,简化了状态管理的操作
  • pinia模块划分不需要modules,
  • pinia自动化代码拆分
  • pinia对ts支持很好以及vue3的composition API
  • pinia体积更小,性能更好

安装 pinia

npm i -S pinia

pinia的使用

pinia的工作原理

image.png

pinia的工作流程

image.png

创建pinia实例

在根目录下创建一个名为 store 的文件夹,并在其中创建一个名为 counter.js 的文件

  • 选项式api的格式:
import { defineStore } from 'pinia'; // 导入相应的方法
 // vuex是使用createStore来创建一整个store,pinia是使用defineStore来创建一个叫counter的store
export const useCounterStore = defineStore('counter', { // 名称counter必须唯一
  state: () => { // 相当于我们学习的组件中的data函数
    return {
      count: 0,
    }
  },
  getters: {  // 相当于我们学习的组件中的computed
    doubleCount: (state) => {
      return state.count * 2;
    }
  },
  actions: { // 相当于我们学习的组件中的methods,pinia同步异步均支持
    increment(n) {
      this.count += n;
    }
  }
})
  • 组合式api的格式:
import { defineStore } from 'pinia'; // 导入相应的方法
import { ref, computed } from 'vue';
 // vuex是使用createStore来创建一整个store,pinia是使用defineStore来创建一个叫counter的store
export const moneyStore = defineStore('account', ()=>{
  const count = ref(10000); // 初始化余额
  const doubleCount = computed(()=>{ // 使用computed计算金豆的数量
    return count.value * 100;
  });

  const increment = (n) => { // 增加的方法
    count.value += n;
  };
  return { count, doubleCount, increment }; // 暴露出数据和方法
});

挂载Pinia实例

在 main.js 中安装上面的store

import { createApp } from 'vue';
import { createPinia } from 'pinia';// 导入相应的方法
import App from './App.vue';

const app = createApp(App);

app.use(createPinia());  // 将Pinia用插件的方法安装
app.mount('#app');

用对象的方式使用

<script setup>
import { useCounterStore } from './stores/counter.js'
// 里面的变量提取出来,直接使用counter.count调用,因为counter是响应式的,因此使用counter.count做操作也是响应式的
const counter = useCounterStore();
</script>

<template>
  <main>
    <p>数字:{{ counter.count }}</p> 
    <p>2倍数字:{{ counter.doubleCount }}</p>
    <button @click="counter.increment">增加</button>
  </main>
</template>

提取属性的方式使用

为了从 Store 中提取属性,同时保持其响应性,您需要使用storeToRefs(),它将为每个响应性属性创建引用。

<script setup>
import { useCounterStore } from './stores/counter.js'
const counter = useCounterStore();
// const { count, doubleCount } = counter; // 直接提取属性,count和doubleCount不具备相应性
const { count, doubleCount } = storeToRefs(counter); // 现在count和doubleCount不具备相应性
</script>

<template>
  <main>
    <p>数字:{{ count }}</p> 
    <p>2倍数字:{{ doubleCount }}</p>
    <button @click="increment">增加</button>
  </main>
</template>