1.storeToRefs
在Count.vue文件中
显的冗余了,如何更加优雅简化代码。用storeToRefs
补充:
为什么不用ToRefs呢?
使用的话会将所有数据都用ref引用包裹,其实方法等是没必要包裹的,具有一定风险
2.getters的使用
概念:当state
中的数据,需要经过处理后再使用时,可以使用getters
配置。
1.在count.ts文件增添getters
第二种写法:
1.简化写法
2.将up的xiaoli转换成大写
或者
追加getters
配置并从组件中读取数据 。
count.ts文件代码:
import {defineStore} from 'pinia'export const useCountStore = defineStore('count',{ // actions里面放置的是一个一个的方法,用于响应组件中的“动作” actions:{ increment(value:number){ console.log('increment被调用了',value) if( this.sum < 10){ // 修改数据(this是当前的store) this.sum += value, this.up ='xiaoli', this.message='欢迎来看我的博客,别忘了点赞噢,谢谢' } } }, // 真正存储数据的地方 state(){ return { sum:6, up:'xxx', message:'xxxxxxxx' } }, getters:{ bigSum:state=>state.sum*10,//通过回调来简化写法 upperUp():String{//这里的state可以用this表示 return this.up.toUpperCase()//有this不能用回调!!! } }})
Conunt.vue文件代码:
<template> <div class="count"> <h2>当前求和为:{{ sum }},扩大十倍后: {{bigSum}}</h2> <h3>博主:{{up}},转换大写后:{{ upperUp }}</h3> <h4>他想说的话:{{ message }}</h4> <select v-model.number="n"> <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 setup lang="ts" name="Count"> import { ref,reactive } from "vue"; import {useCountStore} from '@/store/count' import { storeToRefs } from "pinia"; import{toRefs} from 'vue' const countStore = useCountStore() const{sum,up,message,bigSum,upperUp} = toRefs(countStore) // 数据 let n = ref(1) // 用户选择的数字 // 方法 function add(){ //第一种修改方式 // countStore.sum = 8888888, // countStore.up='小李同学', // countStore.message='欢迎来看我的博客,别忘了点赞噢,谢谢' //第二种修改方式 // countStore.$patch({ // sum:666, // up:'小李同学', // message:'欢迎来看我的博客,别忘了点赞噢,谢谢' // }) // 第三种修改方式 countStore.increment(n.value) } function minus(){ countStore.sum -= n.value }</script><style scoped> .count { background-color: skyblue; padding: 10px; border-radius: 10px; box-shadow: 0 0 10px; } select,button { margin: 0 5px; height: 25px; }</style>
3.$subscribe
通过 store 的 $subscribe()
方法侦听 state
及其变化 ,还可以实现刷新后仍保留数据
loveTalk.ts文件代码:
import {defineStore} from 'pinia' // 引入 pinia 的 defineStore 方法,用于定义状态管理仓库 import axios from 'axios' // 引入 axios 库,用于发送 HTTP 请求 import {nanoid} from 'nanoid' // 引入 nanoid 库,用于生成唯一的 ID // 导出名为 useTalkStore 的状态管理仓库 export const useTalkStore = defineStore('talk',{ // 定义 actions,用于包含异步操作或批量修改状态的操作 actions:{ // 定义一个异步方法 getATalk,用于获取一条随机的土味情话语录 async getATalk(){ // 发送 GET 请求到指定的 URL,并等待响应结果 // 使用连续解构赋值和重命名的方式获取响应数据中的 content 字段,并将其重命名为 title let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json') // 创建一个新的对象 obj,包含使用 nanoid 生成的唯一 ID 和上面获取的 title let obj = {id:nanoid(),title} // 将新创建的对象 obj 插入到 talkList 数组的开头 this.talkList.unshift(obj) } }, // 定义 state,用于返回组件或应用的初始状态 state(){ // 尝试从 localStorage 中获取 'talkList' 键对应的值,并解析为 JavaScript 对象或数组 // 如果解析失败或获取不到值,则返回一个空数组作为 talkList 的默认值 return { talkList:JSON.parse(localStorage.getItem('talkList') as string) || [] } } })
LoveTalk.vue文件代码:
<template> <div class="talk"> <button @click="getLoveTalk">获取一句土味情话</button> <ul> <li v-for="talk in talkList" :key="talk.id">{{talk.title}}</li> </ul> </div></template><script setup lang="ts" name="LoveTalk"> import {useTalkStore} from '@/store/loveTalk' import { storeToRefs } from "pinia"; const talkStore = useTalkStore() const {talkList} = storeToRefs(talkStore) talkStore.$subscribe((mutate,state)=>{ console.log('talkStore里面保存的数据发生了变化',mutate,state) localStorage.setItem('talkList',JSON.stringify(state.talkList)) }) // 方法 function getLoveTalk(){ talkStore.getATalk() }</script><style scoped> .talk { background-color: orange; padding: 10px; border-radius: 10px; box-shadow: 0 0 10px; }</style>
展示:
4.store的组合式写法
这种组合式写法的优势在于它提供了更好的代码组织和复用性。通过将逻辑封装在单独的函数中,使用 setup
函数和组合式 API 的其他函数(如 reactive
),可以更灵活地控制组件的状态和行为。
之前我们这样写就是选项式的写法
换成组合式写法 :
loveTalk代码:
import {defineStore} from 'pinia'import axios from 'axios'import {nanoid} from 'nanoid'//选项式写法/* export const useTalkStore = defineStore('talk',{ 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) || [] } }}) *///组合式写法import {reactive} from 'vue'export const useTalkStore = defineStore('talk',()=>{ // talkList就是state const talkList = reactive( JSON.parse(localStorage.getItem('talkList') as string) || [] ) // getATalk函数相当于action async function getATalk(){ // 发请求,下面这行的写法是:连续解构赋值+重命名 let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json') // 把请求回来的字符串,包装成一个对象 let obj = {id:nanoid(),title} // 放到数组中 talkList.unshift(obj) } return {talkList,getATalk}})