v-for导致的问题引发的思考

322 阅读1分钟

前言

在动态添加数组操作的时候 会发生渲染错乱的问题,显示在页面和数组里面的num不一致,引发问题的demo,在点击前面几列的加号的时候 连续点击两次就会问题。如下图 应该为2、3却渲染成3、3

image.png

代码

<template>
  <div class="con">
    <div>

      <el-table :data="tableData"
                border
                style="width: 100%">

        <el-table-column v-for="(item,index) in tableHeader"
                         :key="item.tripIndex"
                         :prop="'prop'+item.tripIndex"
                         width="100"
                         align="center">
          <template slot="header"
                    slot-scope="scope">
            <div>
              <i @click="addHeade(item.tripIndex)"
                 class="el-icon-circle-plus-outline myIcon operateLine-item"></i>
              <i @click="subHeade(item.tripIndex)"
                 class="el-icon-remove-outline myIcon"></i>
            </div>
            {{`${item.tripIndex}  ${getMain(item)}  `}}

          </template>

          <template slot-scope="scope">
            {{ getName(scope.row,item.tripIndex)}}

          </template>

        </el-table-column>

      </el-table>
    </div>
  </div>
</template>

<script>
export default {
  name: "add",
  components: {},
  data() {
    return {
      isShow: true,
      tableHeader: [
        {
          tripIndex: 1,
        },
        {
          tripIndex: 2,
        },
        {
          tripIndex: 3,
        },
        {
          tripIndex: 4,
        },
      ],
      tableData: [
        {
          prop1: { name: "张三" },
          prop2: { name: "李四" },
          prop3: { name: "王五" },
          prop4: { name: "赵六" },
        },
        {
          prop1: { name: "陈甲" },
          prop2: { name: "巫乙" },
          prop3: { name: "于丙" },
          prop4: { name: "汪丁" },
        },
      ],
    };
  },
  mounted() {},
  methods: {
    getMain(v) {
      if (v.tripIndex % 2 == 0) {
        return "副站";
      } else {
        return "主站";
      }
    },
    addHeade(v) {
      this.isShow = false;

      //表头加一
      this.tableHeader.forEach((element) => {
        if (element.tripIndex > v) {
          element.tripIndex += 1;
        }
      });

      for (let index = this.tableHeader.length; index == 0; index--) {
        if (this.tableHeader[index].tripIndex > v) {
          this.tableHeader[index].tripIndex += 1;
        }
      }

      //插入表头
      let i;
      let addItem = {
        tripIndex: v + 1,
      };

      for (let index = 0; index < this.tableHeader.length; index++) {
        const element = this.tableHeader[index];
        if (element.tripIndex == v) {
          i = index;
        }
      }
      //   this.tableHeader.splice(i + 1, 0, addItem);

      for (let index = 0; index < this.tableData.length; index++) {
        for (var key in this.tableData[index]) {
          if (key.indexOf("prop") != -1) {
            let num = "odd" + key.substring(4);
            this.tableData[index][num] = this.tableData[index][key];
          }
        }
      }

      for (let index = 0; index < this.tableData.length; index++) {
        for (var key in this.tableData[index]) {
          //后面值后移
          if (key.substring(4) > v && key.indexOf("prop") != -1) {
            let num = "prop" + (parseInt(key.substring(4)) + 1);
            let now = "odd" + key.substring(4);
            this.tableData[index][num] = this.tableData[index][now];
          }
          //新增出来的值置空
          if (key.substring(4) == v && key.indexOf("prop") != -1) {
            let num = "prop" + (parseInt(key.substring(4)) + 1);
            this.tableData[index][num] = {};
          }
        }
      }

      console.log(this.tableData);

      this.$nextTick(() => {
        this.isShow = true;
      });
    },
    subHeade(v) {
      this.isShow = false;
      let i;
      for (let index = 0; index < this.tableHeader.length; index++) {
        const element = this.tableHeader[index];
        if (element.tripIndex == v) {
          i = index;
        }
      }
      this.tableHeader.splice(i, 1);

      this.tableHeader.forEach((element) => {
        if (element.tripIndex > v) {
          element.tripIndex -= 1;
        }
      });

      for (let index = 0; index < this.tableData.length; index++) {
        for (var key in this.tableData[index]) {
          if (key.indexOf("prop") != -1) {
            let num = "odd" + key.substring(4);
            this.tableData[index][num] = this.tableData[index][key];
          }
        }
      }

      for (let index = 0; index < this.tableData.length; index++) {
        for (var key in this.tableData[index]) {
          //后面值前移
          if (key.substring(4) > v && key.indexOf("prop") != -1) {
            let num = "prop" + (parseInt(key.substring(4)) - 1);
            let now = "odd" + parseInt(key.substring(4));
            this.tableData[index][num] = this.tableData[index][now];
          }
          //删除最后一项
          let last =
            "prop" +
            (this.tableHeader[this.tableHeader.length - 1].tripIndex + 1);

          delete this.tableData[index][last];
        }
      }

      console.log(this.tableData);
      this.$nextTick(() => {
        this.isShow = true;
      });
    },
    getName(v, x) {
      let p = "prop" + x;
      return v[p];
    },
  },
  created() {},
};
</script>


后续

虽然使用v-if 去重新渲染表格解决了问题 但是知其然不知其所以然 大佬们要是有明白的又刚好看见此文,还望不吝指教 十分感谢