Vue3+Pinia的使用


前言

  • 记录Vue3与Pinia的基本用法
  • 实现简单的数据状态控制

一、前期准备

二、使用步骤

1.使用vite创建vue3项目

  • npm init vite@latest
  • 选择vue — vue-ts
  • pnpm i 安装依赖
  • pnpm run dev 启动初始化项目
  • 安装pinia :pnpm i pinia
    在这里插入图片描述
    在这里插入图片描述

2.初始化pinia

  • 修改main.ts
import {
    
     createApp } from "vue";
import {
    
     createPinia } from "pinia";
import "./style.css";
import App from "./App.vue";

//创建 app 实例
const app = createApp(App);
// 创建 pinia 实例
const pinia = createPinia();
// 使用pinia实例
app.use(pinia);
// 挂载app
app.mount("#app");
  • src下创建store/index.ts
    基本框架:
import {
    
     defineStore } from "pinia";

export const useFirstStore = defineStore("first", {
    
    
  actions: {
    
    },
  getters: {
    
    },
  state: () => {
    
    
    return {
    
    };
  },
});
  • 进一步按需修改:
import {
    
     defineStore } from "pinia";
// 1.定义容器
// 2.使用容器的state
// 3.修改state
// 4.容器中的action使用

/**
 * 参数1:容器的ID(唯一),Pinia会将所有的容器挂载到根容器
 * 参数2:选项对象
 * 返回值是一个函数
 **/
export const useMainStore = defineStore("main", {
    
    
  /**
   * state
   * 类似于组件的data,存储全局状态
   * 1.必须是函数(箭头函数),箭头函数有助于ts类型推导。
   * 使用函数可以防止在服务端渲染的时候交叉请求导致数据状态污染
   **/
  state: () => {
    
    
    return {
    
    
      count: 1,
      foo: "2",
      arr: [1, 2],
    };
  },
  /**
   * getters
   * 类似于组件的computed,用来封装计算属性,有缓存功能(如在页面中调用三次,如果数值无变化则只执行一次)
   **/
  getters: {
    
    
    // ts指定返回值类型
    count10(): number {
    
    
      console.log("相当于computed,一来就调用");
      return this.count++;
    },
    // 使用state里的数据,指定数据源
    // count11(state) {
    
    
    //   return state.count++;
    // },
  },
  /**
   * actions
   * 类似于组件的methods,封装业务逻辑,修改state中数据的状态
   * actions中要使用this,所以不能使用箭头函数定义
   * (HelloWorld组件中的方式4)
   **/
  actions: {
    
    
    // 可以在使用本store(useMainStore)的时候调用actions中的方法来控制state状态
    // 定义num:number类型,可以接收从页面传来的值
    changeState(num: number) {
    
    
      // 通过this直接访问state中的数据
      // 单次修改
      this.count += num;
      this.foo = "zwt2";
      this.arr.push(666);
      // 也支持同时修改多个参数
      /*   // 对象方式
      this.$patch({
        count: this.count + 9,
        foo: this.foo + 12,
      }); */
      /*  // 函数方式
      this.$patch(state => {
        this.count++,
        this.foo + 12,
      }); */
    },
  },
});

3.组件使用

  • 修改HelloWord.vue为
  • 四个button包括不同的用法以及注意事项
<template>
  <div style="text-align: left">
    <h2>Pinia Test</h2>
    <ul>
      <li v-for="b in buttonContent">{
    
    {
    
     b.id }}——{
    
    {
    
     b.content }}</li>
    </ul>
    普通方式获取count:{
    
    {
    
     mainStore.count }}
    <hr />
    使用storeToRefs获得响应式数据:{
    
    {
    
     count }}
    <hr />
    <button @click="add">Button1</button>
    {
    
    {
    
     count }}
    <hr />
    <button @click="addSome">Button2</button>
    参数1: {
    
    {
    
     count }}—— 参数2: {
    
    {
    
     foo }}
    <hr />
    <button @click="addArr">Button3</button>
    参数1: {
    
    {
    
     count }}—— 参数2: {
    
    {
    
     foo }}—— 参数3:{
    
    {
    
     arr }}
    <hr />
    <button @click="changeInActions">Button4</button>
    参数1: {
    
    {
    
     count }}—— 参数2: {
    
    {
    
     foo }}—— 参数3:{
    
    {
    
     arr }}
    <hr />
    <h2>{
    
    {
    
     mainStore.count10 }}</h2>
    <!-- <h2>{
    
    {
    
     mainStore.count11 }}</h2> -->
  </div>
</template>

<script setup lang="ts">
import {
    
     useMainStore } from "../store";
import {
    
     storeToRefs } from "pinia";
import {
    
     ref } from "vue";
// 各类button对应的内容
const buttonContent = ref([
  {
    
    
    id: "button1",
    content: "修改state单个数据(用storeToRefs获得响应式数据)",
  },
  {
    
     id: "button2", content: "使用$patch修改state多个数据" },
  {
    
     id: "button3", content: "使用$patch函数方式直接修改state数据" },
  {
    
     id: "button4", content: "使用封装在actions中的方法修改state数据" },
]);
// 初始化实例
const mainStore = useMainStore();
console.log(mainStore);
// Pinia把state的数据做了reactive处理,解构赋值成响应式数据要借用toRefs
// 此处count被解构出来的是一个ref对象,需要使用count.value访问
const {
    
     count, foo, arr } = storeToRefs(mainStore);
// 方式一  最简单的state状态数据修改,单个数据
const add = () => {
    
    
  // console.log(count.value);
  count.value++;
};
//方式二 对state中的多个数进行修改,使用$patch(有内部优化,批量更新系)
// 比较简单的多个数据修改
const addSome = () => {
    
    
  mainStore.$patch({
    
    
    count: count.value + 9,
    foo: foo.value + 12,
  });
};
// 方式三 将$patch写成一个函数,可以对state中的数组进行修改(推荐)
// 比较复杂的多个数据修改(数组等)
// 通过指定添加参数state,写成一个函数可以直接对里面的数据进行修改
// 无需加上 .value,直接使用state.x=""修改
const addArr = () => {
    
    
  mainStore.$patch((state) => {
    
    
    state.count++;
    state.foo = "添加数组成功";
    state.arr.push(8);
  });
};
// 方式4 逻辑较多的时候可以使用封装在actions中的changeState方法(index中)
const changeInActions = () => {
    
    
  mainStore.changeState(12);
};
</script>

<style scoped>
button {
    
    
  background-color: #bfa;
}
</style>

4.效果展示

  • 在这里插入图片描述
  • 在这里插入图片描述

总结

  • 要多思考各个数据逻辑之间的调用关系
  • ts语法注意类型转换
  • storeToRefs可将state中的数据变为响应式数据在模板中直接使用
  • 更多内容见注释详解

猜你喜欢

转载自blog.csdn.net/CherishTaoTao/article/details/126427560