需求:点击table表格中的“修改”之后,当前行变为可输入状态的行,点击“确定”后变为普通表格;
在这里插入图片描述
先贴上已经完美解决问题的代码
实现代码:

<section>
    <div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px">
        <h4>接入点信息</h4>
        <el-button type="primary" @click="addBtn">新 增</el-button>
    </div>
    <el-form ref="form1" :model="formData" label-width="0px" :inline-message="true">
        <el-table :data="formData.access_param" :border="true">
            <el-table-column label="名称" align="center" prop="name">
                <template slot="header">
                    <span>
                        <span class="fred">*</span>
                        名称
                    </span>
                </template>
                <template slot-scope="scope">
                    <el-form-item v-if="scope.row.editable" :prop="'access_param.' + scope.$index + '.name'" :rules="tableFromRules.name">
                        <el-input v-model="scope.row.name"></el-input>
                    </el-form-item>
                    <span v-else>{{ scope.row.name }}</span>
                </template>
            </el-table-column>
            <el-table-column label="拓扑角色" align="center" prop="topo_type">
                <template slot="header">
                    <span>
                        <span class="fred">*</span>
                        拓扑角色
                    </span>
                </template>
                <template slot-scope="scope">
                    <el-form-item v-if="scope.row.editable" :prop="'access_param.' + scope.$index + '.topo_type'" :rules="tableFromRules.topo_type">
                        <el-select v-model="scope.row.topo_type" clearable>
                            <el-option
                                v-for="(item,index) in topoRoleLists"
                                :key="index" 
                                :value="item.id" 
                                :label="item.name"
                            ></el-option>
                        </el-select>
                    </el-form-item>
                    <span v-else>{{ scope.row.topo_type == 1 ? '任意到任意' : (scope.row.topo_type == 2 ? '中心节点' : (scope.row.topo_type == 3 ? '边缘节点' : '点到点')) }}</span>
                </template>
            </el-table-column>
            <el-table-column label="接入方式" align="center" prop="access_type">
                <template slot="header">
                    <span>
                        <span class="fred">*</span>
                        接入方式
                    </span>
                </template>
                <template slot-scope="scope">
                    <el-form-item v-if="scope.row.editable" :prop="'access_param.' + scope.$index + '.access_type'" :rules="tableFromRules.access_type">
                        <el-select v-model="scope.row.access_type" clearable>
                            <el-option :value=1 label="单归"></el-option>
                            <el-option :value=2 label="双归主备"></el-option>
                            <el-option :value=3 label="双归负载"></el-option>
                        </el-select>
                    </el-form-item>
                    <span v-else>{{ scope.row.access_type == 1 ? '单归' : (scope.row.access_type == 2 ? '双归主备' : '双归负载') }}</span>
                </template>
            </el-table-column>
            <el-table-column label="操作" align="center" width="120">
                <template slot-scope="scope">
                    <div class="fullstacktable_btn">
                        <el-button @click="modifyBtn(scope.row,scope.$index)" type="button" v-show="title == '修改'&&!scope.row.editable">修改</el-button>
                        <el-button @click="saveBtn(scope.row,scope.$index)" type="button" v-show="title == '修改'&&scope.row.editable">确定</el-button>
                        <el-button @click="delBtn(scope.row,scope.$index)" type="button">删除</el-button>
                    </div>
                </template>
            </el-table-column>
        </el-table>
    </el-form>
</section>

data中的数据定义部分

formData: {
    access_param: [
        { name: "", topo_type: "", access_type: "", status: true, editable: true},
    ],
},

说明:其中,status字段为接口返回的字段,用来表示是否可以编辑或删除;true表示可以删除或修改,false表示被占用中,不可以删除或修改;editable是前端页面自己定义的字段,用来控制显示可编辑列还是普通列;
methods中的方法实现

