vue+sortablejs实现列表元素拖拽排序,调用接口保存排序位置

值得注意的就是,v-forkey必须绑定唯一值,不能使用index,不然vue虚拟dom匹配会出现问题,导致拖拽无效

<template>
    <div
      class="list"
      ref="list">
      <div
        class="list-item"
        v-for="(item, index) in showList"
        :key="item.id">
          {{ index }}
      </div>
    </div>
  </card>
</template>
<script>
import Sortable from 'sortablejs';

export default {
  data() {
    return {
      list: [],
      tempList: [],
      sort: null,
    };
  },
  created() {
    this.getList();
  },
  methods: {
    async selectSysAppsYdyByUserId() {
      try {
        const { data: res } = await http.post(
          '/list',
          {}
        );
        if (res.code === 200) {
          this.list = res.data;
          // 浅拷贝一个数组用于排序
          this.tempList = res.data.slice();
          // 初始化排序功能
         if (!this.sort) {
            this.$nextTick(() => {
              this.initSort();
            });
          }
        }
      } catch {
      } finally {
      }
    },
    /** 初始化排序功能 */
    initSort() {
      this.sort = new Sortable(this.$refs.card_list, {
        animation: 300,
        onEnd: ({ newIndex, oldIndex }) => {
          // 不能直接修改原数据,因为virtual DOM和真实DOM之间出现了不一致,导致拖拽错乱,将修改存到一个浅拷贝的临时数组
          // https://www.jiangweishan.com/article/vuejs20221027.html
          const currRow = this.tempList.splice(oldIndex, 1)[0];
          this.tempList.splice(newIndex, 0, currRow);
          this.list = this.tempList.slice();
          this.setSort(this.list);
        },
      });
    },
    /** 保存排序接口 */
    async setSort(data) {
      try {
        const { data: res } = await http.post(
          '/updateList',
          // 这里后端需求是让前端设置好排序索引,也很简单
          data.map((item, index) => {
            item.sortOrder = index;
            return item;
          })
        );
        if (res.code === 200) {
        }
      } catch {
      } finally {
      }
    },
  },
};
</script>

你可能感兴趣的:(vue.js,前端,javascript)