【发布时间】:2022-01-13 21:01:12
【问题描述】:
这是我的第一个 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>
Token 现在是响应式的,我将 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>
在控制台中我有“false”,然后是“true”,但条件加载不起作用
【问题讨论】:
-
究竟什么不起作用?什么是记录数据?有错误吗?
-
我猜
loader默认值设置为false。似乎tokens.value.length是undefined,因此该语句将返回false。所以一开始不显示。您应该默认将其设置为true,并在响应到来时更改它。