在sortablejs中排序, 使用splice, 按照vue的触发视图的方法确实对象数组的位置都更新正确了, 但是dom元素上其他一些初始化渲染的左侧ABC序号和右侧第三列就出现删除文字的渲染既然跟着sortablejs拖拽一起移动了.

而我拿到的需求是拖拽后, 左侧ABC正常从上往下显示, 右侧删除文字也是从第三列开始显示.

解决办法:

JS:

// 拖拽排序
    sortableFun() {
      const _this = this;
      let scrollTopTemp = 0;
      Sortable.create(document.getElementById('sortable'), {
        animation: 1000, // 动画时长
        draggable: '.sortable_item', // 可拖拽的子元素
        delay: 0, // 延时
        // 开始拖拽
        onStart() {
          scrollTopTemp = document.getElementsByTagName('body')[0].scrollTop; // 记录滚动位置
        },
        // 拖动结束
        onEnd({ newIndex, oldIndex }) {
          const listTemp = [ ..._this.list ];
          const oldValue = listTemp.splice(oldIndex, 1); // 取出旧值
          listTemp.splice(newIndex, 0, oldValue[0]); // 添加到新位置
          _this.list = []; // 1.清空(这样ABC才会重新渲染)
          _this.$nextTick(() => {
            _this.list = listTemp; // 2.重新赋值(这样ABC才会重新渲染)
            _this.$nextTick(() => {
              document.getElementsByTagName('body')[0].scrollTop = scrollTopTemp; // 还原滚动条位置
            });
          });
        },
      });
    },

html: (无关紧要可以不看

<el-form id="sortable" label-width="20px" label-position="left">
          <template v-for="(item, index) in list">
            <el-form-item class="sortable_item" :label="index | filterLetters(':')" :key="index">
              <div class="input_line">
                <el-input
                  v-model="item.option_content"
                  placeholder="请输入"
                  maxlength="128"
                  show-word-limit
                ></el-input>
                <el-link
                  v-if="index > 1"
                  class="del_text"
                  type="primary"
                  :underline="false"
                  @click="delOptions(index)"
                >
                  删除
                </el-link>
              </div>
              <div class="upload_line">
                <el-upload
                  class="avatar-uploader"
                  :show-file-list="false"
                  action="#"
                  :before-upload="beforeAvatarUpload"
                  :http-request="(data) => httpRequest(data, index)"
                >
                  <img v-if="item.pic_url" :src="item.pic_url" class="avatar" />
                  <i v-else class="el-icon-plus avatar-uploader-icon" style="color: #2f96ff"></i>
                  <div v-show="item.pic_url" class="del_img" @click.stop="delImgFun(index)">
                    删除
                  </div>
                </el-upload>
                <div class="img_text">
                  上传图片的最佳尺寸300px*300px,且支持png、jpeg、jpg、gif格式,大小不超过1M
                </div>
              </div>
            </el-form-item>
          </template>
          <el-link
            v-if="ruleForm.question_options.length < 10"
            type="primary"
            :underline="false"
            @click="addOptions"
          >
            新增选项
          </el-link>
        </el-form>

Logo

前往低代码交流专区

更多推荐