1. 程式人生 > >解決Vue循環中子組件不實時更新的問題

解決Vue循環中子組件不實時更新的問題

獲取 effect https red 顯示 fault 沒有 art cli

問題描述

使用Element-UI中的table組件時會遇到一個常見的問題。當在el-table中調用子組件的時候會出現數據更新後,子組件沒有重新渲染的問題。
eg:資源列表中的健康度組件。
技術分享圖片
代碼如下:

    <el-table :data="sourceData" class="resource_list_data" v-loading="loading" size="mini" :default-sort="{prop: 'update_time', order: 'descending'}" @sort-change="handleSortChange">
            <el-table-column prop="name" label="資源名稱">
                <template slot-scope="scope">
                    <el-tooltip effect="dark" :openDelay="500" :content="`點擊進入${scope.row.name}管理頁面`" placement="top">
                        <a @click="manageClick(scope.row.id)"> {{scope.row.name}}</a>
                    </el-tooltip>
                </template>
            </el-table-column>
            <el-table-column prop="res_type_name" label="資源類別">
            </el-table-column>
            <el-table-column prop="ip" label="IP">
            </el-table-column>
            <el-table-column prop="probe_name" label="采集器" :formatter="probeFormatter">
            </el-table-column>
            <el-table-column prop="desc_" label="描述" :formatter="descriptionFormatter">
            </el-table-column>
            <el-table-column prop="health_degree" label="健康度">
                <template slot-scope="scope">
                    <HealthDegree :degree="scope.row.health_degree"></HealthDegree>
                </template>
            </el-table-column>
            <el-table-column prop="update_time" label="更新時間">
            </el-table-column>
            <el-table-column label="操作">
                <template slot-scope="scope">
                    <BlueButton title="管理" @click.native="manageClick(scope.row.id)" />
                    <RedButton title="刪除" @click.native="ruleDelete(scope.row)" />
                </template>
            </el-table-column>
        </el-table>

理論上當我更新數據的時候,sourceData的值已經發生了改變(而不是其中的某個字段發生了改變),子組件應該獲取的數據更新並重新渲染。實際上該頁面的健康度組件只會保留第一次界面初始化的渲染頁面。

解決方法

這是Element-UI的一個bug,解決方案是從el-table中增加一個row-key屬性,並為row-key設置一個能唯一標識的字段名。假如你的數據中能夠唯一標識的字段是id,那你就設置為id。這樣就解決了這種問題。
eg:代碼如下

    <el-table :data="sourceData" class="resource_list_data" row-key="id" v-loading="loading" size="mini" :default-sort="{prop: 'update_time', order: 'descending'}" @sort-change="handleSortChange">
            <el-table-column prop="name" label="資源名稱">
                <template slot-scope="scope">
                    <el-tooltip effect="dark" :openDelay="500" :content="`點擊進入${scope.row.name}管理頁面`" placement="top">
                        <a @click="manageClick(scope.row.id)"> {{scope.row.name}}</a>
                    </el-tooltip>
                </template>
            </el-table-column>
            <el-table-column prop="res_type_name" label="資源類別">
            </el-table-column>
            <el-table-column prop="ip" label="IP">
            </el-table-column>
            <el-table-column prop="probe_name" label="采集器" :formatter="probeFormatter">
            </el-table-column>
            <el-table-column prop="desc_" label="描述" :formatter="descriptionFormatter">
            </el-table-column>
            <el-table-column prop="health_degree" label="健康度">
                <template slot-scope="scope">
                    <HealthDegree :degree="scope.row.health_degree"></HealthDegree>
                </template>
            </el-table-column>
            <el-table-column prop="update_time" label="更新時間">
            </el-table-column>
            <el-table-column label="操作">
                <template slot-scope="scope">
                    <BlueButton title="管理" @click.native="manageClick(scope.row.id)" />
                    <RedButton title="刪除" @click.native="ruleDelete(scope.row)" />
                </template>
            </el-table-column>
        </el-table>

還有一個解決方法是給table增加一個隨機數的key

<el-table :key="Math.random()" ></el-table>

但是在chrome上會出現頁面卡死,內存占用過高的問題。不建議使用

參考鏈接:

vue數據更新了,視圖沒有更新
vue組件庫element-ui 的Table內容顯示不更新
element-ui中table-column中template下元素不更新

解決Vue循環中子組件不實時更新的問題