目录
前言:
Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态,类似 Vuex, 是 Vue 的另一种状态管理方案,支持 Vue2 和 Vue3。
1.pinia是什么?
我们都知道Vuex在Vue2中主要充当状态管理的角色,所谓状态管理,简单来说就是一个存储数据的地方,存放在Vuex中的数据在各个组件中都能访问到,它是Vue生态中重要的组成部分。
在Vue3中,可以使用传统的Vuex来实现状态管理,也可以使用最新的pinia来实现状态管理。
2.Pinia 的优势
- Vue2和Vue3都支持
- pinia中action支持同步和异步,Vuex不支持
- 良好的Typescript支持
- 体积非常小,只有1KB左右
- pinia支持插件来扩展自身功能
- pinia中只有state、getter、action,抛弃了Vuex中的Mutation
3.安装 Pinia
# 使用 npm
npm install pinia
# 使用 yarn
yarn add pinia
4.pinia的基本使用与概念
4.1准备工作
修改main.js,引入pinia提供的createPinia方法,创建根存储。
// main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
//引入pinia中的createPinia方法
import {createPinia} from "pinia"
//创建根储存
const pinia = createPinia();
const app = createApp(App);
app.use(pinia);
app.mount('#app')
4.2store
store就是数据仓库的意思,我们数据都放在store里面,可以读写操作。
//src/store/goods.js
//引入函数
import { defineStore } from "pinia";
// 调用defineStore函数创建Store 实体
export const goodsStore = defineStore('users', {
})
创建store实体的defineStore函数有两个参数值
- name:字符串,必传项,该store的唯一id。
- options:对象,store的配置项,比如state等。
4.3添加state
我们需要存放的数据就放在state属性内。
//src/store/goods.js
import { defineStore } from "pinia";
export const goodsStore = defineStore('users', {
// state
state: () => {
return {
goods:["商品1","商品2"]
}
},
})
4.4使用store
这时我们store里面的配置项state就存在数据了,我们就能够去使用它
//App.vue
<script setup>
import {goodsStore} from "./store/store";
const store = goodsStore()
console.log(store)
</script>
打印出来我们刚刚的goods数据就在里面了
在引入数据的时候引入pinia中的storeToRefs函数这样修改的时候就不会丢失响应式
<script setup>
import {goodsStore} from "./store/store";
import { reactive } from "vue";
import {storeToRefs} from 'pinia'
const store = goodsStore()
const {goods} = storeToRefs(store)
</script>
<template>
<div>
<ul>
<li v-for="(item,index) in goods" :key="index">
{{ item }}
</li>
</ul>
</div>
</template>
结果:这时就拿到了store仓库中的数据了
4.5修改数据
修改单个数据
const updataGoods=()=>{
store.goods[0] = "西瓜"
}
$patch : 修改多行数据
const path = ()=>{
store.$patch({
goods:["西瓜","兰花"]
})
}
$state : 有数据就修改替换,没有数据就增加
const stata = ()=>{
store.$state = {
name:"wjd",
age:"289"
}
}
4.6重置数据
在我们修改了数据,需要回到初始数据的时候,这是时候就可以使用$reset()方法
const reset = () => {
store.$reset();
}
5.getters属性
getter就相当于Vue中的计算属性,它的作用就是返回一个新的结果
//src/store/goods.js
export const goodsStore = defineStore('users', {
// state
state: () => {
return {
goods:["商品1","商品2"],
list : ["手机","电脑"]
}
},
getters:{
getGoods(state){
return state.goods[0] + state.list[0]
}
}
})
在页面中使用getters
//app.vue
<template>
<div>
<ul>
<li v-for="(item,index) in goods" :key="index">
{{ item }}
</li>
//使用使用这样的方式
{{ store.getGoods }}
</ul>
</div>
</template>
getters传参
//src/store/goods.js
export const goodsStore = defineStore('users', {
// state
state: () => {
return {
goods:["商品1","商品2"],
list : ["手机","电脑"]
}
},
getters:{
getGoods(state){
return state.goods[0] + state.list[0]
},
//返回一个函数在调用的时候直接传递参数
getass(state){
return (num)=>{
return num + state.goods[0]
}
}
}
})
//app.js 中调用
{{ store.getass("1:") }}
6.Actions属性
Action 相当于组件中的 method,用来放置一些处理业务逻辑的方法,我们有业务代码的话最好是写在Actions中。
export const goodsStore = defineStore('users', {
// state
state: () => {
return {
goods:["商品1","商品2"],
list : ["手机","电脑"]
}
},
getters:{
getGoods(state){
return state.goods[0] + state.list[0]
},
getass(state){
return (num)=>{
return num + state.goods[0]
}
}
},
actions:{
setList(){
//通过this.xx 访问相应状态
this.list = [
"麻将",
"扑克"
]
}
}
})
在页面中使用
//app.vue
<script setup>
import {goodsStore} from "./store/store";
import { reactive } from "vue";
import {storeToRefs} from 'pinia'
const store = goodsStore()
const {goods} = storeToRefs(store)
store.setList()
</script>
7.所有代码
//main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import {createPinia} from "pinia"
const pinia = createPinia();
const app = createApp(App);
app.use(pinia);
app.mount('#app')
// src/store/store.js
import { defineStore } from "pinia";
// 调用defineStore函数创建Store 实体
export const goodsStore = defineStore('users', {
// state
state: () => {
return {
goods:["商品1","商品2"],
list : ["手机","电脑"]
}
},
getters:{
getGoods(state){
return state.goods[0] + state.list[0]
},
getass(state){
return (num)=>{
return num + state.goods[0]
}
}
},
actions:{
setList(){
this.list = [
"麻将",
"扑克"
]
}
}
})
//app.vue
<script setup>
import {goodsStore} from "./store/store";
import { reactive } from "vue";
import {storeToRefs} from 'pinia'
const store = goodsStore()
const {goods} = storeToRefs(store)
const updataGoods=()=>{
store.goods[0] = "西瓜"
}
const reset = () => {
store.$reset();
}
const path = ()=>{
store.$patch({
goods:["西瓜","兰花"]
})
}
const stata = ()=>{
store.$state = {
name:"wjd",
age:"289"
}
}
store.setList()
</script>
<template>
<div>
<ul>
<li v-for="(item,index) in goods" :key="index">
{{ item }}
</li>
<button @click="updataGoods">修改</button>
<button @click="reset">重置</button>
<button @click="path">批量</button>
<button @click="stata">覆盖修改</button>
{{ store.getass("1:") }}
</ul>
</div>
</template>
<style scoped>
div{
width: 100vw;
height: 100%;
}
li{
list-style: none;
}
</style>
总结:
Pinia 相比 Vuex 的知识点更少也更简单,而且 Pinia 可以自由扩展,使用起来也更加方便。