Vue——vue3.0 Pinia

281 阅读3分钟

Pinia:vue新一代状态管理插件

也就是更新版本的vuex(仓库)

官方文档:pinia.web3doc.top/introductio…

为什么要使用 Pinia?

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。 如果您熟悉 Composition API,您可能会认为您已经可以通过一个简单的 export const state = reactive({}). 这对于单页应用程序来说是正确的,但如果它是服务器端呈现的,会使您的应用程序暴露于安全漏洞。 但即使在小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处:

  • dev-tools 支持

    • 跟踪动作、突变的时间线
    • Store 出现在使用它们的组件中
    • time travel 和 更容易的调试
  • 热模块更换

    • 在不重新加载页面的情况下修改您的 Store
    • 在开发时保持任何现有状态
  • 插件:使用插件扩展 Pinia 功能

  • 为 JS 用户提供适当的 TypeScript 支持或 autocompletion

  • 服务器端渲染支持

如何使用Pinia

1.安装

npm install pinia

2.在main.js文件中引入:

import {createPinia} from "pinia"
let app=createApp(App)
app.use(createPinia())

3.创建一个store文件夹(也就是仓库)

在store文件夹中的js文件中引入pinia,注册仓库

import { defineStore } from 'pinia'

//导出仓库usestore
//注意:这里的usestore是由自己定义的,可以随便写
//但是官方建议我们定义的时候尽量用use开头命名,
//方便大家知道看见了这个名字,就知道它是一个定义的仓库
export const usestore =defineStore("注册的仓库名",{
state:()=>{
return {
仓库存储的数据
例如:msg:100
  } }
})

4.在组件中使用:

<script setup>
       //引入前面导出的仓库
	import useStore from "../store/index.js"
        //仓库
	let store=useStore()
	console.log(store.msg,111)	
</script>

5.修改仓库状态

1.单个修改仓库(就是修改一次,刷新一次)

let fn=function(){
//直接修改就行了
store.msg="修改的值"
//注意:这里的数据msg不是响应式数据
//需要将它转化为响应式数据,才可以刷新页面
//toRef、toRefs
}

2.重置仓库

//回到初始的状态
//将状态 重置 到其初始值
 store.$reset()

3.批量修改仓库(修改多个,只用一次刷新)

//第一种写法
store.$patch({
msg:20,
count:30
//注意:在这里修改仓库里面没有的值,是不会报错的
//但是也不会向仓库里面添加这个没有的值
//也就是说不能通过这个给仓库添加成员
})

//第二种写法:通过函数修改
store.$patch(()=>{
store.msg="chongq"
})

问题:单个修改与批量修改有什么区别?

答:状态刷新一次,可以批量修改

6.订阅修改:

//可以通过 store 的 $subscribe() 方法查看状态及其变化,通过patch修改状态时就会触发一次
store.$subscribe((mutation, state) => { 
  // 每当它发生变化时,将整个状态持久化到本地存储
  localStorage.setItem('test', JSON.stringify(state))
})

案例:

image.png

7.Getter

Getter 完全等同于 Store 状态的 计算值。 它们可以用 defineStore() 中的 getters 属性定义。 他们接收“状态”作为第一个参数以鼓励箭头函数的使用:(ps:虽然鼓励但是依然提供了非es6玩家的使用方式 内部可以用this代表state)

//store/index.js文件
export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  getters: {
    doubleCount: (state) => state.counter * 2,
  },
})
​
//组件中直接使用:  <p>Double count is {{ store.doubleCount }}</p>

8.Actions

在pinia中没有提供mutaion 因为Actions就够了(它可以异步同步的统一修改状态)

之所以提供这个功能 就是为了项目中的公共修改状态的业务统一

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  actions: {
    increment() {
      this.counter++//1.有this
    },
    randomizeCounter(state) {//2.有参数   想用哪个用哪个
      state.counter = Math.round(100 * Math.random())
    },
    randomizeCounter(state) {
        //异步函数
        axios("/test").then(res=>{
             state.counter = res.data.length
        })  
    }
  },
})
​
//组件中的使用:
  setup() {
    const store = useStore()
    store.increment()
    store.randomizeCounter()
  }

案例:

image.png

9.模块化

一个文件一个小仓库,仓库之间可以相互访问数据 不同组件也可以访问任意小仓库数据

//store/car.js文件
export const car = defineStore('car', {
  state: () => ({
    counter: 0,
  }),
  actions: {
   
  }
})
​
//store/userinfo.js文件
export const userinfo = defineStore('userinfo', {
  state: () => ({
    counter: 0,
  }),
  actions: {
     fn(state){state.counter=100}
  }
})
​
​
​
//A组件可以用car,userinfo两个仓库的数据
import {car} from "@/store/car.js"
import {userinfo} from "@/store/userinfo.js"
let store1=car()
store1.counter
let store2=userinfo()
store2.counter//car仓库使用userinfo仓库跟组件一样的使用方式
import {userinfo} from "@/store/userinfo.js"
let store2=userinfo()
store2.counter
store2.fn()
​