vue-query的使用

vue-query,类似于vuex/pinia,以缓存为目的,但侧重的是对网络请求的缓存。

这是我预想的使用场景:假设在各个页面都需要发起相同的请求,去获取数据,而这种数据在一定时间内不会发生变化,那么这种请求数据是可以被缓存下来的。

pinia用于处理公共状态,vue-query用于处理服务端状态,准确的说是把原本需要在pinia中处理的服务端状态迁移到vue-query中。

本实例使用的vue版本是3.3.0

vue-query

github地址:DamianOsipiuk/vue-query: Hooks for fetching, caching and updating asynchronous data in Vue (github.com)

1、安装vue-query

bash 复制代码
npm i vue-query 

2、在入口文件中引入

javascript 复制代码
import { VueQueryPlugin } from 'vue-query'
import { createApp } from 'vue'

import router from './router'

import App from './App.vue'
const app = createApp(App)
app.use(router)
app.use(VueQueryPlugin);

app.mount('#app')

3、使用

index.vue

html 复制代码
<template>
  <div>
首页
{{ isLoading }}
<showList/>
<button @click="goAbout">去about页面</button>
  </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'
import ajax from '@/common/ajax'
import {useQuery} from 'vue-query';
import {useRouter} from 'vue-router'
import showList from '@/components/showList.vue';
const router = useRouter();
const getData = ()=>{
//这里使用的是node写的接口服务,自行替换自己的接口
  return ajax('/live/api/packages/list');
}
const goAbout = ()=>{
  router.push('/about')
}
const {data,isLoading} = useQuery(["listData"], ()=>getData());

</script>

<style scoped>

</style>

components/showList.vue

html 复制代码
<template>
    <div>
        <h2>列表组件</h2>
        <ul>
            <li v-for="packages in packageList" :key="packages._id">{{ packages.name }}</li>
        </ul>
    </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { useQuery } from 'vue-query';

const {data} = useQuery(["listData"]);


const packageList = computed(() => data.value?.data.data.list);


</script>

<style scoped></style>

效果展示

可以看到组使用 listData的缓存数据

接下来在首页跳转到about页面,在about页面也使用这份缓存数据

about.vue

html 复制代码
<template>
  <div>
    <h2>About页面使用缓存数据</h2>
    <ul>
      <li v-for="packages in packageList" :key="packages._id">{{ packages.name }}</li>
    </ul>
    </div>
</template>
 
<script setup lang="ts">
import { computed } from 'vue'

import { useQuery } from 'vue-query';
const { data } = useQuery(["listData"]);

const packageList = computed(() => data.value?.data.data.list);

</script>
 
<style scoped></style>

效果展示

跳转到about页面,是没有重新发送请求的,使用的是之前的缓存数据

但是发现在页面重新获取焦点和切换路由后,会重新发送请求,看文档说以下添加配置,但是发现不起效

javascript 复制代码
const {data,isLoading} = useQuery(["listData"], ()=>getData(),{
    cacheTime: Infinity,
    staleTime: Infinity,
});

vue-query

@tanstack/vue-query

@tanstack/vue-query可以说是vue-query的强化版本,TanStack Query 是一个开源、功能齐全、支持 TypeScript 的库,非常适合用于处理客户端状态,处理异步或服务器状态。它支持React,Vue,Svelte,Solid框架,大多时候我们都会我们使用的框架把它叫做vue-query或者react-query。

特点

  • 非常好用的query库,目的是为了缓存后端api的结果,不用像以前一样,手动将结果一个一个存储到store,并且提供了一些非常好用的hook方法
  • 非常适合用于处理客户端状态,处理异步或服务器状态
  • 默认支持异步
  • 它并不是用于替代axios等请求库,而只是作为外层的封装,方便控制请求与结果

安装:

bash 复制代码
npm i @tanstack/vue-query

在入口文件注册

bash 复制代码
import { VueQueryPlugin } from '@tanstack/vue-query'
app.use(VueQueryPlugin);

复用上面的代码,只需要将vue-query改为@tanstack/vue-query

index.vue

html 复制代码
<template>
  <div>
    首页
    {{ isLoading }}
    <!-- {{ data }} -->
    <!-- {{ datas }} -->
    <showList />
    <button @click="goAbout">去about页面</button>
  </div>
</template>

<script setup lang="ts">

import ajax from '@/common/ajax'
import { useQuery } from '@tanstack/vue-query';

import { useRouter } from 'vue-router'
import showList from '@/components/showList.vue';
const router = useRouter();

const getData = () => {


  return ajax('/live/api/packages/list');
}

const goAbout = () => {
  router.push('/about')
}


const { data, isLoading } = useQuery({
  queryKey: ['listData'],
  queryFn: () => getData(),
  
});

</script>

<style scoped></style>

components/showList.vue

html 复制代码
<template>
    <div>
        <h2>列表组件</h2>
        <ul>
            <li v-for="packages in packageList" :key="packages._id">{{ packages.name }}</li>
        </ul>
    </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import {useQuery} from '@tanstack/vue-query';


const { data } = useQuery({
    queryKey: ['listData']
});

const packageList = computed(() => data.value?.data.data.list);


</script>

<style scoped></style>

about.vue

html 复制代码
<template>
  <div>
    <h2>About页面使用缓存数据</h2>
    <ul>
      <li v-for="packages in packageList" :key="packages._id">{{ packages.name }}</li>
    </ul>
    </div>
</template>
 
<script setup lang="ts">
import { computed } from 'vue'

import { useQuery } from '@tanstack/vue-query';
const { data } = useQuery({
  queryKey:["listData"]
});

const packageList = computed(() => data.value?.data.data.list);

</script>
 
<style scoped></style>

设置refetchInterval,在规定间隔中重新发送请求

javascript 复制代码
const { data, isLoading } = useQuery({
  queryKey: ['listData'],
  queryFn: () => getData(),
  refetchInterval: 12000
});

可以看到network会重新发送请求

@tanstack/vue-query

总结

vue-query 只适用于存储从服务端获取的数据,如果有另外的数据需要存储还是要用到 pinia,但是这种数据是比较少的,这样也可以使得 pinia 中的代码量减少很多并简洁。当然这里介绍的 vue-query 的 api 是最简单的,你能想到的功能它基本都有,感兴趣的可以查看文档。

相关推荐
子兮曰18 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰18 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万18 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝18 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋19 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁19 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王952721 小时前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大21 小时前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师21 小时前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学1 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端