最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

維護(hù)loading加載狀態(tài)的幾個(gè)方法小結(jié)

 更新時(shí)間:2024年09月03日 08:34:47   作者:vilan_微瀾  
在項(xiàng)目開(kāi)發(fā)中,當(dāng)頁(yè)面請(qǐng)求接口時(shí),組件局部或者頁(yè)面全局顯示loading加載遮罩可謂是司空見(jiàn)慣了,下面來(lái)討論一下如何優(yōu)雅的使用loading狀態(tài),文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下

前言

在項(xiàng)目開(kāi)發(fā)中,當(dāng)頁(yè)面請(qǐng)求接口時(shí),組件局部或者頁(yè)面全局顯示loading加載遮罩可謂是司空見(jiàn)慣了,下面來(lái)討論一下如何優(yōu)雅的使用loading狀態(tài)。下文引用了比較常用的兩個(gè)組件Button按鈕和Table表格作為例子,談?wù)勅绾蝺?yōu)雅的維護(hù)loading加載狀態(tài)。

Butoon組件原始加載用法

<template>
  <div>
    <div>數(shù)據(jù):{{ list }}</div>
    <el-button type="primary" @click="asyncFetch" :loading="loading">異步獲取</el-button>
    <el-button type="primary" @click="syncFetch" :loading="loading">同步獲取</el-button>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { FetchApi } from '@/api'

const loading = ref(false)
const list = ref([])
// 異步調(diào)用
const asyncFetch = () => {
  loading.value = true
  FetchApi().then(res => {
    console.log(res)
    list.value = res
  }).finally(() => {
    loading.value = false
  })
}
// 同步調(diào)用
const syncFetch = async () => {
  loading.value = true
  try {
    const res = await FetchApi()
    console.log(res)
    list.value = res
  } catch (error) {
    console.log(error)
  }
  loading.value = false
}
</script>

由以上代碼可看出,在每次點(diǎn)擊按鈕提交時(shí),都需要在調(diào)用接口前開(kāi)啟加載狀態(tài),在接口調(diào)用結(jié)束時(shí),無(wú)論成功與否,都結(jié)束加載狀態(tài)。為了簡(jiǎn)化這一操作步驟,減少代碼冗余,我們可以封裝一個(gè)button組件,把loading狀態(tài)及相關(guān)邏輯提取這個(gè)組件當(dāng)中。

封裝Button組件

<template>
  <!-- 新版本vue中,透?jìng)骺墒÷詖-bind="$attrs" -->
  <el-button v-bind="$attrs" :loading="loading" :onClick="handleClick">
    <slot></slot>
  </el-button>
</template>

<script setup>
import { ref } from 'vue'

const { onClick } = defineProps(['onClick'])

const loading = ref(false)
// 重寫點(diǎn)擊方法
const handleClick = async () => {
  loading.value = true
  try {
    // 傳遞的onClick方法必須為同步的
    onClick && await onClick()
  } catch (error) {
    console.error(error)
  }
  loading.value = false
}

</script>

以上對(duì)button組件進(jìn)行二次封裝,把一些重復(fù)的業(yè)務(wù)邏輯放到該組件中,為了能夠知道異步方法什么時(shí)候執(zhí)行結(jié)束,將點(diǎn)擊方法通過(guò)prop參數(shù)的形式傳遞到子組件中,交給子組件在合適的時(shí)機(jī)執(zhí)行,學(xué)過(guò)react的話應(yīng)該對(duì)此操作比較熟悉。

組件加載用法

Page.vue

<template>
  <div>
    <div>數(shù)據(jù):{{ list }}</div>
    <ViButton type="primary" :onClick="syncFetch">同步獲取</ViButton>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { FetchApi } from '@/api'
import ViButton from '@/components/ViButton/ViButton.vue'

const list = ref([])
// 同步調(diào)用
const syncFetch = async () => {
  const res = await FetchApi()
  list.value = res
}
</script>

需要注意的是,我們需要把FetchApi()異步方法轉(zhuǎn)為同步,這是為了在Button組件中能夠方便地知道FetchApi方法的執(zhí)行結(jié)束時(shí)機(jī),否則在Button組件中將不能正確的隱藏loading狀態(tài)。

封裝表格組件

<template>
  <!-- 新版本vue中,透?jìng)骺墒÷詖-bind="$attrs" -->
  <el-table v-bind="$attrs" v-loading="loading">
    <slot></slot>
  </el-table>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const props = defineProps({
  // 獲取數(shù)據(jù)方法
  fetchData: {
    type: Function,
    default: () => {}
  },
  // 默認(rèn)是onMounted立即執(zhí)行fetchData
  immediateFetch: {
    type: Boolean,
    default: true
  }
})

