【VUE基础】VUE3第九节—Pinia使用

Pinia简介

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。

安装Pinia

yarn add pinia
# 或者使用 npm
npm install pinia

在这里插入图片描述
创建一个 pinia 实例 (根 store) 并将其传递给应用:

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

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

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

显示下图证明使用pinia成功
在这里插入图片描述

存储数据和读取数据

Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有三个概念,state、getter 和 action,我们可以假设这些概念相当于组件中的 data、 computed 和 methods。

Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字:

import { defineStore } from 'pinia'

// 你可以任意命名 `defineStore()` 的返回值,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。
// (比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('alerts', {
  // 其他配置...
})

有两种写法
选项式Store

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    double: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

组合式Store

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

在 Setup Store 中:

  • ref() 就是 state 属性
  • computed() 就是 getters
  • function() 就是 actions

State

在 Pinia 中,state 被定义为一个返回初始状态的函数

import { defineStore } from 'pinia'

export const useUserStore = defineStore("user",{
    state(){
        return{
            username : "xiaoc",  //属性都将自动推断出它们的类型
            age : 25,
            poclist:[{ id: "dasdasdad01", title: "禅道 12.4.2 后台任意文件上传漏洞", content: "禅道 <= 12.4.2版本" },
            { id: "dasdasdad02", title: "Rails sprockets 任意文件读取漏洞", content: "Sprockets < 3.7.1" },
            { id: "dasdasdad03", title: "Rails sprockets 任意文件读取漏洞", content: "Sprockets < 3.7.1" },
            { id: "dasdasdad04", title: "HiKVISION 综合安防管理平台 report 任意文件上传漏洞", content: "HiKVISION 综合安防管理平台" }]
        }
    }
})

在这里插入图片描述

在这里插入图片描述

读取数据

默认情况下,你可以通过 store 实例访问 state,直接对其进行读写。

import {useUserStore} from '@/store/user'

const userStore =useUserStore()
console.log(userStore)

在这里插入图片描述

重置 state

使用选项式 API 时,你可以通过调用 store 的 $reset() 方法将 state 重置为初始值。

userStore.$reset()
console.log(userStore)

在 Setup Stores 中,您需要创建自己的 $reset() 方法:

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)

  function $reset() {
    count.value = 0
  }

  return { count, $reset }
})

修改state值

直接修改

userStore.username = "xiaohei"

在这里插入图片描述

批量修改

const userStore =useUserStore()
userStore.$patch({
  username:'xiaoc123456',
  age:100,
})

在这里插入图片描述

借助action修改(action中可以编写一些业务逻辑)

import { defineStore } from 'pinia'

export const useUserStore = defineStore("user",{
    state(){
        return{
            username : "xiaoc",  //属性都将自动推断出它们的类型
            age : 25,
            poclist:[{ id: "dasdasdad01", title: "禅道 12.4.2 后台任意文件上传漏洞", content: "禅道 <= 12.4.2版本" },
            { id: "dasdasdad02", title: "Rails sprockets 任意文件读取漏洞", content: "Sprockets < 3.7.1" },
            { id: "dasdasdad03", title: "Rails sprockets 任意文件读取漏洞", content: "Sprockets < 3.7.1" },
            { id: "dasdasdad04", title: "HiKVISION 综合安防管理平台 report 任意文件上传漏洞", content: "HiKVISION 综合安防管理平台" }]
        }
    },
    actions:{
        updateusername(){
            this.username ="这是通过action修改的名字"
        }
    }

组件中调用action即可

// 使用countStore
const countStore = useCountStore()

// 调用对应action
countStore.incrementOdd(n.value)

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

storeToRefs

通过解构获取数据,会提示获取到的数据是常数,而不是响应式数据

const {username,age,poclist} =userStore

function changeUsername(){
 ager += 1
}

在这里插入图片描述
需要使用storeToRefs

const {username,age,poclist} =storeToRefs(userStore)

function changeUsername(){
 age.value += 1
}

监听state

类似于 Vuex 的 subscribe 方法,你可以通过 store 的 $subscribe() 方法侦听 state 及其变化。比起普通的 watch(),使用 $subscribe() 的好处是 subscriptions 在 patch 后只触发一次 (例如,当使用上面的函数版本时)。

cartStore.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  // 和 cartStore.$id 一样
  mutation.storeId // 'cart'
  // 只有 mutation.type === 'patch object'的情况下才可用
  mutation.payload // 传递给 cartStore.$patch() 的补丁对象。

  // 每当状态发生变化时,将整个 state 持久化到本地存储。
  localStorage.setItem('cart', JSON.stringify(state))
})
userStore.$subscribe((mutation,state)=>{
  console.log(mutation,state);
  
})

在这里插入图片描述

存储本地会话

function changename(){
  userStore.updateusername()
  localStorage.setItem('poclist',JSON.stringify(userStore.poclist))
}

在这里插入图片描述

Getter

Getter 完全等同于 store 的 state 的计算值。可以通过 defineStore() 中的 getters 属性来定义它们。推荐使用箭头函数,并且它将接收 state 作为第一个参数:

import { defineStore } from 'pinia'

export const useUserStore = defineStore("user",{
    state(){
        return{
            username : "xiaoc",  //属性都将自动推断出它们的类型
            age : 25,
            poclist:[{ id: "dasdasdad01", title: "禅道 12.4.2 后台任意文件上传漏洞", content: "禅道 <= 12.4.2版本" },
            { id: "dasdasdad02", title: "Rails sprockets 任意文件读取漏洞", content: "Sprockets < 3.7.1" },
            { id: "dasdasdad03", title: "Rails sprockets 任意文件读取漏洞", content: "Sprockets < 3.7.1" },
            { id: "dasdasdad04", title: "HiKVISION 综合安防管理平台 report 任意文件上传漏洞", content: "HiKVISION 综合安防管理平台" }]
        }
    },
    getters:{
        doubleAge:(state)=>state.age*2
    },
    actions:{
        updateusername(){
            this.username ="这是通过action修改的名字"
        }
    }
})

使用其他 getter
我们也可以通过 this 访问到整个 store 实例,但(在 TypeScript 中)必须定义返回类型。这是为了避免 TypeScript 的已知缺陷,不过这不影响用箭头函数定义的 getter,也不会影响不使用 this 的 getter。

读取数据

可以直接访问 store 实例上的 getter

getters:{
    doubleAge:(state)=>state.age*2,
    changeDoubleAge():number{
        return this.doubleAge*4
    }
},

在这里插入图片描述

Action

Action 相当于组件中的 method。它们可以通过 defineStore() 中的 actions 属性来定义,并且它们也是定义业务逻辑的完美选择。

export const useCounterStore = defineStore('main', {
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++
    },
    randomizeCounter() {
      this.count = Math.round(100 * Math.random())
    },
  },
})

相关推荐

  1. vue3使用pinia

    2024-07-10 18:56:01       15 阅读
  2. vue3-Pinia

    2024-07-10 18:56:01       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 18:56:01       5 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 18:56:01       5 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 18:56:01       4 阅读
  4. Python语言-面向对象

    2024-07-10 18:56:01       7 阅读

热门阅读

  1. 两段序列帧动画播放,在ios机型上出现闪屏

    2024-07-10 18:56:01       11 阅读
  2. GPT-5或重塑我们的工作与生活

    2024-07-10 18:56:01       9 阅读
  3. Soul App Android一二三面凉经(2024)

    2024-07-10 18:56:01       9 阅读
  4. leetcode-动态规划-01背包

    2024-07-10 18:56:01       11 阅读
  5. 软件开发面试题C#,.NET知识点(续)

    2024-07-10 18:56:01       12 阅读
  6. git命令获取当前分支远端分支名

    2024-07-10 18:56:01       12 阅读
  7. oracle查询出表中某几个字段值不唯一的数据

    2024-07-10 18:56:01       12 阅读
  8. Git 常用命令

    2024-07-10 18:56:01       7 阅读
  9. C#规则引擎

    2024-07-10 18:56:01       10 阅读
  10. 深度学习Day-24:ResNeXt-50算法思考

    2024-07-10 18:56:01       10 阅读
  11. 完全背包求具体方案(c++题解)

    2024-07-10 18:56:01       10 阅读
  12. Pull Request

    2024-07-10 18:56:01       10 阅读
  13. stm32使用硬件SPI

    2024-07-10 18:56:01       8 阅读
  14. Elasticsearch7.10集群搭建

    2024-07-10 18:56:01       8 阅读