addBtn() {
    let flag = false;
    this.formData.access_param.forEach((item, index) => {
        if (!item.name || !item.topo_type || !item.access_type) {
            flag = true;
            return true
        }
    })
    if (flag) {
        this.$message({
            message: '请先完善必填信息!',
            type: 'info',
            showClose: true
        });
    } else {
        this.formData.access_param.push({
            name: "", 
            topo_type: "", 
            access_type: "",
            editable: true,
            status: true
        })
    }
},
modifyBtn(row,index) {
    if (!row.status) { // true:可以修改;false:不可以修改;
        this.$message({
            message: '已被占用,不支持修改!',
            type: 'warning',
            showClose: true
        });
        return
    }
    this.formData.access_param[index].editable = true;
    this.formData = JSON.parse(JSON.stringify(this.formData));
},
saveBtn(row,index) {
    if (row.name == "" || row.topo_type == "" || row.access_type == "") {
        this.$message({
            message: '请先完善必填信息!',
            type: 'info',
            showClose: true
        });
        return
    }
    this.formData.access_param[index].editable = false;
    this.formData = JSON.parse(JSON.stringify(this.formData));
},
delBtn(row,index) {
    if (!row.status) { // true:可以修改;false:不可以修改;
        this.$message({
            message: '已被占用,不支持删除!',
            type: 'warning',
            showClose: true
        });
        return
    }
    if (this.formData.access_param.length === 1) {
        this.$message({
            message: '至少保留一条数据',
            type: 'warning',
            showClose: true
        })
        return
    }
    this.formData.access_param.splice(index,1)
},

遇到问题的解决步骤:

  1. 在modifyBtn方法中想要通过修改当前行的editable字段来切换可编辑行和普通行 this.formData.access_param[index].editable = true;
    点击“修改”按钮没有效果,数据更新了视图没有更新,因为数据层次太多,render函数没有自动更新,需手动强制刷新。

  2. 通过this.$forceUpdate()强制刷页面,依然无效

this.formData.access_param[index].editable = true;
this.$forceUpdate();
  1. 想要使用this.$set来更新视图
this.$set(this.formData.access_param[index],'editable', true);

结果:第一次点击“修改”按钮可以将当前行变为可编辑的列,但是点击其他的“修改按钮”就没有效果了

  1. 把当前行的this.formData.access_param[index].editable = true;设置为true;然后在把 表格的数据 用this.formData = JSON.parse(JSON.stringify(this.formData)); 重新克隆一遍再赋值给表格就OK了,这也是我代码中使用的方法,但是使用JSON.parse(JSON.stringify());这种方法会有缺陷:如果数据中有使用new Date会将其转换成字符串,需要把数据过滤一下;
// 可行
this.formData.access_param[index].editable = true;
this.formData = JSON.parse(JSON.stringify(this.formData));

// 如果数据中有使用new Date
this.formData.access_param = this.formData.access_param.filter(item => item);
  1. 最完美的办法:直接使用es6的 Object.assign复制一个新的对象 this.formData = Object.assign([],this.formData) 简单明了

其他办法:
给table加key:修改绑定在 table 上面的 key 值,可以触发 table 的重新渲染,这样就可以把修改后的 data 在表格里面更新渲染。

<el-table :data="formData.access_param" :key="timeStamp" :border="true">
</el-table>
data() {
    return {
        timeStamp:'',
        formData: {
            access_param: [
                { name: "", topo_type: "", access_type: "", status: true, editable: true},
            ],
        },
    }
},
watch: {
    'formData.access_param': {
        handler(newVal, oldVal) {
            this.timeStamp = new Date()+''
        },
        deep: true,
        // immediate: true
    },
},

methods: {
	modifyBtn(row,index) {
	    if (!row.status) { // true:可以修改;false:不可以修改;
	        this.$message({
	            message: '已被占用,不支持修改!',
	            type: 'warning',
	            showClose: true
	        });
	        return
	    }
	    
	    this.formData.access_param[index].editable = !row.editable;
	    this.$set(this.formData.access_param[index],'editable', true);
	    // 方法一:将this.timeStamp = new Date()+''放在watch中
	    
	    // 方法二:直接放在this.formData.access_param更新的方法中,顺便设置一下key,页面就更新了
	    // this.timeStamp = new Date()+'';
	},
}
GitHub 加速计划 / eleme / element
54.06 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:2 个月前 )
c345bb45 7 个月前
a07f3a59 * Update transition.md * Update table.md * Update transition.md * Update table.md * Update transition.md * Update table.md * Update table.md * Update transition.md * Update popover.md 7 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