一、安装Pinia
npm install pinia
二、在src/main.ts
中引入并使用Pinia
// 引入 createApp 用于创建应用
import { createApp } from "vue";
// 引入 App 根组件
import App from './App.vue'
// 引入路由器
import router from "./router";
// 1、引入 createPinia
import { createPinia } from "pinia";
// 创建一个应用
const app = createApp(App)
// 使用路由器
app.use(router)
// 2、创建Pinia
const pinia = createPinia()
// 3、使用Pinia
app.use(pinia)
// 挂载整个应用到 app 容器中
// .mount() 方法应该始终在整个应用配置和资源注册完成后被调用。同时请注意,不同于其他资源注册方法,它的返回值是根组件实例而非应用实例。
app.mount('#app')
只要使用了Pinia
,即app.use(pinia)
,则在vue.js devtools
中立马能看到Pinia
。如下图(Edge浏览器)。
三、代码案例
1、新建文件src/store/loveTalk.ts
。(文件名你随意,只要在store
目录下就行)
import axios from "axios";
import { defineStore } from "pinia";
import { reactive } from "vue";
const useLoveTalkStore = defineStore('love-talk-id', () => {
// 相当于[state-状态] 先从浏览器的 localStorage 中取值
const loveTalks: string[] = reactive(JSON.parse(localStorage.getItem('loveTalks') as string) || [])
// 相当于[actions-动作]
async function addLoveTalk() {
const { data: { code, content } } = await axios.get('https://api.uomg.com/api/rand.qinghua');
console.log('情话:', code, content);
if (code === 1) {
// loveTalks 数组头部插入
loveTalks.unshift(content)
// 存储到浏览器的 localStorage 中,实现页面刷新数据不丢失
storeToLocalStorage()
}
}
// 存储数据到客户端,实现页面刷新数据不丢失
function storeToLocalStorage() {
localStorage.setItem('loveTalks', JSON.stringify(loveTalks))
}
// 向外暴露
return { loveTalks, addLoveTalk }
})
// 暴露useLoveTalkStore
export default useLoveTalkStore
2、App.vue
(App.vue是作者用来展示效果的页面,你们若不嫌麻烦,可以使用其他页面)
<template>
<div class="app">
<h2>父组件</h2>
<p>
宣言:
<ul>
<li v-for="(loveTalk, index) in loveTalks" :key="index">{{ loveTalk }}</li>
</ul>
</p>
<button @click="addLoveTalk">甜蜜暴坤</button>
<hr />
</div>
</template>
<script setup lang="ts" name="App">
import useLoveTalkStore from './store/loveTalk';
import { storeToRefs } from 'pinia';
import { toRefs } from 'vue';
let loveTalkStore = useLoveTalkStore()
// 可以直接从 useLoveTalkStore() 结果中解构方法
const { addLoveTalk } = loveTalkStore
console.log('loveTalkStore === ', loveTalkStore);
// 解构时,需要对数据做 storeToRefs 或 toRefs 操作,以保证 state 数据的响应式
// storeToRefs 只对 loveTalkStore 中的 state 做 toRefs 操作
const { loveTalks } = storeToRefs(loveTalkStore)
console.log('storeToRefs(loveTalkStore) === ', loveTalks);
// toRefs 会对 loveTalkStore 中的所有属性做 toRefs 操作
console.log('toRefs(loveTalkStore) === ', toRefs(loveTalkStore));
</script>
<style lang="scss" scoped>
.app {
margin: 150px;
padding: 30px;
background-color: bisque;
}
</style>
3、效果如下,刷新页面数据不会丢失。因为数据存储到浏览器的localStorage
中了,每次刷新时Pinia
都会先从localStorage
中读取数据赋给loveTalks
。
四、修改 Pinia 中的 state 数据
1、直接获取state
并修改
let loveTalkStore = useLoveTalkStore()
loveTalkStore.loveTalks.shift()
// 注意:只是修改了Pinia中的loveTalks的值,页面刷新数据也会重置。
// 想要保证页面刷新不丢失,可借助客户端存储 localStorage.setItem('xxx', xxx)
2、$patch批量修改
loveTalkStore.$patch((state) => {
state.a = 100
state.b = 200,
// 清空数组。注意:要调用数组提供的api才能保留响应式
state.loveTalks.splice(0, state.loveTalks.length)
})
// 注意:只是修改了Pinia中的loveTalks的值,页面刷新数据也会重置。
// 想要保证页面刷新不丢失,可借助客户端存储 localStorage.setItem('xxx', xxx)
3、调用store
中的actions
(1)调用页面:
addLoveTalk()
(2)自定义的store.ts:
// 相当于[state-状态] 先从浏览器的 localStorage 中取值
let loveTalks: string[] = reactive(JSON.parse(localStorage.getItem('loveTalks') as string) || [])
// 相当于[actions-动作]
function addLoveTalk() {
// loveTalks 数组头部插入
// loveTalks.unshift(content)
// 清空数组
loveTalks.splice(0, loveTalks.length)
// 存储到浏览器的 localStorage 中,实现页面刷新数据不丢失
storeToLocalStorage()
}
// 存储数据到客户端,实现页面刷新数据不丢失
function storeToLocalStorage() {
localStorage.setItem('loveTalks', JSON.stringify(loveTalks))
}