Pinia使用
- Pinia简介
 - 安装Pinia
 - 存储数据和读取数据
 - State
 - 读取数据
 - 重置 state
 - 修改state值
 - storeToRefs
 - 监听state
 
- Getter
 - 读取数据
 
- Action
 
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())
    },
  },
})
                


















