Vue-for无法渲染数据:Django+Vue CDN实时搜索表格问题
问题描述
在Django应用中通过Vue.js CDN实现实时搜索表格,POST请求能正常获取API响应,但使用v-for渲染数据时失败,页面仅显示表格表头,表格主体未在HTML中呈现。
用户提供的原始代码
dashboard HTML 文件
<div id="app" class="col-md-12 col-sm-12 py-3 px-4"> <!--Text search--> <div class="input-group"> <input @keyup="send_namerequest" v-model="search_query" type="text" class="form-control form-control-lg" placeholder="Search Bogus Client" aria-label="Recipient's username" aria-describedby="basic-addon2"> <div class="input-group-append"> <span class="input-group-text" id="basic-addon2"><i class="fas fa-search"></i></span> </div> <div id="eraser" class="input-group-append" @click="remove_search"> <span class="input-group-text" id="basic-addon2"><i class="fas fa-eraser"></i></span> </div> {%include "components/table.html"%} </div> </div>
table.html 文件
<table v-show="true" id="recent" class="table p-0 w-0 table-lg table-responsive-sm table-striped table-bordered"> <tbody> <tr v-for="client in resultsobj" :key="client.name"> <td><#client.name#></td> <td><#client.project.project_name#></td> <td><#client.reason.reason_name#></td> </tr> </tbody> </table>
app.js 文件
var dash = new Vue({ el: '#app', delimiters: ["<#", "#>"], data: { haveresults: false, search_query: '', resultsobj: [], }, computed :{}, ready: function(){}, methods: { remove_search : function(){ this.search_query = ""; this.haveresults = false; }, async send_namerequest(){ const res = await axios.post('/api/search/',{ client_name : this.search_query, }) .then(function(response){ this.haveresults = true; this.resultsobj = (response.data); console.log(resultsobj) }) } }, });
问题原因及修复方案
1. 核心问题:this指向错误
在send_namerequest方法的.then()回调中,使用普通函数会导致this上下文丢失,不再指向Vue实例,无法更新resultsobj和haveresults数据。
修复:改用箭头函数(或在外部保存this引用),确保回调内的this指向Vue实例。
2. 其他优化点
- 未处理请求失败场景:添加错误捕获,避免页面无响应。
ready钩子已废弃:Vue 2.x中应使用mounted替代。- 表格缺少表头:添加thead提升用户体验。
v-for的key不够可靠:建议用唯一ID替代名称,避免重复数据渲染异常。- 空查询无效请求:添加判断,减少不必要的API调用。
- 嵌套属性可能报错:添加可选链操作符,防止
project或reason为null时页面崩溃。
修复后的完整代码
app.js 修复版
var dash = new Vue({ el: '#app', delimiters: ["<#", "#>"], data: { haveresults: false, search_query: '', resultsobj: [], }, computed: {}, // 替换废弃的ready为mounted mounted: function(){}, methods: { remove_search: function(){ this.search_query = ""; this.haveresults = false; this.resultsobj = []; // 清空结果数组 }, async send_namerequest(){ // 过滤空查询 if(!this.search_query.trim()) { this.resultsobj = []; this.haveresults = false; return; } try { const response = await axios.post('/api/search/',{ client_name: this.search_query, }); this.haveresults = true; this.resultsobj = response.data; console.log(this.resultsobj); // 正确打印Vue实例数据 } catch (error) { console.error('搜索请求失败:', error); this.resultsobj = []; this.haveresults = false; } } }, });
table.html 优化版
<table v-show="haveresults || resultsobj.length > 0" id="recent" class="table p-0 w-0 table-lg table-responsive-sm table-striped table-bordered"> <thead> <tr> <th>客户名称</th> <th>项目名称</th> <th>原因</th> </tr> </thead> <tbody> <tr v-for="client in resultsobj" :key="client.id"> <!-- 用唯一ID作为key更可靠 --> <td><#client.name#></td> <td><#client.project?.project_name#></td> <!-- 可选链避免嵌套属性为空时报错 --> <td><#client.reason?.reason_name#></td> </tr> </tbody> </table>
内容的提问来源于stack exchange,提问作者se6
相关产品推荐
相关产品推荐

