前言:
vue的computed虽然用了很久,但是还会因此遇到个坑。
问题:
自己基于el-table进行封装了一个组件-pro-table,和网上一些理念相似,让开发者少写一些代码。
发现问题:
我在最外层组件引用了pro-table,我的columns经最外层组件传递到pro-table中渲染,即:
<CProTable :api="ajaxTableData" :columns="columns"/>
但是我的columns有一个数据--list是需要动态变化的,即:
[
{
label: '**',
prop: '**',
width: '100px',
showOverflowTooltip: true,
search: {
type: 'tableSingleSelect',
prop: 'teacherIds',
props: {
placeholder: '请输入',
options: this.list, // 需要根据接口返回的数据展示
render: item => {
console.log(item);
return `${item.userName}/${item.mobile}`;
}
}
}
},
]
this.list在调用接口后展示相应的下拉框数据,
于是我便把定义columns的地方放到的computed里,computed会收集当前所有的依赖,依赖更新我的columns也更新,这一切看起来都是正常的逻辑,也确实,当我更新this.list的时候,computed里的方法会重新调用
问题出来了:
我在使用到this.list的地方没有更新到最新的数据
使用的地方:
<el-table-column
v-else
v-bind="col"
:key="col.prop"
:class="col.showOverflowTooltip ? 'change' : ''"
>
<template #header="{ column, $index }">
<slot :column="column" :$index="$index">
<div v-if="!col.search">
<span>{{ column.label }}</span>
</div>
<Transform
v-else
v-bind="col" // 传递到此处
@change="handleChangeVal(col, $event)"
:value="totalParam[col.search.prop]"
@search="handleSearch"
@clear="handleClearSingleValue"
>
<template v-slot:option>
<slot name="option"></slot>
</template>
<template #rightIcon="scope">
<slot :name="col.search.rightIcon" :data="scope.data"></slot>
</template>
</Transform>
</slot>
</template>
</el-table-column>
在我的Transform组件中就没有获取到最新的this.list数据。
排查问题:
首先确定当前最新的数据有没有被传递到pro-table中,我在代码把最新的columns放到代码中:
{{ JSON.stringify(columns) }}
发现已经是最新的数据了!
那问题就出在组件渲染上了,后面尝试this.$forceUpdate(),改变Transform的key值,重新定义一份columns,均无法实现数据的更新。
解决问题:
在el-table中的el-table-column我配置了key值,最后发现其实只要更改这个值便会重新渲染下面的内容,但是在columns中我唯一变化的就是this.list的值,最后只能根据其来json化来当key值了,即:
<el-table-column
v-else
v-bind="col"
:key="JSON.stringify(col) + 2"
:class="col.showOverflowTooltip ? 'change' : ''"
>
总结:当做问题的记录吧,后面再遇到类似的问题可以联想到解决方案