Vue3从入门到实战:掌握状态管理库pinia(下部分)

1.storeToRefs

在Count.vue文件中

显的冗余了,如何更加优雅简化代码。用storeToRefs

补充:

为什么不用ToRefs呢?

使用的话会将所有数据都用ref引用包裹,其实方法等是没必要包裹的,具有一定风险


2.getters的使用

概念:当state中的数据,需要经过处理后再使用时,可以使用getters配置。

1.在count.ts文件增添getters

第二种写法:

1.简化写法

2.将up的xiaoli转换成大写

或者

追加getters配置并从组件中读取数据 。

count.ts文件代码:

javascript 复制代码
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文件代码:

javascript 复制代码
<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文件代码:

javascript 复制代码
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文件代码:

javascript 复制代码
<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代码:

javascript 复制代码
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}
})
相关推荐
尤水就下1 分钟前
🔥预热:在线文档的 block 架构是如何实现的(未完待续...)
前端·javascript·架构
全栈项目管理程序猿24 分钟前
ArcGIS JS 基础教程(29):CSVLayer 表格点位图层
前端·javascript
高级程序源35 分钟前
SSM仓储管理系统31582-计算机课程设计、毕业设计
vue.js·python·mysql·小程序·flask·课程设计
骑着蜗牛撵大象3271 小时前
豆包 Seed 驱动的记账智能体:从拍票抽取到月报生成的全链路落地记录
java·前端·javascript·结构化输出·豆包seed·多模态识别·记账系统
溪语流沙1 小时前
【Web全栈进阶】前端世界观:现代工具链与框架为什么存在
前端·javascript·vue.js
kyriewen1 小时前
我逐个测了 JSON.stringify 的 7 个坑:第 1 个就在丢数据
前端·javascript·程序员
积流成海2 小时前
用代码实现哈希计算器:Web Crypto API 实战
前端·算法·哈希算法·哈希函数·盘子工具站
data analyse 4562 小时前
服务端访问日志聚合 PV 与 UV 怎么实现?日志采集与口径设计
大数据·前端·数据分析
song5012 小时前
React Native for OpenHarmony 实战:三方库 react-native-ratings 的鸿蒙化适配指南
javascript·react native·react.js·分类·harmonyos
JavaGuide2 小时前
DeepSeek Harness 重磅更新,Codex、Claude Code 子智能体进官方插件列表了,还有 Git 工作树和思考翻译!
前端·后端