pinia介绍
- 更简洁的 APIPinia 的 API 设计得更加简洁和直观,使得状态管理更加容易理解和使用。与 Vuex 相比,Pinia 减少了样板代码,使得状态的定义和使用更加直接。
- 模块化Pinia 支持模块化的状态管理,允许你将状态逻辑组织到不同的模块中。每个模块可以包含自己的状态、getter、动作(actions)和插件,这有助于保持代码的组织性和可维护性。
- 响应式Pinia 使用 Vue 3 的 Composition API 和其响应式系统,这意味着状态的变化会自动触发视图的更新。Pinia 的响应式系统比 Vuex 更轻量,更高效。
- 插件系统Pinia 允许你通过插件扩展其功能。你可以编写自己的插件来添加额外的功能,如持久化、日志记录等。
- 更好的 TypeScript 支持Pinia 提供了更好的 TypeScript 支持,使得在 TypeScript 项目中使用状态管理更加方便和安全。
安装和基本使用
安装pinia
npm i pinia
搭建pinia环境
// 导入 Vue 的 createApp 方法,用于创建 Vue 应用
import { createApp } from "vue";
// 导入本地的 App 组件,这是应用的根组件
import App from "./App.vue";
import { createPinia } from "pinia";
//创建一个应用
const app=createApp(App);
const pinia=createPinia()
app.use(pinia)
app.mount('#app')
创建一个 Pinia Store
// 引入defineStore用于创建store
import {defineStore} from 'pinia'
// 定义并暴露一个store
export const useCountStore = defineStore('count',{
// 动作
actions:{},
// 状态
state(){
return {
sum:6
}
},
// 计算
getters:{}
})
// 引入defineStore用于创建store
import {defineStore} from 'pinia'
// 定义并暴露一个store
export const useTalkStore = defineStore('talk',{
// 动作
actions:{},
// 状态
state(){
return {
talkList:[
{id:'yuysada01',content:'你今天有点怪,哪里怪?怪好看的!'},
{id:'yuysada02',content:'草莓、蓝莓、蔓越莓,你想我了没?'},
{id:'yuysada03',content:'心里给你留了一块地,我的死心塌地'}
]
}
},
// 计算
getters:{}
})
在组件中使用 Store
<template>
<div class="count">
<h2>当前求和为:{{ sum }}</h2>
<select v-model.number="num">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add">加</button>
<button @click="minus">减</button>
</div>
</template>
<script lang="ts" setup name="Count">
import {ref} from 'vue'
import {useCountStore} from '@/store/count'
import { storeToRefs } from 'pinia'
const countStore=useCountStore()
//storeToRefs 只关心数据 不关心方法 只将数据变成ref包裹的对象
const {sum}=storeToRefs(countStore)
let num=ref(1)
function add(){
//第一种方式 直接改
countStore.sum +=num.value
//第二种方式 批量改
// countStore.$patch(
// {
// sum:888
// }
// )
}
function minus(){
countStore.sum -=num.value
}
</script>
<style scoped>
.count{
background-color: aqua;
padding: 10px;
border-radius: 10px;
box-shadow: 0 0 10px;
}
select,button{
margin: 0 5px;
height: 25px;
}
</style>
<template>
<div class="count">
<button @click="addTalk">点击来一句土味情话</button>
<ul v-for="talk in talkStore.talkList" :key="talk.id">
<li>{{ talk.content }}</li>
</ul>
</div>
</template>
<script lang="ts" setup name="LoveTalk">
import { reactive } from 'vue';
import axios from 'axios';
import {useTalkStore} from '@/store/loveTalk'
const talkStore=useTalkStore()
async function addTalk() {
let result = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json');
talkStore.talkList.push({ id: `${talkStore.talkList.length + 1}`, content: result.data.content });
}
</script>
<style scoped>
.count {
background-color: chartreuse;
padding: 10px;
border-radius: 10px;
box-shadow: 0 0 10px;
}
</style>
实现的简单效果
点击加或者减后 数字发生变化 点击再来一句土味情话 土味情话加1
storeToRefs
借助storeToRefs
将store
中的数据转为ref
对象,方便在模板中使用
storeToRefs
只关心数据
不关心方法
只将数据
变成ref
包裹的对象
<template>
<div class="count">
<h2>当前求和为:{{ sum }}</h2>
<select v-model.number="num">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add">加</button>
<button @click="minus">减</button>
</div>
</template>
<script lang="ts" setup name="Count">
import {ref} from 'vue'
import {useCountStore} from '@/store/count'
import { storeToRefs } from 'pinia'
const countStore=useCountStore()
//storeToRefs 只关心数据 不关心方法 只将数据变成ref包裹的对象
const {sum}=storeToRefs(countStore)
let num=ref(1)
function add(){
//第一种方式 直接改
countStore.sum +=num.value
//第二种方式 批量改
// countStore.$patch(
// {
// sum:888
// }
// )
}
function minus(){
countStore.sum -=num.value
}
</script>
<style scoped>
.count{
background-color: aqua;
padding: 10px;
border-radius: 10px;
box-shadow: 0 0 10px;
}
select,button{
margin: 0 5px;
height: 25px;
}
</style>
$subscribe
通过 store
的 $subscribe()
方法侦听 state
及其变化
countStore.$subscribe((mutate,state)=>{
console.log('LoveTalk',mutate,state)
localStorage.setItem('talk',JSON.stringify(sum.value))
})
当数字发生了改变的时候