Pinia的使用及属性详解

一、 pinia特点

  • 兼容vue2和vue3版本
  • 删除mutations
  • 不能与vuex混用(注意避坑)
  • 支持插件扩展功能
  • 支持模块热更新无需加载页面可以修改容器,可以保持任何现有的状态
  • 更完美TS支持
  • 支持服务端渲染

二、 基本使用及容器组成

安装命令

复制代码
npm install pinia

在main.js中引入pinia并创建容器挂载到根实例上

scss 复制代码
// 引入挂载
import { createPinia } from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount('#app')

容器基本组成

  • 创建store/index.js,引入pinia
  • defineStore( )方法的第一个参数:相当于为容器起一个名字。注意:这里的名字必须唯一。这个是官方特别说明的一个事情。
  • defineStore( )方法的第二个参数:可以简单理解为一个配置对象,里边是对容器仓库的配置说明。
javascript 复制代码
//引入
import { defineStore } from "pinia" 
// 定义容器
export const useMain = defineStore('useStore', {
  // 存储全局状态
  // 必须是箭头函数: 为了在服务器端渲染的时候避免交叉请求导致数据状态污染
  state: () => {
    return {
      count: 0,
      list: [1, 2, 3, 4 ]
    }
  },
 //用来封装计算属性,有缓存功能,类似于computed
  getters: {
    
  },
  //编辑业务逻辑  类似于methods
  actions: {

  }

})

二、 属性详解

3.1 state

  • 存储全局状态类似于组件中的data
  • 定义数据,可在任意文件中引用修改
yaml 复制代码
state: () => {
  return {
    count: 0,
    list: [ 1, 2, 3 ]
  }
}
  • state页面使用
javascript 复制代码
//引入
import { useMain } from '@/store/index.js'
const useStoreMain = useMain()
less 复制代码
//使用
<p>{{ useStoreMain.count }}</p>
  • 简单的数据修改或逻辑可以直接在调用的页面进行 ``
ini 复制代码
  <button @click="useLeStore.count++">count++</button>
  <button @click="useLeStore.list.push('le')">list-push</button>
  • 如果我们批量更改数据建议使用$patch()方法,可以优化性能
ini 复制代码
  <button @click="changeMultiple">修改多个</button>
ini 复制代码
const changeMultiple = () => {
  useLeStore.$patch((state) => {
    console.log(state);
    state.count = 100;
    state.list = ["le", "lele"];
    console.log(state);
  });
};

3.2 getter

  • 封装计算属性,有缓存功能,类似于computed,
  • pinia中的getters只是在幕后做计算,不能传递任何参数,但是可以使用getter返回一个函数接受任何参数
  • 这里需要传入state才能拿到数据,可以直接使用state和this效果是一样的
  • 和计算属性一样的是你可以写很多getter通过this来直接访问,具体依据官网文档
javascript 复制代码
getters: {
    doubleCount: (state) => state.count * 2,
    doubleCountPlusOne() {
      return this.count + 1
    }
  }
  • getters页面使用
javascript 复制代码
//引入
import { useMain } from '@/store/index.js'
const useStoreMain = useMain()
less 复制代码
//使用
<p>{{ useStoreMain.getNum }}</p>

3.3 actions

  • 在这里我们获取state里数据是不需要传入,可以直接使用this.xxx
javascript 复制代码
actions: {
  addCount() {
    this.count++
  }
}
  • actions方法可以互相调用直接使用this
  • 例如下面的情况:
javascript 复制代码
//引入
import { defineStore } from "pinia"
// 定义容器  
export const leStore = defineStore('leStore', {
    // 存储全局状态
    // 必须是箭头函数: 为了在服务器端渲染的时候避免交叉请求导致数据状态污染
    state: () => {
        return {
            count: 0,
            list: [1, 2, 3, 4]
        }
    },
    //用来封装计算属性,有缓存功能,类似于computed
    getters: {
        doubleCount: (state) => state.count * 2,
    },
    //编辑业务逻辑,类似于methods
    actions: {
        addCount() {
            this.count++
        },
        addList() {
            this.addCount()
            this.list.push({ count: this.count, doubleCount: this.doubleCount })
            console.log(this.list);
        },
    }

})

三、页面使用

state数据使用

  • 可以直接使用,也可以直接结构出想要的数据,但是数据会出现无法实现响应式问题
  • 官方使用的APIstoreToRefs使state数据生成响应式
  • 引用官方APIstoreToRef作用就是把结构的数据使用ref做代理
  • 页面引入
javascript 复制代码
// 引入store
import { useMain } from '@/store/index.js'
const useStoreMain = useMain()
  • 直接使用
xml 复制代码
<template>
  <div class="greetings">
    <h1 class="green">{{ useStoreMain.count }}</h1>
  </div>
</template>
  • 数据解构
javascript 复制代码
//引入storeToRefs
import { storeToRefs } from 'pinia'
// 直接结构后数据不为响应式
// const { count } = useStoreMain;
// 使用storeToRefs()结构,数据为响应式
const { count } = storeToRefs(useStoreMain);
  • 数据解构-页面使用
xml 复制代码
<template>
  <div class="greetings">
    <h1 class="green">{{ count }}</h1>
    <button @click="count++">未解构按钮</button>
    <button @click="useStoreMain.count++">已解构按钮</button>
  </div>
</template>

getter数据使用

  • 略...
  • getter同理,不做过多演示

actions方法使用

javascript 复制代码
    actions: {
        addCount(e) {
            this.count += e
            console.log(this.count); 
        },
    }
  • 页面调用
ini 复制代码
  <button @click="changeCount">修改Count</button>
ini 复制代码
import { leStore } from "../store/leStore.js";
const useLeStore = leStore();
const changeCount = () => {
  useLeStore.addCount(10)
};

*本篇的所有使用方法都可以在多个容器之间直接可以互相调用,具体用法可依照业务场景自行扩展

相关推荐
musk12126 分钟前
electron 打包太大 试试 tauri , tauri 安装打包demo
前端·electron·tauri
万少1 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
OpenGL1 小时前
Android targetSdkVersion升级至35(Android15)相关问题
前端
程序员鱼皮1 小时前
Cursor 网页版来了,这下拉屎时也能工作了
计算机·ai·程序员·开发·项目·编程经验
rzl021 小时前
java web5(黑马)
java·开发语言·前端
Amy.Wang1 小时前
前端如何实现电子签名
前端·javascript·html5
海天胜景1 小时前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui
今天又在摸鱼2 小时前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js
蓝婷儿2 小时前
每天一个前端小知识 Day 21 - 浏览器兼容性与 Polyfill 策略
前端