Pinia的使用方法

2023-11-13

Pinia的作用

作用

Pinia 是 Vue.js 的轻量级状态管理库,他可以在组件和页面间共享状态。

相关链接

官方网站:https://pinia.vuejs.org/

中文文档:   https://pinia.web3doc.top/introduction.html

使用它的原因

  • Vuex的官方强烈推荐新新项目用Pinia。
  • Pinia 的 API 设计非常接近 Vuex 5 的提案。
  • pinia相比vuex4,对于vue3的pinia的api更友好。
  • pinia相比vuex4,具备完善的 类型推荐 ,对 TS 支持很友好。
  • Vue开发者工具支持pinia。

pinia集成

  1. 安装依赖 yarn add pinia or npm i pinia;
  2. 在main.js中创建pinia const pinia = createPinia();
  3. 将创建好的pinia应用到app中;
  4. 定义store;
创建单个store的步骤
1. 创建store/user.js
2. const userStore = defineStore("storeId"{
		state:()=>{return {}},
		actions:{},
		getters:{}	
});
###   配置对象有state,getters, actions
3. 导出userStore
  1. 创建store, 页面或组件中导入定义好的业务store,并调用userStore()。

(1)在main.js

import { createPinia } from 'pinia';
import { createApp } from 'vue';
import App  from './App.vue'


const app = createApp(App);
const pinia = createPinia();

app.use(pinia);
app.mount('#app');

(2)store/userStore.js

import { defineStore } from "pinia";

const useUserStore = defineStore('userStore', {
    state: ()=> {
        return {
            userName: 'heihei',
        }
    },

    actions: ()=>{

    },
    getters: ()=>{

    }
})
export default useUserStore;

(3) 在组件中使用

<script setup>
import { useRoute } from 'vue-router';
import useUserStore from '../store/uerStore';

    const userStore = useUserStore();

</script>
<template>
    Home
</template>

actions的使用

前置条件
在pinia中没有mutations,只有actions,不管是同步还是异步的操作,都可以在actions中定义。

步骤
定义同步方法

  1. 在actions中定义方法
  2. 操作数据
  3. 在视图template中使用方法

定义异步方法:同上

实例代码

(1)在userSotre的actions中提供方法并且修改数据

import { defineStore } from "pinia";
const useUserStore = defineStore('userStore', {
    state: () => {
        return {
            userName: 'heihei',
            age: 18
        }
    },
    actions: {
        increment() {
            this.age++
        },
        incrementAsync() {

            setTimeout(() => {
                this.age++

            }, 1000)
        }
    },
    getters: {

    }
})
export default useUserStore;

(2)在Home组件中使用

<script setup>
import { useRoute } from 'vue-router';
import useUserStore from '../store/uerStore';

    const userStore = useUserStore();

</script>
<template>
    Home
    {{userStore.age}}
    <button @click="userStore.increment">+1</button>
    <button @click="userStore.incrementAsync">异步+1</button>
</template>

总结

  1. 在actions 中可以定义同步异步方法
  2. actions中的方法直接修改数据this.数据名
  3. 在template中使用方法 (store的变量名.方法名)

getters的使用

作用
pinia中的getters和vuex中的基本是一样的,计算state的状态值。

步骤

  1. 在getters 中计算方法
  2. getters中的方法直接操作数据(this.数据名)
  3. 在template中使用 (store的变量名.方法名)

实例代码

(1)在getters中提供计算属性

import { defineStore } from 'pinia'
// 1. 创建store
// 参数1:store的唯一表示
// 参数2:对象,可以提供state actions getters
const useCounterStore = defineStore('counter', {
  state: () => {
    return {
      count: 0,
    }
  },
  getters: {
    double() {
      return this.count * 2
    },
  },
  actions: {
    increment() {
      this.count++
    },
    incrementAsync() {
      setTimeout(() => {
        this.count++
      }, 1000)
    },
  },
})

export default useCounterStore

