我正在從 API 獲取資料,我用它來填充組件中的表單。我只需要在初始填充資料后觸發觀察者。像異步方式。但是觀察者會立即被觸發。只有在初始填充資料后更改任何值時,我才需要禁用更新按鈕。
<template>
<div id="app">
<input type="text" v-model="user.userId" /> <br />
<br />
<input type="text" v-model="user.title" /> <br />
<br />
<button :disabled="isDisabled">Update</button>
</div>
</template>
<script>
export default {
name: "App",
watch: {
user: {
handler(oldVal, newVal) {
if (oldVal != newVal) {
this.isLoaded = false;
}
},
deep: true,
},
},
computed: {
isDisabled() {
return this.isLoaded;
},
},
async created() {
await fetch("https://jsonplaceholder.typicode.com/todos/1")
.then((response) => response.json())
.then((json) => {
this.user = json;
this.isLoaded = true;
});
},
data() {
return {
user: {
userId: 0,
id: 0,
title: "",
completed: false,
},
isLoaded: true,
};
},
};
</script>
我已經提到了Vue、await for Watch和手表是異步的嗎?和Vue.js How to watcher before mount() ,無法從 watch 獲取資料,但我無法跟進。
這是一個預覽:https : //codesandbox.io/embed/great-euler-skd3v?fontsize=14&hidenavigation=1&theme=dark
uj5u.com熱心網友回復:
最簡單的問題答案:
Q:如何在 VueJS 中從 API 初始加載后才觀看?
答:在您的
watch(例如isLoaded)中添加標志。
您的代碼也有一些問題:
async/await在created什么都不做,isDisabled不需要,因為僅基于 1 個值data。您可以改為使用此值 (isLoading)。- 如果 api 呼叫失敗,
isLoading標志不會改變,更好的方法是將其移動到finally。
您的問題的解決方案(代碼和框):
<template>
<div id="app">
<div v-if="!isFetching">
<input type="text" v-model="user.userId" /> <br />
<br />
<input type="text" v-model="user.title" /> <br />
<br />
<button :disabled="!isLoaded">Update</button>
</div>
<div v-else>Loading...</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
user: {
userId: 0,
id: 0,
title: "",
completed: false,
},
isFetching: false,
isLoaded: false
};
},
watch: {
user: {
handler(oldVal, newVal) {
if (!this.isFetching) {
// this comparision doesn't work (cause oldVal/newVal is an object)
if (oldVal != newVal) {
this.isLoaded = false;
}
}
},
deep: true
},
},
created() {
this.isFetching = true;
fetch("https://jsonplaceholder.typicode.com/todos/1")
.then((response) => response.json())
.then((json) => {
this.user = json;
this.isLoaded = true;
})
.finally(() => this.isFetching = false)
},
};
</script>
uj5u.com熱心網友回復:
這需要根據一些條件來確定。
isLoaded已經起到了確定初始加載狀態的作用,但是名字很混亂,因為它確定了資料沒有被加載。
有可能:
watch: {
user: {
if (this.isLoading && oldVal != newVal) {
this.isLoading = false;
}
...
觀察者不需要并且在不需要時可以不被觀察deep:
async created() {
let unwatchUser = this.$watch('user', (oldVal, newVal) => {
if (this.isLoading && oldVal != newVal) {
this.isLoading = false;
unwatchUser();
}
})
...
指定資料尚未加載的常用方法是將其設定為null,即沒有值。這不需要isLoading標志或觀察者。如果null由于參考的物件屬性而不受歡迎,則可以通過可選鏈接和條件渲染來克服:
<div v-if="user">
<input type="text" v-model="user.userId" />
...
<div v-else class="spinner"/>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/353955.html
標籤:javascript Vue.js
