Skip to content

Instantly share code, notes, and snippets.

@MrZhouZh
Created August 21, 2023 11:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MrZhouZh/08a460d1504811c4ab2b4e5b478b2c13 to your computer and use it in GitHub Desktop.
Save MrZhouZh/08a460d1504811c4ab2b4e5b478b2c13 to your computer and use it in GitHub Desktop.
Practice of composition api with Vue3
// api/index.ts
export type SubmitApiResult = {
text: string
status: 'ok'
}
export function submitApi(text: string) {
return new Promise<SubmitApiResult>((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve({
text,
status: 'ok'
})
} else {
reject(new Error('O..ops! something wrong.'))
}
}, 1500)
})
}
<script setup lang="ts">
// Vue SFC Playground: https://play.vuejs.org/#eNqdV8tu4zYU/RWOFmMFcKUMgtm4itq0TdEp2k6QBOgiyoKRKFsJRap8OAk8/vdePvSM7ACjjSXe9+G5l/QuuGiaaKtJsAoSmYuqUUgSpRtEMVufZ4GSWZBmrKobLhTaIUFKtEel4DVagNmiE/3K68avR7H5MF5BnLGcM6lQLdfo3JgnUomKrdNw8QehlKN/uaDFh8VJxpLYZQDx4EORuqFYEfhCKNl8Snc762S/T2L4sqsVa7RC2x9qXhAK2YLcpmsMBIrdm83MvCdx5zNYQmWQWFmto0fJGZS/M8pZkIN2RYn42qgKEs+CFbISI8OQ7/Ofdk0JTZbter4h+dPM+qN8MWtZcCWIJGJLsqCTKSzWRDnx5c0/5AXeOyHUoyloHxFeE8mpNjk6tV80KyDtgZ7N9ovdHcD7Vl6+KMJkW5RJ1GjurX4WwG4ZoA6V3qd7Fp1Zu4ztAUUDF5f4gRIZa0kutOLX5D9NpIqUBFQ9O9RrQ4A914fYM0esjFmri6b6XbPkN6zwEl1hgWuJABDCCokwe727T4FXYRRFjZWtvM4JOk/RFbirJLHGllUVU0SUOAe3faa+3rZYynEBgP20Qg+cU4LBzCxzdqPznEgJgrAAhysT3obZ8qoAOPqUe9+wTZqqd7K/A1wSHyxdzlWc3hvn5MWCVWqWm4zRGPBjQUJXQ8lWs949Z7gDAgp8i07GTkbLM4WlHkDX8LsWSCiwxFSSZQ8h7PR5Gw19+9brrpyqYVfvSbiIf3XugCuhN4CxMVLVByocccRumk/WPOMA0RZTTcCgbZFWSWnBAMKBn15qnkhtCAuh1Sfu26cv/+PH/sMYTBwNwoFwLNtPg5YVg05/DcNpVe9UZ4Ge922ZPEjibuxiaWAGQoLa/ARoQx2fAHbmZMGP80Oglw6ayjt23DON49IctY9bSm5TANZm7YcADAY/DW7T0XC4hclwrL180LAgJYawPQ0tgr4rxpmNGoEWnrJjBx1zu3iA6jtpDz+GW02LCWnf0Hbs9DhpBt4mJDlIEFp0pABK4KaKK1aQF8cAj6vdxRv9UFcKOrTbQx9cwcBaIXc3cCtSYaVhni/4E5wGNuR0h2TrLRyan7Q+fXaMPHe4TeKnoWk/TrcwnQR5JLmaAgK3oduqJlyrebCqEoV/Y7WJBGYFr0EnRafR5y6HcSfaUOGMqIXA03f6jLGYSqczYY+IGaKzGZgaQ4PIpRBchIuvUcQb+QFJXhO1McR+Fhx6d3EydTqgwRJ9+nx62pIBft0oaK9933uZhGaPY9SJx8dbpxnFRy8dw0vFuIOPe+iH1tDDhC/LnnIDb0O+d1deGEcR5etwYWKZ660tzo2EO396te7uoQ/GhYRdHLD0RuCo5qwbwiVR+WZg2c6pzgDo5lrM3LrfEN9m1HWSOY6MAvC3ax6j100Cpin188rE7fMLFxhjYMuh02+IhdlyOPwHzJpE6Y47T6ojfwlgxhfVFuUUSwncyjn1V3/3JJuz9MuihqYCJOx2M8JgR3fmo4fR/Z04Gxo2gsBfiqoEpy478Ote4D5sKzCoGjvQHBo+aKUAypXfXJvUIFQWoJ9zWuVPIGjhBtfuJYmddVtaDLWN/7JAh+3/B85IeEY=
import { ref } from 'vue';
// import { useAutoRequest } from './composables/useAutoRequest.ts'
import { useAutoLoading } from './composables/useAutoLoading.ts'
import { SubmitApiResult, submitApi } from './api/index.ts'
// const [loading, submit] = useAutoRequest(submitApi)
const [commonLoading, fetch] = useAutoLoading()
const result = ref<SubmitApiResult>()
function onSubmit() {
result.value = null
fetch(submitApi('aaa')).then(res => {
console.log({ res })
result.value = res
})
}
</script>
<template>
<div class="col">
<h3>I'm test component {{ commonLoading }}</h3>
<pre v-if="result">result: {{ result }}</pre>
<button :loading="commonLoading" @click="onSubmit">Submit</button>
</div>
</template>
// composables/useAutoLoading.ts
import type { Ref } from "vue";
import { ref } from "vue";
type AutoLoadingResult = [
Ref<boolean>,
<T>(requestPromise: Promise<T>) => Promise<T>
]
export function useAutoLoading(defaultLoading = false): AutoLoadingResult {
const ld = ref(defaultLoading)
function run<T>(requestPromise: Promise<T>): Promise<T> {
ld.value = true
return requestPromise.finally(() => {
ld.value = false
})
}
return [ld, run]
}
// composables/useAutoRequest.ts
import type { Ref } from 'vue'
import { ref } from 'vue'
type ApiFun<Data, Params extends any[]> = (...params: Params) => Promise<Data>
interface AutoRequestOptions {
loading?: boolean
onSuccess?: (data: any) => void
}
type AutoRequestResult<Data, Params extends any[]> = [Ref<boolean>, ApiFun<Data, Params>]
export function useAutoRequest<Data, Params extends any[]>(
fn: ApiFun<Data, Params>,
options?: AutoRequestOptions
): AutoRequestResult<Data, Params>{
const { loading = false, onSuccess } = options || { loading: false }
const requestLoading = ref(loading)
const run: ApiFun<Data, Params> = (...params) => {
requestLoading.value = true
return fn(...params)
.then(res => {
onSuccess && onSuccess(res)
return res
})
.finally(() => {
requestLoading.value = false
})
}
return [requestLoading, run]
}
@MrZhouZh
Copy link
Author

