封装一个组件时,我使用到了v-for和v-if,它们在同一标签内,总是提示v-for循环出来的item在实例中没有被定义,查询资料后原因是因为v-for和v-if在同级使用时,v-if优先级比v-for高,所以拿不到v-for循环出来的item。
<el-table-column
align="center"
v-for="item in tableData"
v-if="item.show"
:key="item.prop"
:prop="item.prop"
:label="item.label"
:sortable="item.sortable ? 'custom' : false"
:width="item.width"
:formatter="item.formatter"
class="tooltip-column"
>
</el-table-column>
解决办法:
1.我们在外层包裹一个 <template> ,先去循环再去判断,这样v-if就可以正常使用了
<template v-for="item in columns">
<el-table-column
align="center"
v-if="item.show"
:key="item.prop"
:prop="item.prop"
:label="item.label"
:sortable="item.sortable ? 'custom' : false"
:width="item.width"
:formatter="item.formatter"
class="tooltip-column"
>
</el-table-column>
</template>
2.不使用template标签,我们可以在script中处理
使用计算属性computed解决,通过数组方法filter过滤数组,v-for直接循环计算属性后的结果,就不需要使用v-if了。而且computed是有缓存的,就是在它的依赖没有变化时,不会再执行对应计算属性的回调函数,就提高了性能。
// 计算属性:处理显示列
const tableColumns = computed(() => {
return props.columns.filter((item) =>
typeof item.show === "undefined" ? true : item.show
);
});
<el-table-column
align="center"
v-for="item in tableColumns"
:key="item.prop"
:prop="item.prop"
:label="item.label"
:sortable="item.sortable ? 'custom' : false"
:width="item.width"
:formatter="item.formatter"
class="tooltip-column"
>
</el-table-column>