显示Vue 3异步axios请求的加载程序



这是我的第一个Vue 3项目。。。

我正在尝试在Axios异步请求期间显示加载程序。这是我的组件

<script setup>
import { defineProps, onMounted, ref, computed } from 'vue';
import axios from 'axios'
const props = defineProps({
publicKey: String
})
const tokens = ref([]);
const loader = computed(() => {
return tokens.value.length > 0
})
onMounted(async () => {
console.log(loader);
const url = `https://example.com/${props.publicKey}/nfts/metadata`
const res = await axios.get(url);
tokens.value = res.data;
console.log(loader);
});
</script>
<template>
<div v-if="loader">
<div class='anim-circle'></div>
</div>
<div v-else>
{{tokens}}
</div>
</template>

它不起作用,我尝试了几种方法都没有成功。。。

我用这种方式编辑脚本

<script setup>
import {
defineProps,
onMounted,
reactive,
computed
} from 'vue';
import axios from 'axios'
const props = defineProps({
publicKey: String
})
let tokens = reactive([]);
const loaded = computed(() => {return !(tokens?.length > 0)})
onMounted(async () => {
const url = `https://api.example.io/solana/account/${props.publicKey}/nfts/metadata`
const res = await axios.get(url);
tokens.push(...res.data);
});
</script>
<template>
<div v-if="loaded.value">
<div class="row">
<div v-for="token in tokens.nfts" v-bind:key="token.id" class="col-lg-4 col-md-6 col-12 mb-4 pb-2">
<router-link :to="{ name: 'Token', params: { id: token.id }}">
<div class="nft-collection nft-col-primary p-3 bg-white rounded-md">
<img :src="token.image" class="img-fluid rounded-md shadow mb-2">
<div class="content mt-3 p-2 rounded-md" style="background-color: white">
<a class="title text-light h3" href="">
{{token.name}}
{{token.description}}
</a>
<ul class="pt-3 d-flex justify-content-between align-items-center list-unstyled mb-0">
<li>
<!-- <span v-for="skill in buddha.metadata" v-bind:key="skill" class="badge bg-soft">{{skill}}</span> -->
</li>
</ul>
</div>
</div>
</router-link>
</div>
</div>
</div>
<div v-else>
<div class="row loading">
<div class='anim-circle'></div>
</div>
</div>
</template>

代币现在是被动的,我把axios调用的结果推到数组中。我改为";加载的";如果已加载则显示我的结果,如果未加载则显示加载程序。

控制台中的错误是

Uncaught (in promise) TypeError: Found non-callable @@iterator
at eval (TokenList.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[1]:24)

另一次尝试性重构

<script setup>
import {
defineProps,
onMounted,
ref,
computed
} from 'vue';
import axios from 'axios'
const props = defineProps({
publicKey: String
})
const tokens = ref([])
const loadingState = ref(null)
const showToken = computed(() => loadingState.value === 'success' )
// Fetch Data Feature
const fetchAllTokens = () => {
console.log(showToken.value);
loadingState.value = 'loading'
const url = `https://api.unlocktech.io/solana/account/${props.publicKey}/nfts/metadata`
return axios.get(url)
.then(response => {
loadingState.value = 'success'
tokens.value = response.data.nfts
console.log(tokens.value);
console.log(showToken.value);
})
}
onMounted(
fetchAllTokens()
);
</script>
<template>
<div v-if="showToken.value">
<div class="row">
<div v-for="token in tokens.value" v-bind:key="token.id" class="col-lg-4 col-md-6 col-12 mb-4 pb-2">
<router-link :to="{ name: 'Token', params: { id: token.id }}">
<div class="nft-collection nft-col-primary p-3 bg-white rounded-md">
<img :src="token.image" class="img-fluid rounded-md shadow mb-2">
<div class="content mt-3 p-2 rounded-md" style="background-color: white">
<a class="title text-light h3" href="">
{{token.name}}
{{token.description}}
</a>
<ul class="pt-3 d-flex justify-content-between align-items-center list-unstyled mb-0">
<li>
<!-- <span v-for="skill in buddha.metadata" v-bind:key="skill" class="badge bg-soft">{{skill}}</span> -->
</li>
</ul>
</div>
</div>
</router-link>
</div>
</div>
</div>
<div v-else>
<div class="row loading">
<div class='anim-circle'></div>
</div>
</div>
</template>

在控制台中;CCD_ 1";然后";CCD_ 2";但是条件加载不起作用

我认为对象(数组(应该是reactive而不是ref

https://v3.vuejs.org/api/basic-reactivity.html

这就是新代码:

<script setup>
import { defineProps, onMounted, ref, computed } from 'vue';
import axios from 'axios'
const props = defineProps({
publicKey: String
})
const tokens = reactive([]);
const loader = computed(() => {
return tokens?.length > 0
})
onMounted(async () => {
console.log(loader);
const url = `https://example.com/${props.publicKey}/nfts/metadata`
const res = await axios.get(url);
tokens = res.data;
console.log(loader);
});
</script>
<template>
<div v-if="loader">
<div class='anim-circle'></div>
</div>
<div v-else>
{{tokens}}
</div>
</template>

我认为;装载机";应该是

const loader = computed(() => {return !(tokens?.length > 0)})

因为您想要显示加载程序,如果令牌数组中没有项。另外,tokensconst,因此不能重新分配。您应该使用tokens.push(...res.data)

此外,正如@ImagiNiha所示,您应该使用reactive而不是false0。

最新更新