Vue 中 pinia 的使用

文章目录


前言

pinia 全局状态管理工具

一、Pinia是什么?

pinia 全局状态管理工具

Pinia.js 有如下特点:

  • 完整的 ts 的支持;

  • 足够轻量,压缩后的体积只有1kb左右;

  • 去除 mutations,只有 state,getters,actions;

  • actions 支持同步和异步;

  • 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的

  • 无需手动添加 store,store 一旦创建便会自动添加;

  • 支持Vue3 和 Vue2

二、使用步骤

1.安装方法:

yarn add pinia
npm install pinia -s

2.引入注册Vue3

main.ts:

import { createApp } from 'vue'
import App from './App.vue'
import {createPinia} from 'pinia'
 
const store = createPinia()
let app = createApp(App)
 
 
app.use(store)
 
app.mount('#app')

3.vue2中使用

main.js:

import { createPinia, PiniaVuePlugin } from 'pinia'
 
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
 
new Vue({
  el: '#app',
  // other options...
  // ...
  // note the same `pinia` instance can be used across multiple Vue apps on
  // the same page
  pinia,
})

//组件中使用
<template>
  <div>
    <button @click="changeVuex">拿pinia数据</button>
    <br />
    {{ test.data }}
  </div>
</template>

<script>
//导入
import { Test } from "@/store";
export default {
  props: {},
  data() {
    return {
        //创建pinia实例
      test: Test(),
    };
  },
  methods: {
    changeVuex() {
      console.log(this.test.data);
      this.test.changeData();
    },
  },
  components: {},
};
</script>

<style scoped lang="less"></style>

初始化仓库Store,使用仓库中的数据

1、src下新建一个文件夹Store

2、Store/新建文件index.ts

3、index.ts中定义仓库Store

import { defineStore } from 'pinia'


// Names 枚举 是为了定义一组数据  挡在defineStore中 作为唯一的值
 enum Names {
    Test1='Test1'
}
// defineStore(a,b)  a是给仓库绑定一个唯一的值,b是配置项,类型是对象,有三个参数 state,getters,actions
export const Test = defineStore(Names.Test1, {
    state: () => {
        return {
            current: 1,
            name:'张三'
        }
    },
    // 相当于一个计算属性 可以在不修改state值的情况下 对值进行一些操作
    getters: {
        
    },
    //可以进行同步异步的提交
    actions: {
        
    }
})

 在组件中使用Test仓库(Vue3为例)

<template>
  <div>
<!-- 3、使用仓库中的数据 -->
    <span> {{ testStore.current }}====={{ testStore.name }} </span>
  </div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
//1、导入pinia store
import { Test } from "./store";
export default defineComponent({
  setup() {
    //2、获取Test仓库中对象
    let testStore = Test();

    return {
      testStore,
    };
  },
});
</script>

 pinia中修改state中数据的五种方式

<template>
  <div>
    <h4>修改仓库中的数据:{{ testStore.test }}</h4>
    <h4>修改仓库中的数据:{{ testStore.num }}</h4>
    <button @click="changeNum">点击</button>
  </div>
</template>
<script lang="ts">
// 1. 引入Pinia  store
import { Test } from "../store";
import { defineComponent, ref } from "vue";
export default defineComponent({
  setup(props, context) {
    //2.获取Test仓库中对象
    let testStore = Test();
    console.log(testStore);
    console.log(testStore.test);

    function changeNum() {
      // (1) 改变state数据  (直接修改)
      testStore.num++;

      // (2) 使用$patch 批量修改  $patch({修改的属性1:值,修改的属性2:值})
      testStore.$patch({
        test: "张三66",
        num: 250,
      });

      // (3) 使用$patch(函数形式触发)
      testStore.$patch((state) => {
        state.test += "~~!!";
        state.num += 50;
      });

      // (4) 使用原始$state 修改 但state中的所有属性必须全部修改
      testStore.$state = {
        test: "毕云涛",
        num: 199,
      };

      // (5) 通过actions 修改
      testStore.modify();
    }
    return {
      changeNum,
      testStore,
    };
  },
});
</script>
<style lang="less" scoped></style>

调用actions进行异步修改

import { defineStore } from "pinia";
// defineStore(a,b) a是仓库绑定唯一的值 , 一般是id  ,b是配置项,类型是对象,有三个参数 state,getters,actions
const Test1 = "Test1";

// 异步修改
const actionsAsync = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        test: "异步修改了",
        num: 111,
      });
    }, 2000);
  });
};
export const Test = defineStore(Test1, {
  state: () => {
    return {
      test: "测试数据",
      num: 100,
    };
  },
  // pinia里的 actions 支持同步修改状态也支持异步修改状态
  actions: {
    // 定于actions
    modify() {
      this.num += 100;
    },
    // 异步
    async asyncModify() {
      let res = (await actionsAsync()) as any;
      console.log(typeof res);
      this.test = res.test;
      this.num = res.num;
    },
  },
  getters: {
    newTest(): any {
      return this.test + "~~";
    },
    newNum: (state) => {
      return ++state.num;
    },
  },
});


组件中使用:
<template>
  <div>
    <button @click="asyncChangeNum">点击异步修改actions</button>
  </div>
</template>
<script lang="ts">
// 1. 引入Pinia  store
import { Test } from "../store";
import { defineComponent, ref } from "vue";
export default defineComponent({
  setup(props, context) {
    //2.获取Test仓库中对象
    let testStore = Test();
    console.log(testStore);
    console.log(testStore.test);

    // 异步修改actions
    function asyncChangeNum() {
      testStore.asyncModify();
    }

    return {
      testStore,
      asyncChangeNum,
    };
  },
});
</script>
<style lang="less" scoped></style>

调用getters

// 相当于一个计算属性 可以在不修改state值的情况下 对值进行一些操作
    getters: {
        newName():string {
            return `${this.newCurrent}---${this.name +='~'}`
        },
        newCurrent: (state) => {
            return '$'+ ++state.current;
        }
    },

使用:
 <p>getters中newName:{{ testStore.newName }}</p>
   <p>getters中newCurrent:{{ testStore.newCurrent }}</p>

总结

官方文档Pinia:Pinia

git 地址: https://github.com/vuejs/pinia

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值