某些场景下建议vue query代替pinia原理解析
马格纳斯 人气:0前言
在 vue3 中,状态管理都是用的 pinia 来处理和存储从服务端获取的数据。使用 react 的同学应该对 swr
、react-query
、ahooks 的 useRequest(前两者的模仿)并不陌生,这些是专门用来处理数据请求的, 能够帮助你处理得到的数据、loading、error,还有缓存数据的功能等等。不止有 react-query
、vue-query
, 还有 svelte-query
和 solid-query
,这些其实都是同一个作者,是在同一个库中,通过它的核心底层来实现各个框架的功能。query 文档地址
使用区别
pinia
// 根文件 const pinina = createPinia(); app.use(pinia);
获取和修改用户信息,需要维护 user 状态, 页面中需要维护两个 loading 状态。
const useStore = defineStore('main', { state: () => ({ user: null, }), actions: { async getUser() { try { const user = await axios.get("/api/user"); this.user = user; } catch(err) { // } }, async updateUser(data) { try { const res = await axios.post("/api/user", data); // do something // this.user = res; } catch(err) { // } } }, })
<script setup> const getUserLoading = ref(false); const updateUserLoading = ref(false); // 获取用户信息 onMounted(async() => { getUserLoading.value = true; await store.getUser(); getUserLoading.value = false; }) // 修改用户信息 const updateUser = async () => { updateUserLoading.value = true; await store.updateUser({ username: "123" }) updateUserLoading.value = false; } </script>
vue-query
// 根文件 app.use(VueQueryPlugin)
// 新建一个文件 useUserQuery.js。需要必传两个值,queryKey 是缓存数据需要的唯一值,是个数组,我的习惯是直接用 api 地址。queryFn 是请求的方法。 // useUserQuery.js const api = "/api/user"; export const useUserQuery = (props) => useQuery({ queryKey: [api], queryFn: () => axios.get(api), ...props }); // 新建一个文件 useUserMutation.js,因为是修改数据,并没有缓存这个概念,所以不需要唯一值,只需要传入请求方法即可。 // useUserMutation.js const api = "/api/user"; export const useUserMutation = (props) => useMutation({ mutationFn: (data) => axios.post(api, data), ...props });
<script setup> // 获取用户信息 const { data, isLoading } = useUserQuery({ onSuccess: (data) => { // 成功回调 }, onError: (error) => { // 可以配置全局 onError 错误处理,这里不做介绍 }, }); const { isLoading, mutate } = useUserMutation(); // 修改用户信息 const updateUser = () => { mutate({ username: "123" }) } </script>
如果你在另一个地方也需要用到这个 user 数据,你可以再调用一次 useUserQuery,因为之前有缓存了,所以不会发出请求,但可以拿到数据。或者使用 queryClient 传入唯一值来获取数据。
const queryClient = useQueryClient(); const data = queryClient.getQueryData(["/api/user"])
总结
先来看看官方文档中怎么说 # Does TanStack Query replace Vuex, Pinia or other global state managers?
vue-query 只适用于存储从服务端获取的数据,如果有另外的数据需要存储还是要用到 pinia,但是这种数据是比较少的,这样也可以使得 pinia 中的代码量减少很多并简洁。当然这里介绍的 vue-query 的 api 是最简单的,你能想到的功能它基本都有,感兴趣的可以查看文档。
趋势
在 react 中使用 swr、react-query 是大势所趋,可以从 npm 下载量来看出来。相信今后在 vue 中 vue-query 也会有越来越多的使用,因为另外三大框架都是跟随 react 走的 hooks 的思想。
加载全部内容