- A+
所属分类:Web前端
今天在写一个选择器的时候出现一个问题
这个功能需求是:通过选择器选择不同的选项,点击查询按钮发送请求,并将响应结果放到一个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; }) }
问题到这里就解决了