const loading = ref(false)

const getList = async () => {
  loading.value = true
  try {
    await props.fetchData()
  } catch (error) {
    console.log(error)
  }
  loading.value = false
}

onMounted(() => {
  props.immediateFetch && getList()
})

// 暴露經(jīng)過(guò)loading處理的fetch方法,比如搜索時(shí)候需要在父組件手動(dòng)調(diào)用
defineExpose({ fetchData: getList })
</script>

組件加載用法

page.vue

<template>
  <div>
    <ViTable ref="ViTableRef" :data="list" :fetchData="syncFetch" :immediateFetch="false">
      <el-table-column prop="name" label="姓名"></el-table-column>
    </ViTable>
    <el-button @click="onSearch">查詢</el-button>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { FetchApi } from '@/api'
import ViTable from '@/components/ViTable/ViTable.vue'

const list = ref([])
const ViTableRef = ref(null)
// 同步調(diào)用
const syncFetch = async () => {
  console.log('syncFetch')
  const res = await FetchApi()
  list.value = res
  console.log(list.value)
}

// 搜索
const onSearch = () => {
  ViTableRef.value.fetchData()
}
</script>

以上需要注意的有兩點(diǎn):

  • 數(shù)據(jù)是否需要在表格掛載完成立即獲?。?/li>
  • 需要對(duì)外暴露經(jīng)過(guò)loading加工的fetch方法,目的是滿足需要手動(dòng)調(diào)用獲取數(shù)據(jù)的需求,比如點(diǎn)擊搜索;

以上方式當(dāng)需要手動(dòng)調(diào)用時(shí)似乎還是有些麻煩,下面我們改成useHook方式來(lái)試試~

封裝useLoading鉤子函數(shù)

useLoading.js

import { ref } from 'vue'

// 多個(gè)組件共享統(tǒng)一狀態(tài)
const loading = ref(false)

export const useLoading = (prop = {
  fetchData: () => {}
}) => {
  // 對(duì)外暴露loading給table組件或者button組件使用
  // 內(nèi)部只負(fù)責(zé)處理業(yè)務(wù)邏輯,不負(fù)責(zé)調(diào)用,這樣更加靈活
  return {
    loading,
    fetchData: async () => {
      loading.value = true
      try {
        await prop.fetchData()
      } catch (error) {
        console.log(error)
      }
      loading.value = false
    }
  }
}

ViTablePlus.vue

<template>
  <!-- 新版本vue中,透?jìng)骺墒÷詖-bind="$attrs" -->
  <el-table v-bind="$attrs" v-loading="loading">
    <slot></slot>
  </el-table>
</template>

<script setup>
import { useLoading } from '@/hooks/useLoading'

const { loading } = useLoading()
</script>

用法

Page.vue

<template>
  <div>
    <ViTablePlus :data="list" :fetchData="syncFetch" :immediateFetch="false">
      <el-table-column prop="name" label="姓名"></el-table-column>
    </ViTablePlus>
    <el-button @click="onSearch">查詢</el-button>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { FetchApi } from '@/api'
import ViTablePlus from '@/components/ViTablePlus/ViTablePlus.vue'
import { useLoading } from '@/hooks/useLoading'

// 手動(dòng)執(zhí)行經(jīng)過(guò)loading處理的fetchData方法
const { fetchData } = useLoading({
  fetchData: syncFetch
})

const list = ref([])
// 需要使用function定義方法,進(jìn)行變量提升,因?yàn)閡seLoading在syncFetch方法定義前執(zhí)行
async function syncFetch() {
  const res = await FetchApi()
  list.value = res
}

// 搜索
const onSearch = () => {
  // 經(jīng)過(guò)loading處理的fetchData方法
  fetchData()
}

onMounted(() => {
  // 經(jīng)過(guò)loading處理的fetchData方法
  fetchData()
})
</script>

總結(jié)

本文講了在二次封裝的ButtonTable組件內(nèi)部維護(hù)loading狀態(tài),為了能夠獲取到異步方法的調(diào)用完成時(shí)機(jī),我們把異步方法轉(zhuǎn)為同步方法后,通過(guò)prop的方式傳遞到子組件,委托子組件在恰當(dāng)?shù)臅r(shí)機(jī)執(zhí)行。但把loading狀態(tài)封裝到組件內(nèi)部還是不夠靈活,最后使用useLoading鉤子函數(shù)維護(hù)一個(gè)全局狀態(tài),提供靈活的跨組件狀態(tài)共享。