Vue SFC Playground: https://play.vuejs.org/#eNqdV8tu4zYU/RWOFmMFcKUMgtm4itq0TdEp2k6QBOgiyoKRKFsJRap8OAk8/vdePvSM7ACjjSXe9+G5l/QuuGiaaKtJsAoSmYuqUUgSpRtEMVufZ4GSWZBmrKobLhTaIUFKtEel4DVagNmiE/3K68avR7H5MF5BnLGcM6lQLdfo3JgnUomKrdNw8QehlKN/uaDFh8VJxpLYZQDx4EORuqFYEfhCKNl8Snc762S/T2L4sqsVa7RC2x9qXhAK2YLcpmsMBIrdm83MvCdx5zNYQmWQWFmto0fJGZS/M8pZkIN2RYn42qgKEs+CFbISI8OQ7/Ofdk0JTZbter4h+dPM+qN8MWtZcCWIJGJLsqCTKSzWRDnx5c0/5AXeOyHUoyloHxFeE8mpNjk6tV80KyDtgZ7N9ovdHcD7Vl6+KMJkW5RJ1GjurX4WwG4ZoA6V3qd7Fp1Zu4ztAUUDF5f4gRIZa0kutOLX5D9NpIqUBFQ9O9RrQ4A914fYM0esjFmri6b6XbPkN6zwEl1hgWuJABDCCokwe727T4FXYRRFjZWtvM4JOk/RFbirJLHGllUVU0SUOAe3faa+3rZYynEBgP20Qg+cU4LBzCxzdqPznEgJgrAAhysT3obZ8qoAOPqUe9+wTZqqd7K/A1wSHyxdzlWc3hvn5MWCVWqWm4zRGPBjQUJXQ8lWs949Z7gDAgp8i07GTkbLM4WlHkDX8LsWSCiwxFSSZQ8h7PR5Gw19+9brrpyqYVfvSbiIf3XugCuhN4CxMVLVByocccRumk/WPOMA0RZTTcCgbZFWSWnBAMKBn15qnkhtCAuh1Sfu26cv/+PH/sMYTBwNwoFwLNtPg5YVg05/DcNpVe9UZ4Ge922ZPEjibuxiaWAGQoLa/ARoQx2fAHbmZMGP80Oglw6ayjt23DON49IctY9bSm5TANZm7YcADAY/DW7T0XC4hclwrL180LAgJYawPQ0tgr4rxpmNGoEWnrJjBx1zu3iA6jtpDz+GW02LCWnf0Hbs9DhpBt4mJDlIEFp0pABK4KaKK1aQF8cAj6vdxRv9UFcKOrTbQx9cwcBaIXc3cCtSYaVhni/4E5wGNuR0h2TrLRyan7Q+fXaMPHe4TeKnoWk/TrcwnQR5JLmaAgK3oduqJlyrebCqEoV/Y7WJBGYFr0EnRafR5y6HcSfaUOGMqIXA03f6jLGYSqczYY+IGaKzGZgaQ4PIpRBchIuvUcQb+QFJXhO1McR+Fhx6d3EydTqgwRJ9+nx62pIBft0oaK9933uZhGaPY9SJx8dbpxnFRy8dw0vFuIOPe+iH1tDDhC/LnnIDb0O+d1deGEcR5etwYWKZ660tzo2EO396te7uoQ/GhYRdHLD0RuCo5qwbwiVR+WZg2c6pzgDo5lrM3LrfEN9m1HWSOY6MAvC3ax6j100Cpin188rE7fMLFxhjYMuh02+IhdlyOPwHzJpE6Y47T6ojfwlgxhfVFuUUSwncyjn1V3/3JJuz9MuihqYCJOx2M8JgR3fmo4fR/Z04Gxo2gsBfiqoEpy478Ote4D5sKzCoGjvQHBo+aKUAypXfXJvUIFQWoJ9zWuVPIGjhBtfuJYmddVtaDLWN/7JAh+3/B85IeEY=

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment