微信公众号
扫描关注微信公众号
博客大厅

如何在自定义 Hook 中处理异步逻辑?

原创 来源:博客站 阅读 0 03月23日 07:52 听全文

在 Vue 3 中,自定义 Hook 可以处理异步逻辑,例如从 API 获取数据、处理异步操作等。处理异步逻辑时,通常需要使用 async/awaitPromise。以下是如何在自定义 Hook 中处理异步逻辑的详细步骤和示例:

1. 创建处理异步逻辑的自定义 Hook

在自定义 Hook 中,你可以使用 async/await 来处理异步操作。以下是一个从 API 获取数据的自定义 Hook 示例。

// useFetch.js
import { ref } from 'vue';

export function useFetch(url) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(false);

  async function fetchData() {
    loading.value = true;
    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      data.value = await response.json();
    } catch (err) {
      error.value = err;
    } finally {
      loading.value = false;
    }
  }

  fetchData();

  return { data, error, loading, fetchData };
}

2. 在组件中使用处理异步逻辑的自定义 Hook

在组件中,你可以像使用普通函数一样使用自定义 Hook。自定义 Hook 返回的响应式数据和方法可以直接在模板中使用。

<template>
  <div>
    <p v-if="loading">Loading...</p>
    <p v-else-if="error">Error: {{ error.message }}</p>
    <div v-else>
      <p>Data: {{ data }}</p>
      <button @click="fetchData">Refresh</button>
    </div>
  </div>
</template>

<script>
import { useFetch } from './useFetch';

export default {
  setup() {
    const { data, error, loading, fetchData } = useFetch('https://api.example.com/data');

    return {
      data,
      error,
      loading,
      fetchData
    };
  }
};
</script>

3. <script setup> 语法中使用处理异步逻辑的自定义 Hook

<script setup> 语法中,使用处理异步逻辑的自定义 Hook 也非常简洁。

<template>
  <div>
    <p v-if="loading">Loading...</p>
    <p v-else-if="error">Error: {{ error.message }}</p>
    <div v-else>
      <p>Data: {{ data }}</p>
      <button @click="fetchData">Refresh</button>
    </div>
  </div>
</template>

<script setup>
import { useFetch } from './useFetch';

const { data, error, loading, fetchData } = useFetch('https://api.example.com/data');
</script>

4. 处理依赖变化的异步逻辑

如果异步逻辑依赖于某些响应式数据的变化,你可以使用 watchwatchEffect 来监听这些变化,并在变化时重新执行异步逻辑。

// useFetchDependent.js
import { ref, watch } from 'vue';

export function useFetchDependent(url, dependency) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(false);

  async function fetchData() {
    loading.value = true;
    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      data.value = await response.json();
    } catch (err) {
      error.value = err;
    } finally {
      loading.value = false;
    }
  }

  watch(dependency, fetchData, { immediate: true });

  return { data, error, loading, fetchData };
}

5. 在组件中使用依赖变化的异步逻辑自定义 Hook

在组件中,你可以传入依赖的响应式数据来使用自定义 Hook。

<template>
  <div>
    <input v-model="query" />
    <p v-if="loading">Loading...</p>
    <p v-else-if="error">Error: {{ error.message }}</p>
    <div v-else>
      <p>Data: {{ data }}</p>
      <button @click="fetchData">Refresh</button>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue';
import { useFetchDependent } from './useFetchDependent';

export default {
  setup() {
    const query = ref('initial-query');
    const { data, error, loading, fetchData } = useFetchDependent(`https://api.example.com/data?query=${query.value}`, query);

    return {
      query,
      data,
      error,
      loading,
      fetchData
    };
  }
};
</script>

6. <script setup> 语法中使用依赖变化的异步逻辑自定义 Hook

<script setup> 语法中,使用依赖变化的异步逻辑自定义 Hook 也非常简洁。

<template>
  <div>
    <input v-model="query" />
    <p v-if="loading">Loading...</p>
    <p v-else-if="error">Error: {{ error.message }}</p>
    <div v-else>
      <p>Data: {{ data }}</p>
      <button @click="fetchData">Refresh</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { useFetchDependent } from './useFetchDependent';

const query = ref('initial-query');
const { data, error, loading, fetchData } = useFetchDependent(`https://api.example.com/data?query=${query.value}`, query);
</script>

7. 处理异步操作的清理

如果异步操作需要清理(如取消请求、清除定时器等),可以在自定义 Hook 中使用 onInvalidate 函数。

// useFetchWithCleanup.js
import { ref, watchEffect } from 'vue';

export function useFetchWithCleanup(url) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(false);

  watchEffect((onInvalidate) => {
    let isCancelled = false;

    async function fetchData() {
      loading.value = true;
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        if (!isCancelled) {
          data.value = await response.json();
        }
      } catch (err) {
        if (!isCancelled) {
          error.value = err;
        }
      } finally {
        if (!isCancelled) {
          loading.value = false;
        }
      }
    }

    fetchData();

    onInvalidate(() => {
      isCancelled = true;
    });
  });

  return { data, error, loading };
}

8. 在组件中使用带清理的异步逻辑自定义 Hook

在组件中,你可以使用带清理的异步逻辑自定义 Hook。

<template>
  <div>
    <p v-if="loading">Loading...</p>
    <p v-else-if="error">Error: {{ error.message }}</p>
    <div v-else>
      <p>Data: {{ data }}</p>
    </div>
  </div>
</template>

<script>
import { useFetchWithCleanup } from './useFetchWithCleanup';

export default {
  setup() {
    const { data, error, loading } = useFetchWithCleanup('https://api.example.com/data');

    return {
      data,
      error,
      loading
    };
  }
};
</script>

总结

  • 自定义 Hook 可以处理异步逻辑,例如从 API 获取数据、处理异步操作等。
  • 使用 async/awaitPromise 来处理异步操作。
  • 如果异步逻辑依赖于某些响应式数据的变化,可以使用 watchwatchEffect 来监听这些变化,并在变化时重新执行异步逻辑。
  • 使用 onInvalidate 函数来清理异步操作的副作用(如取消请求、清除定时器等)。
  • 在组件中,你可以像使用普通函数一样使用自定义 Hook,返回的响应式数据和方法可以直接在模板中使用。
  • <script setup> 语法中,使用自定义 Hook 更加简洁。
学在每日,进无止境!更多精彩内容请关注微信公众号。
原文出处: 内容由AI生成仅供参考,请勿使用于商业用途。如若转载请注明原文及出处。
出处地址:http://www.07sucai.com/tech/871.html
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。
>