javascript 在 Vue.js 中等待 Ajax 响应数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51322046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait for Ajax response data in Vue.js
提问by Souvik Ghosh
I have a Vue component where I am trying to fetch some data from an API using axios.
我有一个 Vue 组件,我试图在其中使用 axios 从 API 获取一些数据。
<template>
<div>
This is Default child component
{{tools[0].name}}
</div>
</template>
<script>
import { CustomJS } from '../js/custom.js';
export default {
name: 'HomeContent',
props: {
tools: []
},
methods: {
fetchData() {
const customJs = new CustomJS();
return customJs.getTools();
}
},
created() {
this.tools = this.fetchData(); //preferably need to wait here wait for response
}
}
</script>
The getTools()function is in a different JS file outside the Vue component file which makes the API call using axios.get.
该getTools()函数位于 Vue 组件文件之外的不同 JS 文件中,该文件使用 axios.get 进行 API 调用。
getTools(id = 0){
this.apiTool += (id > 0) ? id : '';
axios.get(this.apiTool, {
})
.then(function (response) {
console.log(response.data);
return response.data;
})
.catch(function (error) {
console.log(error);
});
}
The problem is, {{tools}}is undefined since the getTools()takes some time to return the response data. How can wait for the response data and then return?
问题是,{{tools}}未定义,因为getTools()返回响应数据需要一些时间。如何等待响应数据然后返回?
回答by Surya Neupane
Try the code below: so the code will render only when its actually loaded
试试下面的代码:这样代码只会在它实际加载时呈现
<div v-if="tools">
This is Default child component
{{tools[0].name}}
</div>
回答by markcc
<template>
<div v-if="isGetTools">
This is Default child component
{{tools[0].name}}
</div>
</template>
<script>
import { CustomJS } from '../js/custom.js';
export default {
name: 'HomeContent',
props: {
tools: []
},
data: function () {
return {
isGetTools: false
}
},
methods: {
fetchData() {
const customJs = new CustomJS();
this.tools = customJs.getTools();
this.isGetTools = true;
}
},
created() {
this.fetchData(); //preferably need to wait here wait for response
}
}
</script>
Try to add v-if in your div. And update the isGetTools to true after getting the result from AXIOS
尝试在您的 div 中添加 v-if。并在从 AXIOS 获取结果后将 isGetTools 更新为 true
回答by roli roli
Usually for that, I am using a loader to show the user that a request is in progress
通常为此,我使用加载程序向用户显示请求正在进行中
<div v-if="loading">
<loader /> //a loader component
</div>
<div v-else>
// show the template since request finished
</div>
and the script
和脚本
export default {
data: () => ({
loading: false
}),
created() {
this.loading = true
axios.get('api') //your request
.then(response => console.log(response))
.finally(() => (this.loading = false)) //when the requests finish
}
}
If you don't like the way above, you can use beforeEnterso the route will load only when the request finishes:
如果你不喜欢上面的方式,你可以使用beforeEnter这样路由只会在请求完成时加载:
{
path: '/my-route',
component: YourComponent,
props: true,
beforeEnter (to, from, next) {
axios.get('api-request')
.then(response => {
to.params.data = response //we pass data through props to the component
next()
})
}
}
回答by Loi Nguyen Huynh
I don't know why this question pops up in my "timeline" and haven't got the accepted answer yet so I'll answer it anyway. The problem seemed to be with the understanding of the OP with asynchronous code in JS. Here's the fix (there're 3) to make it better:
我不知道为什么这个问题会出现在我的“时间线”中并且还没有得到公认的答案,所以我还是会回答。问题似乎在于对 OP 与 JS 中的异步代码的理解。这是修复(有 3 个)以使其更好:
<template>
<div v-if="tools.length">
{{tools[0].name}}
</div>
<div v-else> // I. Use v-if/v-else to conditionally show data, in Vue 3 there will be another feature called "suspense" borned to do those things: https://vueschool.io/articles/vuejs-tutorials/suspense-new-feature-in-vue-3/
This is Default child component
</div>
</template>
<script>
import { CustomJS } from '../js/custom.js';
export default {
name: 'HomeContent',
props: {
tools: []
},
methods: {
async fetchData() {
const customJs = new CustomJS();
this.tools = await customJs.getTools();
// II. The OP assigned a promise to this.tools, this.tools wasn't being assigned to any actual data at all, because:
// 1. getTools() didn't return any data
// 2. even if it returned data, it wasn't being promise-resolved (by await/then) before assigned to this.tools
}
},
created() {
this.fetchData();
}
}
</script>
async getTools(id = 0){
this.apiTool += (id > 0) ? id : '';
try {
const response = await axios.get(this.apiTool, {});
console.log(response.data);
return response.data;
// III. The OP didn't return any fetched data at all, it just called API then do nothing. All the returns were returned in the arrow functions, the actual function getTools didn't get any return
}
catch (err) {
console.log(err)
}
},
回答by Dionisis Karakasiliotis
You need to return a promise from your request
你需要从你的请求中返回一个承诺
<template>
<div>
This is Default child component
{{tools[0].name}}
</div>
</template>
<script>
import { CustomJS } from '../js/custom.js';
export default {
name: 'HomeContent',
props: {
tools: []
},
methods: {
fetchData() {
const customJs = new CustomJS();
return new Promise((resolve, reject) => {
customJs.getTools()
.then(res => resolve(res))
.catch(err => reject(err))
})
}
},
created() {
this.fetchData().then(res => {
this.tools = res);
} //preferably need to wait here wait for response
}
}
</script>
回答by Hardik
Give a try to retrieve data on mounted
尝试检索已安装的数据
<template>
// try adding this condition on div element.
<div v-if="tools.length">
This is Default child component
{{tools[0].name}}
</div>
</template>
<script>
import { CustomJS } from '../js/custom.js';
export default {
name: 'HomeContent',
props: {
tools: []
},
methods: {
fetchData() {
const customJs = new CustomJS();
return customJs.getTools();
}
},
mounted: function () {
this.tools = this.fetchData();
// or
// const customJs = new CustomJS();
// this.tools = customJs.getTools();
}
}
</script>
回答by Imre_G
What you want to do is to define your getTools function as a promise like this:
您想要做的是将您的 getTools 函数定义为这样的承诺:
getTools (id = 0) {
return new Promise((resolve, reject) => {
this.apiTool += (id > 0) ? id : '';
axios.get(this.apiTool, {
})
.then(function (response) {
console.log(response.data);
resolve(response.data);
})
.catch(function (error) {
console.log(error);
reject(error)
});
})
}
Then you can use it in your component code as:
然后你可以在你的组件代码中使用它:
<template>
<div>
This is Default child component
{{tools[0].name}}
</div>
</template>
<script>
import { CustomJS } from '../js/custom.js';
export default {
name: 'HomeContent',
props: {
tools: []
},
methods: {
fetchData() {
const customJs = new CustomJS();
customJs.getTools().then((result) => {
return result;
}
)
}
},
created() {
this.tools = this.fetchData(); //preferably need to wait here wait for response
}
}
</script>
Or using async/await:
或者使用异步/等待:
<template>
<div>
This is Default child component
{{tools[0].name}}
</div>
</template>
<script>
import { CustomJS } from '../js/custom.js';
export default {
name: 'HomeContent',
props: {
tools: []
},
methods: {
async fetchData() {
const customJs = new CustomJS();
return await customJs.getTools()
}
},
created() {
this.tools = this.fetchData(); //preferably need to wait here wait for response
}
}
</script>

