1.pinia的基本特点

​ pinia同样是一个Vue
状态管理工具,它和vuex有很多相似的地方。本质上他是vuex团队核心成员开发的,在vuex上面提出了一些改进。与vuex相比,pinia去除了vuex中对于同步函数Mutations和异步函数Actions的区分。直接在Actions中便能够使用同步和异步方法(在vuex的开发计划中也将会除去同步和异步的区分)。其次相比于vuex,pinia对于typescript的支持性更好,友好的devTools支持,pinia只有1kb,简化了很多方法的写法。由于vuex比较完善,因此,pinia更加适合小型项目,vuex更加适合大型项目。

2.基本配置和使用

//利用vue-cli创建一个pinia项目(这里选择创建vue3项目)
vue create pinia
//在项目中安装pinia
npm install pinia@next
项目中导入pinia
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
//需要注意的是从pinia中结构出来的createPinia是一个函数,挂载需要先调用执行
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
配置状态管理专用文件,在根目录下创建一个store文件,并新建一个index.js文件
import {defineStore} from 'pinia';
export  const userTestStore = defineStore({//需要注意的是,defineStore返回的是一个回调方法
    id:'test',//test是该状态管理的唯一标志也可以使用defineStore(id,{});的形式
    state(){
     return {
         name:'hello pinia',
         age:20
     }       
    },
    getters:{
        testGetters(){
            return this.name+'...';//直接利用this便能够获取到里面的内容不需要使用state中间对象
        } 
    },
    actions:()=>{
        addAge:function(){
                setInterval(()=>{
                this.age++;
            },1000)
        }
    }
})
从下图可以看出,获取参数的方法被简化了。在这里插入图片描述

3.pinia传参与调用

下面给出调用store里面的带参方法例子:
//在状态管理工具中定义addAge函数
actions:{
      addAge(gap){
           this.age+=gap;
      }
 }
//组件中导入对应状态管理工具
import { userTestStore } from "./store";
const store = userTestStore();
const { addAge } = store;//解构出store实例里面的addAge方法

组件中使用

<div>output age:{{ store.age }}</div>
<button @click="addAge(10)">click for add age</button>

pinia官网有这么一句话

在这里插入图片描述
直接修改解构出来的 age是不ref类型,给出如下的错误案例:

  <div>error:{{ age }}</div>
  <button @click="test">change error age</button>
let { age } = store;
function test() {
  console.log(" error add age");
  age++;
}

解决方法,使用pinia里面的storeToRefs强转:

import { storeToRefs } from "pinia";
let { age } = storeToRefs(userTestStore());
function test() {
  age.value++;//注意这里要加上.value因为被转化成了ref类型
}
//这样就能够是实现有效修改了

demo 修改store值得五种方式,推荐使用action

//store-name.ts
export const enum Names {
    Test = 'Test'
}
// store.js
import { defineStore } from 'pinia'

// defineStore 调用后返回一个函数,调用该函数获得 Store 实体
import { defineStore } from "pinia";
import { Names } from "./store-name";
//定义的defineStore(),并且它需要一个唯一的名称,Names.Test名称抽离出去作为第一个参数传递
export const useTestStore = defineStore(Names.Test, {
    state: () => ({ current: 1, name: '小满' }),
    //computed:修饰一些值
    getters: {

    },
    //methods:可以做同步异步,提交state
    actions: {
        setCurrent(type: boolean) {
            //通过this指向属性
            if (!type) return false
            this.current++
        }
    }
})

// 在vue3中使用
<template>
  <div>
    pinia:{{ current }}---{{ Test.name }}
    <button @click="setCur">set</button>
  </div>
</template>
<script lang="ts" setup>
import { useTestStore } from './store';

const Test = useTestStore()
const current = computed(() => Test.current)
/**
 * state的五种方式修改值
    1.直接修改值
        Test.current=2
    2.通过$patch修改,支持单个或多个属性修改
        Test.$patch({current:33})
    3.$patch工厂函数方式
        Test.$patch((state) => {
          state.current = 99;
          state.name = '范迪塞尔'
        })
    4.$state 缺点是必须修改整个对象
        Test.$state = { current: 88, name: '123' }
    5.action
        Test.setCurrent()
 */
const setCur = () => {
  // Test.current = 2
  // Test.$patch({ current: 33 })
  Test.$patch((state) => {
    state.current = 99;
    state.name = '范迪塞尔'
  })
  Test.$state = { current: 88, name: '123' }
  Test.setCurrent(true)
}
</script>

<style lang = "scss" scoped>
</style>
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