使用Vue?Query實(shí)現(xiàn)高級(jí)數(shù)據(jù)獲取的示例詳解
構(gòu)建現(xiàn)代大規(guī)模應(yīng)用程序最具挑戰(zhàn)性的方面之一是數(shù)據(jù)獲取。加載和錯(cuò)誤狀態(tài)、分頁(yè)、過(guò)濾、排序、緩存等許多功能可能會(huì)增加復(fù)雜性,并經(jīng)常使應(yīng)用程序充滿大量的樣板代碼。
這就是 Vue Query 庫(kù)的用途所在。它使用聲明式語(yǔ)法處理和簡(jiǎn)化數(shù)據(jù)獲取,并在幕后為我們處理所有那些重復(fù)的任務(wù)。
理解 Vue Query
Vue Query 并不是 Axios
或 fetch
的替代品。它是在它們之上的一個(gè)抽象層。
管理服務(wù)器狀態(tài)時(shí)面臨的挑戰(zhàn)與管理客戶端狀態(tài)不同,而且更為復(fù)雜。我們需要解決的問(wèn)題包括:
- 緩存...(可能是編程中最難的事情)
- 將對(duì)相同數(shù)據(jù)的多個(gè)請(qǐng)求進(jìn)行去重,合并為一個(gè)請(qǐng)求
- 在后臺(tái)更新過(guò)時(shí)的數(shù)據(jù)
- 了解何時(shí)數(shù)據(jù)過(guò)時(shí)
- 盡快反映數(shù)據(jù)的更新情況
- 像分頁(yè)和懶加載這樣的性能優(yōu)化
- 管理服務(wù)器狀態(tài)的內(nèi)存和垃圾回收
- 使用結(jié)構(gòu)共享來(lái)記憶化查詢結(jié)果
Vue Query真棒,因?yàn)樗鼮槲覀冸[藏了所有這些復(fù)雜性。它默認(rèn)基于最佳實(shí)踐進(jìn)行配置,但也提供了一種方法來(lái)更改這個(gè)配置(如果需要的話)。
基本示例使用
通過(guò)構(gòu)建以下簡(jiǎn)單的應(yīng)用程序來(lái)展示這個(gè)圖書館。
在頁(yè)面級(jí)別上,我們需要獲取所有產(chǎn)品,將它們展示在一個(gè)表格中,并有一些簡(jiǎn)單的額外邏輯來(lái)選擇其中的一個(gè)。
<!-- Page component without Vue-Query --> <script setup> import { ref } from "vue"; import BoringTable from "@/components/BoringTable.vue"; import ProductModal from "@/components/ProductModal.vue"; const data = ref(); const loading = ref(false); async function fetchData() { loading.value = true; const response = await fetch( `https://dummyjson.com/products?limit=10` ).then((res) => res.json()); data.value = response.products; loading.value = false; } fetchData(); const selectedProduct = ref(); function onSelect(item) { selectedProduct.value = item; } </script> <template> <div class="container"> <ProductModal v-if="selectedProduct" :product-id="selectedProduct.id" @close="selectedProduct = null" /> <BoringTable :items="data" v-if="!loading" @select="onSelect" /> </div> </template>
在選擇產(chǎn)品的情況下,我們會(huì)顯示一個(gè)模態(tài)框,并在顯示加載狀態(tài)時(shí)獲取額外的產(chǎn)品信息。
<!-- Modal component without Vue-Query --> <script setup> import { ref } from "vue"; import GridLoader from 'vue-spinner/src/GridLoader.vue' const props = defineProps({ productId: { type: String, required: true, }, }); const emit = defineEmits(["close"]); const product = ref(); const loading = ref(false); async function fetchProduct() { loading.value = true; const response = await fetch( `https://dummyjson.com/products/${props.productId}` ).then((res) => res.json()); product.value = response; loading.value = false; } fetchProduct(); </script> <template> <div class="modal"> <div class="modal__content" v-if="loading"> <GridLoader /> </div> <div class="modal__content" v-else-if="product"> // modal content omitted </div> </div> <div class="modal-overlay" @click="emit('close')"></div> </template>
添加 Vue Query
這個(gè)庫(kù)預(yù)設(shè)了一些既激進(jìn)又理智的默認(rèn)設(shè)置。這意味著我們?cè)诨臼褂脮r(shí)不需要做太多操作。
<script setup> import { useQuery } from "vue-query"; function fetchData() { // Make api call here } const { isLoading, data } = useQuery( "uniqueKey", fetchData ); </script> <template> {{ isLoading }} {{ data }} </template>
在上述例子中:
- uniqueKey 是用于緩存的唯一標(biāo)識(shí)符
- fetchData 是一個(gè)函數(shù),它返回一個(gè)帶有API調(diào)用的 promise
- isLoading 表示API調(diào)用是否已經(jīng)完成
- data 是對(duì)API調(diào)用的響應(yīng)
我們將其融入到我們的例子中:
<!-- Page component with Vue-Query --> <script setup> import { ref } from "vue"; import { useQuery } from "vue-query"; import BoringTable from "@/components/BoringTable.vue"; import OptimisedProductModal from "@/components/OptimisedProductModal.vue"; async function fetchData() { return await fetch(`https://dummyjson.com/products?limit=10`).then((res) => res.json()); } const { isLoading, data } = useQuery( "products", fetchData ); const selectedProduct = ref(); function onSelect(item) { selectedProduct.value = item; } </script> <template> <div class="container"> <OptimisedProductModal v-if="selectedProduct" :product-id="selectedProduct.id" @close="selectedProduct = null" /> <BoringTable :items="data.products" v-if="!isLoading" @select="onSelect" /> </div> </template>
現(xiàn)在,由于庫(kù)已經(jīng)處理了加載狀態(tài),所以獲取函數(shù)已經(jīng)簡(jiǎn)化。
同樣適用于模態(tài)組件:
<!-- Modal component with Vue-Query --> <script setup> import GridLoader from 'vue-spinner/src/GridLoader.vue' import { useQuery } from "vue-query"; const props = defineProps({ productId: { type: String, required: true, }, }); const emit = defineEmits(["close"]); async function fetchProduct() { return await fetch( `https://dummyjson.com/products/${props.productId}` ).then((res) => res.json()); } const { isLoading, data: product } = useQuery( ["product", props.productId], fetchProduct ); </script> <template> <div class="modal"> <div class="modal__content" v-if="isLoading"> <GridLoader /> </div> <div class="modal__content" v-else-if="product"> // modal content omitted </div> </div> <div class="modal-overlay" @click="emit('close')"></div> </template>
useQuery
返回名為 data 的響應(yīng),如果我們想要重命名它,我們可以使用es6的解構(gòu)方式,如下const { data: product } = useQuery(...)
當(dāng)在同一頁(yè)面進(jìn)行多次查詢時(shí),這也非常有用。- 由于同一功能將用于所有產(chǎn)品,因此簡(jiǎn)單的字符串標(biāo)識(shí)符將無(wú)法工作。我們還需要提供產(chǎn)品id
["product", props.productId]
我們并沒(méi)有做太多事情,但我們從這個(gè)盒子里得到了很多。首先,即使在沒(méi)有網(wǎng)絡(luò)限制的情況下,當(dāng)重新訪問(wèn)一個(gè)產(chǎn)品時(shí),從緩存中得到的性能提升也是顯而易見(jiàn)的。
默認(rèn)情況下,緩存數(shù)據(jù)被視為過(guò)時(shí)的。當(dāng)以下情況發(fā)生時(shí),它們會(huì)自動(dòng)在后臺(tái)重新獲?。?/p>
- 查詢掛載的新實(shí)例
- 窗口被重新聚焦
- 網(wǎng)絡(luò)已重新連接
- 該查詢可選擇配置為重新獲取間隔
此外,失敗的查詢會(huì)在捕獲并向用戶界面顯示錯(cuò)誤之前,靜默地重試3次,每次重試之間的延遲時(shí)間呈指數(shù)級(jí)增長(zhǎng)。
添加錯(cuò)誤處理
到目前為止,我們的代碼都堅(jiān)信API調(diào)用不會(huì)失敗。但在實(shí)際應(yīng)用中,情況并非總是如此。錯(cuò)誤處理應(yīng)在 try-catch
塊中實(shí)現(xiàn),并需要一些額外的變量來(lái)處理錯(cuò)誤狀態(tài)。幸運(yùn)的是,vue-query
提供了一種更直觀的方式,通過(guò)提供 isError
和 error
變量。
<script setup> import { useQuery } from "vue-query"; function fetchData() { // Make api call here } const { data, isError, error } = useQuery( "uniqueKey", fetchData ); </script> <template> {{ data }} <template v-if="isError"> An error has occurred: {{ error }} </template> </template>
總結(jié)
總的來(lái)說(shuō),Vue Query通過(guò)用幾行直觀的Vue Query邏輯替換復(fù)雜的樣板代碼,簡(jiǎn)化了數(shù)據(jù)獲取。這提高了可維護(hù)性,并允許無(wú)縫地連接新的服務(wù)器數(shù)據(jù)源。
直接的影響是應(yīng)用程序運(yùn)行更快、反應(yīng)更靈敏,可能節(jié)省帶寬并提高內(nèi)存性能。此外,我們沒(méi)有提到的一些高級(jí)功能,如預(yù)取、分頁(yè)查詢、依賴查詢等,提供了更大的靈活性,應(yīng)該能滿足您的所有需求。
如果你正在開發(fā)中到大型的應(yīng)用程序,你絕對(duì)應(yīng)該考慮將 Vue Query 添加到你的代碼庫(kù)中。
以上就是使用Vue Query實(shí)現(xiàn)高級(jí)數(shù)據(jù)獲取的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Vue Query獲取高級(jí)數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue實(shí)現(xiàn)點(diǎn)擊按鈕“查看詳情”彈窗展示詳情列表操作
這篇文章主要介紹了vue實(shí)現(xiàn)點(diǎn)擊按鈕“查看詳情”彈窗展示詳情列表操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09vue項(xiàng)目中swiper輪播active圖片實(shí)現(xiàn)居中并放大
這篇文章主要介紹了vue項(xiàng)目中swiper輪播active圖片實(shí)現(xiàn)居中并放大方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Vue中搭配Bootstrap實(shí)現(xiàn)Vue的列表增刪功能
日常開發(fā)中,我們可以用?“拿來(lái)主義”?借助Bootstarp現(xiàn)成的一些樣式,快速生成我們想要的頁(yè)面布局,避免書寫大量的HTML和CSS代碼,省下了許多不必要的時(shí)間,可以直接搭配vue使用2022-11-11Vue3實(shí)現(xiàn)表單輸入的雙向綁定的示例代碼
Vue.js 是一個(gè)漸進(jìn)式的JavaScript框架,廣泛用于構(gòu)建交互式用戶界面,在 Vue 中,雙向綁定是一項(xiàng)非常核心的概念,尤其是在處理表單輸入時(shí),它使得數(shù)據(jù)和用戶界面之間的互動(dòng)變得簡(jiǎn)單又高效,在本篇博客中,我們將深入探討如何在 Vue 3 中實(shí)現(xiàn)表單輸入的雙向綁定2025-01-01基于vue-cli3和element實(shí)現(xiàn)登陸頁(yè)面
這篇文章主要介紹了vue-cli3和element做一個(gè)簡(jiǎn)單的登陸頁(yè)面本文實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11