今天在寫一個選擇器的時候出現一個問題 這個功能需求是:通過選擇器選擇不同的選項,點擊查詢按鈕發送請求,並將響應結果放到一個div中用v-if控制是否顯示。 看似簡單的一個功能,卻出現一個很搞笑的bug。在我選擇一個選項點擊查詢,本應該顯示結果的div沒有顯示出來,而在選擇一個其他選項,不需要點擊查詢 ...
今天在寫一個選擇器的時候出現一個問題
這個功能需求是:通過選擇器選擇不同的選項,點擊查詢按鈕發送請求,並將響應結果放到一個div中用v-if控制是否顯示。
看似簡單的一個功能,卻出現一個很搞笑的bug。在我選擇一個選項點擊查詢,本應該顯示結果的div沒有顯示出來,而在選擇一個其他選項,不需要點擊查詢按鈕,這個div就自動顯示出來了
附上我的代碼,這裡使用Vue3的組合式API
<template>
<span>班級:</span>
<el-select v-model="classId" class="m-2" placeholder="Select" size="large">
<el-option v-for="item in options" :key="item.id" :label="item.className" :value="item.id" />
</el-select>
<span> </span>
<el-button type="primary" round @click="search">查詢</el-button>
<br>
<div v-if="isDisplay">
<el-link v-for="item in checkNames" :key="item" @click="download(item)">
{{ item }}
</el-link>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { getServerUrl } from '../../config/url';
import axios from 'axios';
let isDisplay = ref(false);
function search() {
isDisplay.value = true;
//發送請求,獲得響應
axios.get(getServerUrl() + "/getCheckByClass/" + classId.value)
.then((response) => {
const respData = response.data;
console.log(respData.data);
checkNames = respData.data;
})
}
那麼該如何解決呢?
第一步:首先判斷你的變數有沒有使用Vue的響應式狀態,選項式API只需要把變數放到data()中並且return就好了
let isDisplay = ref(false);
或者let isDisplay = reactive(false);
第二步:在請求結束的.then
中改變isDisplay
的值。因為非同步操作和響應式數據更新的時機不同步,在查詢函數 search()
中將 isDisplay
設置為 true
,但由於涉及非同步操作(axios 請求),在數據還沒有返回之前,頁面就已經渲染完畢了。
問題看似解決了,但是依然會發現另外一個bug,只有第一次正常,到後面又出現剛剛的問題了。
這是什麼原因呢,這是由於Vue的響應性機製造成的。所以需要在查詢時先重置變數內容,下麵是完整的代碼。
function search() {
//重置變數內容
checkNames = [];
isDisplay.value = false;
//發送請求,獲得響應
axios.get(getServerUrl() + "/getCheckByClass/" + classId.value)
.then((response) => {
const respData = response.data;
console.log(respData.data);
checkNames = respData.data;
//響應後更改狀態
isDisplay.value = true;
})
}
問題到這裡就解決了