Vue 条件渲染问题
发布于 3 年前 作者 clubadmin 1334 次浏览 来自 问答
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

如图,在我的vue应用中有一个element-ui表格组件,某一行最后一列的内容是对应该行的一个按钮:

某一行的按钮在按下后,这一行的按钮应当变成另一个有着不同的事件的按钮:

为此我采用条件渲染来实现:

<el-table-column
                        header-align="center"
                        align="center"
                        fixed="right"
                        label=""
                        width="100px">
                        <template slot-scope="operationButtonScope">
                            <el-button
                                    v-if="flag"
                                    type="success"
                                    style="font-size: small"
                                    @click="handleSelect(operationButtonScope.$index)">
                                            选取</el-button>
                            <el-button
                                    v-else
                                    type="danger"
                                    style="font-size: small"
                                    @click="handleCancelSelect(operationButtonScope.$index)">
                                            退选</el-button>
                        </template>
</el-table-column>

在这个vue组件data()返回的对象中定义flag如下:

data() {
  return {
    flag: true,
    // ...
  }
}

methods定义如下:

methods: {
            handleSelect(index) {
                console.log('select index ' + index);
                this.flag = false;
            },
            handleCancelSelect(index) {
                console.log('cancel select index ' + index);
                this.flag = true;
            }
        }

至此,选择性地渲染按钮至少是实现出来了,而且切换非常流畅,点击按钮到按钮切换没有明显的时延:

当然这样会让所有行的按钮都跟着切换。于是我使用一个布尔数组存放每一行的flag:

data() {
  return {
    flagArray: [true, true],
    // ...
  }
}

相应地修改了条件渲染的表达式:

<el-table-column
                        header-align="center"
                        align="center"
                        fixed="right"
                        label=""
                        width="100px">
                        <template slot-scope="operationButtonScope">
                            <el-button
                                    v-if="flagArray[operationButtonScope.$index]"
                                    type="success"
                                    style="font-size: small"
                                    @click="handleSelect(operationButtonScope.$index)">
                                            选取</el-button>
                            <el-button
                                    v-else
                                    type="danger"
                                    style="font-size: small"
                                    @click="handleCancelSelect(operationButtonScope.$index)">
                                            退选</el-button>
                        </template>
</el-table-column>

methods的改动:

methods: {
            handleSelect(index) {
                this.flagArray[index] = false;
                console.log('flag ' + index + ' has turned to ' + this.flagArray[index]);
                console.log(this.flagArray);
            },
            handleCancelSelect(index) {
                this.flagArray[index] = true;
                console.log('flag ' + index + ' has turned to ' + this.flagArray[index]);
                console.log(this.flagArray);
            }
        }

现在问题来了:

当我点击第一行的按钮时,控制台输出了预想的内容,说明数组中的内容确实被改变了,但页面看起来却并没有任何响应,按钮没有被重新渲染,当我关闭控制台后,按钮才被正确地“替换”:

多次试验发现,无论点击按钮多少次,无论等待多久,按钮都不会被替换,除非我打开或关闭控制台。
vue的文档中指出频繁的切换应该使用v-show做条件渲染,但是改用v-show命令后问题没有任何改变。
请问问题出在哪?如果用我的写法无法规避这个问题,按钮的“替换”是否有更好的实现方法?
谢谢耐心看到这里的各位。

回到顶部