likes
comments
collection
share

为什么建议大多数场景下使用 vue-query 代替 pinia ?看完这篇文章你就明白了

作者站长头像
站长
· 阅读数 65

前言

在 vue3 中,状态管理都是用的 pinia 来处理和存储从服务端获取的数据。使用 react 的同学应该对 swrreact-queryahooks 的 useRequest(前两者的模仿)并不陌生,这些是专门用来处理数据请求的, 能够帮助你处理得到的数据、loading、error,还有缓存数据的功能等等。不止有 react-queryvue-query, 还有 svelte-querysolid-query,这些其实都是同一个作者,是在同一个库中,通过它的核心底层来实现各个框架的功能。query 文档地址

使用区别

pinia

// 根文件
const pinina = createPinia();
app.use(pinia);

获取和修改用户信息,需要维护 user 状态和两个 loading 状态

const useStore = defineStore('main', {
  state: () => ({
    user: null,
    getUserLoading: false,
    updateUserLoading: false,
  }),
  actions: {
    async getUser() {
      this.getUserLoading = true;
      try {
        const user = await axios.get("/api/user");
        this.user = user;
      } catch(err) {
       //
      }
      this.getUserLoading = false;
    },
    async updateUser(data) {
      this.updateUserLoading = true;
      try {
        await axios.post("/api/user", data);
      } catch(err) {
       //
      }
      this.updateUserLoading = false;
    }
  },
})
<script setup>
const store = useStore();

// 获取用户信息
store.getUser();

// 修改用户信息
const updateUser = () => {
  store.updateUser({ username: "123" })
}
</script>

<template>
  <loading :loading="store.getUserLoading" />
  ...
</template>

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"])

对比结果

先来看看 vue-query 文档中怎么说 # Does TanStack Query replace Vuex, Pinia or other global state managers?

优点

当项目越来越大时,pinia state 中的字段会越来越多,不好管理。每增加一个请求时,state 就会需要多加几个状态,还要处理 loading 等等。而 vue-query 只要新增一个对应的 hook 即可。当然还有非常多的 api,再次请求、轮询、对缓存的处理等等。

总结

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

趋势

在 react 中使用 swr、react-query 是大势所趋,可以从 npm 下载量来看出来。相信今后在 vue 中 vue-query 也会有越来越多的使用,因为另外三大框架都是跟随 react 走的 hooks 的思想。

转载自:https://juejin.cn/post/7185360908158238776
评论
请登录