Vue中如何在表格tr与td间规范实现嵌套数组的循环渲染
错误根因
- 违反HTML表格嵌套规范:
<tr>的合法直接子元素仅支持<td>、<th>,浏览器会自动将<tr>内部嵌套的块级<div>移出表格结构,直接导致DOM错位、样式异常。 - 额外问题:Vue 2中
v-for优先级高于同元素绑定的v-if,会先遍历所有数据再做判断,存在不必要的性能消耗;模板中{{ p.name }}和接口返回的字段不匹配,实际post下对应字段为title。
规范实现方案
1. 优先简化数据存储逻辑
无需存储整个响应对象再在模板中判断posts键,接口请求后直接提取posts数组赋值给独立的响应式变量,减少模板冗余逻辑:
<script> import Vue from "vue" export default Vue.extend({ data() { return { // 初始化为空数组,避免遍历空值报错 posts: [] } }, mounted() { this.$axios.get("/posts").then(response => { // 直接提取posts字段赋值 this.posts = response.data.posts || [] }); }, }) </script>
2. 按HTML规范重构模板结构
移除<tr>和<td>之间的<div>,让<tr>直接遍历每一条post;同个post的多个作者可在同一个<td>内用行内元素循环拼接,避免破坏表格列数对齐:
<template> <table> <!-- 直接遍历posts数组,无需额外判断key --> <tr v-for="p in posts" :key="p.id"> <td>{{ p.id }}</td> <td>{{ p.title }}</td> <td> <!-- 作者循环放在td内部,用行内span拼接展示 --> <span v-for="(a, idx) in p.authors" :key="a.name"> {{ a.name }}<span v-if="idx < p.authors.length - 1">, </span> </span> </td> </tr> </table> </template>
兼容原数据结构的写法
如果不想调整接口赋值逻辑、必须保留存储整个响应对象的写法,不要把v-if和v-for绑定在同一个元素上,可用<template>包裹做条件判断:
<template> <table> <template v-if="postList"> <tr v-for="p in postList.posts" :key="p.id"> <td>{{ p.id }}</td> <td>{{ p.title }}</td> <td> <span v-for="(a, idx) in p.authors" :key="a.name"> {{ a.name }}<span v-if="idx < p.authors.length - 1">, </span> </span> </td> </tr> </template> </table> </template>
内容的提问来源于stack exchange,提问作者warmwinter
相关产品推荐
相关产品推荐