(2)在组件中使用

  <h1>根组件---{{ counter.count }}</h1>
  <h3>{{ counter.double }}</h3>

总结

  1. 在getters中定义计算方法,
  2. 方法中操作数据并返回
  3. 在视图中使用计算值

storeToRefs的使用

前置条件
如果直接从pinia中解构数据,会丢失响应式, 使用storeToRefs可以保证解构出来的数据也是响应式的

import useAccountStore from '../store/account';
import useUserStore from '../store/uerStore';

const userStore = useUserStore();


const { age} = storeToRefs(userStore);

</script>
<template>
    Home
    <div>{{age}}</div>
    {{ userStore.age }} ---{{ userStore.descAge }}
    <button @click="userStore.increment">+1</button>
    <button @click="userStore.incrementAsync">-1</button>
</template>

总结
使用storeToRefs可以保证解构出来的数据也是响应式的

store间的取值

步骤

  1. 创建另一个store, useAccountStore ;
  2. 在useUserStore中导入useAccoutStore
  3. 在useUserStore中使用useAccoutStore 的数据和方法

实例代码
useAccountSore

import { defineStore } from "pinia";

const useAccountStore = defineStore('account',{
    state:()=>{
        return{
            accountNumber: '123456',
            money: 1000000
        }
    },
    actions:{
        addMoney(){
            this.money+=100;
        }
    }
})
export default useAccountStore;

useUserStore

import { defineStore } from "pinia";
import useAccountStore from "./account";
const useUserStore = defineStore('userStore', {
    state: () => {
        return {
            userName: 'heihei',
            age: 18
        }
    },
    actions: {
        increment(){
            this.age +=1;
        },
        incrementAsync(){
            setTimeout(()=>{
                this.age -= 1
            },1000)
        },
        addMoney(){
            const account = useAccountStore();
            account.addMoney();
            console.log(account.money)
        }
    },
    getters: {
        descAge(){
          return  this.age - 10;
        }
    }
})
export default useUserStore;

总结
导入另一个store,直接用xxxxstore名.的方式操作数据或方法

pinia模块化

前置条件
在复杂项目中,不可能把多个模块的数据都定义到一个store中,一般来说会一个模块对应一个store,最后通过一个根store进行整合
步骤

  1. 创建store/index文件;
  2. 在index.js中将给store导入;
  3. 添加统一导出useStore方法

(1)新建store/user.js文件

import { defineStore } from 'pinia'

const useUserStore = defineStore('user', {
  state: () => {
    return {
      name: 'zs',
      age: 100,
    }
  },
})

export default useUserStore

(2)新建store/index.js

import useUserStore from './user'
import useCounterStore from './counter'

// 统一导出useStore方法
export default function useStore() {
  return {
    user: useUserStore(),
    counter: useCounterStore(),
  }
}

(3)在组件中使用

<script setup>
import { storeToRefs } from 'pinia'
import useStore from './store'
const { counter } = useStore()

// 使用storeToRefs可以保证解构出来的数据也是响应式的
const { count, double } = storeToRefs(counter)
</script>

Pina 和 vuex的比较

Pinia API 与 Vuex ≤4 有很大不同,即

  • mutations 不再存在。他们经常被认为是 非常 冗长。他们最初带来了 devtools 集成,但这不再是问题。
  • 无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
  • 不再需要注入、导入函数、调用函数、享受自动完成功能!
  • 无需动态添加 Store,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手动使用 Store 进行注册,但因为它是自动的,您无需担心。
  • 不再有 modules 的嵌套结构。您仍然可以通过在另一个 Store 中导入和 使用 来隐式嵌套 Store,但 Pinia 通过设计提供平面结构,同时仍然支持 Store 之间的交叉组合方式。 您甚至可以拥有 Store 的循环依赖关系。
  • 没有 命名空间模块。鉴于 Store 的扁平架构,“命名空间” Store 是其定义方式所固有的,您可以说所有 Store 都是命名空间的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pinia的使用方法 的相关文章