vue使用computed不更新孙子组件问题

244 阅读2分钟

前言:

        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' : ''"
        >

总结:当做问题的记录吧,后面再遇到类似的问题可以联想到解决方案