以上就是維護(hù)loading加載狀態(tài)的幾個(gè)方法小結(jié)的詳細(xì)內(nèi)容,更多關(guān)于維護(hù)loading加載狀態(tài)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 微信小程序?qū)崿F(xiàn)撥打電話功能的示例代碼

    微信小程序?qū)崿F(xiàn)撥打電話功能的示例代碼

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)撥打電話功能的示例代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • JavaScript閉包相關(guān)知識(shí)解析

    JavaScript閉包相關(guān)知識(shí)解析

    這篇文章主要介紹了JavaScript閉包相關(guān)知識(shí)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 關(guān)于網(wǎng)頁(yè)中的無(wú)縫滾動(dòng)的js代碼

    關(guān)于網(wǎng)頁(yè)中的無(wú)縫滾動(dòng)的js代碼

    隨便打開(kāi)一個(gè)網(wǎng)頁(yè),基本上都會(huì)看到無(wú)縫滾動(dòng)或者輪播圖,比如淘寶還有360官網(wǎng)的首頁(yè)。那么這些滾動(dòng)效果是怎么實(shí)現(xiàn)的呢?下面小編給大家分享關(guān)于網(wǎng)頁(yè)中的無(wú)縫滾動(dòng)的js代碼,感興趣的朋友一起看下吧
    2016-06-06
  • javascript基于牛頓迭代法實(shí)現(xiàn)求浮點(diǎn)數(shù)的平方根【遞歸原理】

    javascript基于牛頓迭代法實(shí)現(xiàn)求浮點(diǎn)數(shù)的平方根【遞歸原理】

    這篇文章主要介紹了javascript基于牛頓迭代法實(shí)現(xiàn)求浮點(diǎn)數(shù)的平方根,簡(jiǎn)單說(shuō)明了牛頓迭代法的原理,并結(jié)合實(shí)例分析了javascript基于遞歸的數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09
  • 往光標(biāo)所在位置插入值的js代碼

    往光標(biāo)所在位置插入值的js代碼

    往輸入域中插入字符串(光標(biāo)所在位置),在本文將為大家介紹下使用js是如何實(shí)現(xiàn)的,感興趣的朋友可以參考下
    2013-09-09
  • JavaScript原型和原型鏈詳解

    JavaScript原型和原型鏈詳解

    在面向?qū)ο蟮木幊陶Z(yǔ)言中,類和對(duì)象的關(guān)系是鑄模和鑄件的關(guān)系,對(duì)象總是從類創(chuàng)建而來(lái),比如Java中,必須先創(chuàng)建類再基于類實(shí)例化對(duì)象,這篇文章主要介紹了JavaScript原型和原型鏈的相關(guān)知識(shí),需要的朋友可以參考下
    2024-05-05
  • 如何用原生js寫一個(gè)彈窗消息提醒插件

    如何用原生js寫一個(gè)彈窗消息提醒插件

    這篇文章主要介紹了用原生js寫一個(gè)彈窗消息提醒插件,下面小編來(lái)和大家一起學(xué)習(xí)一下
    2019-05-05
  • JS閉包原理與應(yīng)用經(jīng)典示例

    JS閉包原理與應(yīng)用經(jīng)典示例

    這篇文章主要介紹了JS閉包原理與應(yīng)用,結(jié)合實(shí)例形式較為詳細(xì)的分析了javascript閉包的原理、應(yīng)用及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-12-12
  • 一文詳解如何處理JavaScript中的NaN

    一文詳解如何處理JavaScript中的NaN

    在?JavaScript?中,NaN(Not-a-Number)表示一個(gè)無(wú)效的數(shù)字值,通常,它出現(xiàn)在嘗試將無(wú)法轉(zhuǎn)換為數(shù)字的值與數(shù)字進(jìn)行運(yùn)算時(shí),本文主要來(lái)聊聊如何處理JavaScript中的NaN,感興趣的可以了解下
    2025-01-01
  • 淺談JavaScript中的分支結(jié)構(gòu)

    淺談JavaScript中的分支結(jié)構(gòu)

    下面小編就為大家?guī)?lái)一篇淺談JavaScript中的分支結(jié)構(gòu)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-07-07

最新評(píng)論

宝应县| 桑植县| 兰西县| 玛纳斯县| 库尔勒市| 淳化县| 淳安县| 固始县| 台中市| 昌邑市| 天门市| 额敏县| 宁乡县| 榆林市| 隆林| 无为县| 荣成市| 石阡县| 清远市| 塔城市| 曲麻莱县| 额尔古纳市| 江永县| 孟津县| 延吉市| 延寿县| 和平区| 都安| 布拖县| 封丘县| 积石山| 柏乡县| 金堂县| 孙吴县| 承德市| 平塘县| 清新县| 福建省| 革吉县| 溆浦县| 屏东县|