当前位置: 首页 > news >正文

Vue3 使用 pinia

什么是Pinia

Pinia是 Vue 的存储库,它允许您跨组件/页面共享状态,与vuex功能一样。

准备

安装

npm install pinia
或者
yarn add pinia

使用

首先修改main.ts文件

main.ts

import './assets/main.css'import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'const app = createApp(App)
const pinia = createPinia()
// 使用pinia
app.use(pinia)
// 挂载到 #app
app.mount('#app')

现在若有多个组件要使用count组件中的 count 值 和 LoveTalk 组件中的 talkList 值,可使用 Pinia 将这些值存储到一个文件里,使用时直接导入提取即可。
首先在 src 文件夹下创建 store 文件夹用于存放相关ts文件,然后创建useCountStore.ts 和 useTalkListStore.ts文件。

useCountStore.ts

import { defineStore } from "pinia";export const useCountStore = defineStore("count", {actions:{increment(value: number){if (this.count < 10){this.count += value;}}},state(){return {count: 0,school:'atguigu',address:'宏福科技园'}},
});

useTalkListStore

import axios from "axios";
import { nanoid } from "nanoid";
import { defineStore } from "pinia";export const useTalkListStore = defineStore("talkList", {actions:{async getATalk(){let {data:{content:title}}  = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json');let obj = {id: nanoid(), title}this.talkList.unshift(obj);}},state(){return {talkList: [{id:'ftrfasdf01',title:'今天你有点怪,哪里怪?怪好看的!'},{id:'ftrfasdf02',title:'草莓、蓝莓、蔓越莓,今天想我了没?'},{id:'ftrfasdf03',title:'心里给你留了一块地,我的死心塌地'}]}},
});

使用定义在store中的数据。

Count.vue

<script lang="ts" setup name="Count">import { ref } from 'vue';import { useCountStore } from '@/store/useCountStore';import { storeToRefs } from 'pinia';let countStore = useCountStore();let n = ref(1);let { count, address, school } = storeToRefs(countStore);function add() {//第一种修改数据方式// countStore.count += n.value;// countStore.address = '北京市海淀区';// countStore.school = '清华大学';//第二种修改数据方式// countStore.$patch({//     count: countStore.count + n.value,//     address: '北京市海淀区',//     school: '清华大学'// });//第三种修改数据方式countStore.increment(n.value);}function minus() {}
</script><template><div class="count"><!-- <h1>Count: {{ countStore.count }}</h1><h2>地址: {{ countStore.address }}, 名称: {{ countStore.school }}</h2> --><h1>Count: {{ count }}</h1><h2>地址: {{ address }}, 名称: {{ school }}</h2><button @click="add"></button><button @click="minus"></button><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select></div>
</template><style scoped>.count {background-color: skyblue;padding: 10px;border-radius: 10px;box-shadow: 0 0 10px;}select,button {margin: 0 5px;height: 25px;}
</style>

LoveTalk.vue

<script lang="ts" setup name="LoveTalk">import axios from 'axios';import { reactive } from 'vue';import { nanoid } from 'nanoid';import { useTalkListStore } from '@/store/useTalkListStore';let talkListStore = useTalkListStore();function addTalk() {talkListStore.getATalk();}
</script><template><div class="talk"><h2>LoveTalk</h2><ul><li v-for="talk in talkListStore.talkList" :key="talk.id"> {{ talk.title }} </li></ul><button @click="addTalk">获取一条土味情话</button></div>
</template><style scoped>.talk {background-color: orange;padding: 10px;border-radius: 10px;box-shadow: 0 0 10px;}
</style>

上面两个组件实现了一个计数器和展示土味情话功能。Count组件中 select 标签中若不使用.number将字符串转化为数字,在点击 “加”按钮时会使用字符串拼接方式,例如选择2后,点击“加”后,数字就变成了字符串12。

实现效果

在这里插入图片描述

getters

useCountStore.ts

如果对 state 中的数据不满意,想要添加数据时,可以用getters方式,修改useCountStore.ts代码

import { defineStore } from "pinia";export const useCountStore = defineStore("count", {actions:{increment(value: number){if (this.count < 10){this.count += value;}},decrement(value: number){if (this.count > 0){this.count -= value;}}},state(){return {count: 0,school:'atguigu',address:'宏福科技园'}},// 通过 getters 添加新数据getters:{// 需要接受 state 作为参数bigSum(state){return state.count * 2;},smallSum: state => state.count - 1,upperSchool(state){return state.school.toUpperCase();}}
});

Count.vue

修改 Count.vue

<script lang="ts" setup name="Count">import { ref } from 'vue';import { useCountStore } from '@/store/useCountStore';import { storeToRefs } from 'pinia';let countStore = useCountStore();let n = ref(1);// 通过 storeToRefs 得到 getters 添加到的数据let { count, address, school, bigSum, smallSum, upperSchool } = storeToRefs(countStore);function add() {//第一种修改数据方式// countStore.count += n.value;// countStore.address = '北京市海淀区';// countStore.school = '清华大学';//第二种修改数据方式// countStore.$patch({//     count: countStore.count + n.value,//     address: '北京市海淀区',//     school: '清华大学'// });//第三种修改数据方式countStore.increment(n.value);}function minus() {countStore.decrement(n.value);}
</script><template><div class="count"><!-- <h1>Count: {{ countStore.count }}</h1><h2>地址: {{ countStore.address }}, 名称: {{ countStore.school }}</h2> --><h1>Count: {{ count }}</h1><h2>地址: {{ address }}, 名称: {{ school }}</h2><h2>bigSum: {{ bigSum }}</h2><h2>smallSum: {{ smallSum }}</h2><h2>upperSchool: {{ upperSchool }}</h2><button @click="add"></button><button @click="minus"></button><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select></div>
</template><style scoped>.count {background-color: skyblue;padding: 10px;border-radius: 10px;box-shadow: 0 0 10px;}select,button {margin: 0 5px;height: 25px;}
</style>

实现效果

在这里插入图片描述

$subscribe

Vue中可以用watch来监听数据的变化
同理,Pinia的store中的数据发生变化,可以用$subscribe来监听

这一篇,$subscribe+localStorage实现数据存储的案例,来介绍这个API的功能

LoveTalk.vue

<script lang="ts" setup name="LoveTalk">import axios from 'axios';import { reactive } from 'vue';import { nanoid } from 'nanoid';import { useTalkListStore } from '@/store/useTalkListStore';let talkListStore = useTalkListStore();//这个API的作用,类似于Vue中的watch,监听store中的数据变化talkListStore.$subscribe((mutate, state) => {localStorage.setItem('talkList', JSON.stringify(state.talkList));})function addTalk() {talkListStore.getATalk();}
</script><template><div class="talk"><h2>LoveTalk</h2><ul><li v-for="talk in talkListStore.talkList" :key="talk.id"> {{ talk.title }} </li></ul><button @click="addTalk">获取一条土味情话</button></div>
</template><style scoped>.talk {background-color: orange;padding: 10px;border-radius: 10px;box-shadow: 0 0 10px;}
</style>

useTalkListStore.ts

import axios from "axios";
import { nanoid } from "nanoid";
import { defineStore } from "pinia";export const useTalkListStore = defineStore("talkList", {actions:{async getATalk(){let {data:{content:title}}  = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json');let obj = {id: nanoid(), title}this.talkList.unshift(obj);}},state(){return {talkList: JSON.parse(localStorage.getItem('talkList') as string || '[]')}},
});
原文地址:https://blog.csdn.net/weixin_46515691/article/details/142680624
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mrgr.cn/news/45653.html

相关文章:

  • gin如何具体利用Server-Send-Events(SSE)实时推送技术实现消息推送
  • ai助手写作查重率多少?推荐这6款AI论文写作工具
  • 命名管道Linux
  • 2-116 基于matlab的主成分分析(PCA)及累积总和(CUSUM)算法故障监测
  • 计算机网络:数据链路层详解
  • GCC保姆级教程
  • 【Vue】Vue 快速教程
  • UE C++ 实时加载模型的总结
  • 101 公司战略的基本概念
  • 【物流配送中心选址问题】基于改进粒子群算法
  • dotnet7==windows ZIP方式安装和web demo和打包
  • SpringBoot Jar 包加密防止反编译
  • C语言-文件IO
  • 『网络游戏』Tips弹窗队列【10】
  • 头歌实践教学平台 大数据编程 实训答案(二)
  • Python 数据结构与算法全攻略:带你从新手速变高手
  • MARL多智能体强化学习
  • 【微服务】网关 - Gateway(下)(day8)
  • 【计算机网络】Tcp/IP五层协议,Udp报文组成,Udp与Tcp的区别
  • 微知-如何临时设置Linux系统时间?(date -s “2024-10-08 22:55:00“, time, hwclock, timedatectl)