VUE + sortable.js实现拖动,多条置顶

2,343 阅读1分钟

vue-cli3 创建项目

vue create vue-sortable

安装 sortablejs

yarn add sortablejs

效果展示

代码

<template>
  <div>
    <span>
      <button v-show="edit" @click="visiavle">编辑默认排序</button>
      <span v-show="!edit">
        <button @click="save">保存</button>
        <button @click="cancel">取消</button>
        <button @click="top">置顶</button>
      </span>
    </span>
    <ul class="list" id="list">
      <li v-for="(item,index) in items" :key="item.id">
        <input v-show="!edit" @click="add(item.id,index,$event)" type="checkbox" ref="checkbox" />
        <b>{{item.nm}}</b>
      </li>
    </ul>
  </div>
</template>
<script>
import Sortable from "sortablejs";
export default {
  data () {
    return {
      ids: [], // 要置顶的id
      indexs: [],// 当前排序的index数组
      Sort: null, // 存储sortablejs实例对象
      edit: true, // 是否编辑状态
      copyItems: [], // 取消的备用数组
      topItems: [], // 置顶的备用数组
      saveItems: [],
      items: [
        {
          id: 1,
          nm: "1"
        },
        {
          id: 2,
          nm: "22"
        },
        {
          id: 3,
          nm: "333"
        },
        {
          id: 4,
          nm: "4444"
        },
        {
          id: 5,
          nm: "55555"
        },
        {
          id: 6,
          nm: "666666"
        }
      ]
    };
  },
  methods: {
    // 保存要置顶的id
    add (id, index, event) {
      if (event.currentTarget.checked) {
        // 保存要置顶的id备用,发送后台
        this.ids.push(id);
        // 判断当前复选框的状态
        this.indexs.push(index);
      } else {
        // 复选框取消
        let i = this.indexs.findIndex(v => v == index);
        this.indexs.splice(i, 1);
        let k = this.ids.findIndex(v => v == id);
        this.ids.splice(k, 1);
      }
      // console.log(this.indexs,this.ids)
    },
    //置顶
    top () {
      // indexs要从后到前排序一下
      this.indexs = this.indexs.sort((a, b) => b - a)

      this.topItems = JSON.parse(JSON.stringify(this.items));
      if (this.indexs.length > 0) {
        this.indexs.forEach(v => {
          // 删除内容
          // this.topItems.unshift(this.topItems.splice(v, 1)[0]);
          this.saveItems.push(this.topItems.splice(v,1)[0])
        });
        this.saveItems.reverse()
        this.topItems = [...this.saveItems,...this.topItems]
        console.log(this.saveItems)
        this.$refs.checkbox.forEach(v => {
          // 取消复选框选中状态
          v.checked = false;
        });
      } else {
        return
      }
      this.items = [...this.topItems];
      this.indexs = [];
      this.topItems = [];
      this.ids = [];
      this.saveItems = []
    },
    cancel () {
      //取消
      this.visiavle();
      this.items = this.copyItems;
      this.Sort.destroy(); //销毁排序功能
    },
    save () {
      //保存
      this.visiavle();
      this.Sort.destroy();
    },
    visiavle () {
      // 按钮显示切换
      // 编辑为true的时候才去拷贝原数组
      this.edit
        ? (this.copyItems = JSON.parse(JSON.stringify(this.items)))
        : ""; // 复制原有数组
      this.edit = !this.edit;
      !this.edit && this.sort();
    },
    // 排序的方法
    sort () {
      var _this = this;
      var $ul = document.getElementById("list");
      this.Sort = new Sortable($ul, {
        onUpdate: function (event) {
          //修改items数据顺序
          var newIndex = event.newIndex,
            oldIndex = event.oldIndex,
            $li = $ul.children[newIndex],
            $oldLi = $ul.children[oldIndex];
          // 先删除移动的节点
          $ul.removeChild($li);
          // 再插入移动的节点到原有节点,还原了移动的操作
          if (newIndex > oldIndex) {
            $ul.insertBefore($li, $oldLi);
          } else {
            $ul.insertBefore($li, $oldLi.nextSibling);
          }
          // 更新items数组
          var item = _this.items.splice(oldIndex, 1);
          _this.items.splice(newIndex, 0, item[0]);
          // 下一个tick就会走patch更新
        },
        animation: 150
      });
    }
  }
};
</script>
<style scoped>
li {
  list-style: none;
  background: palegoldenrod;
  width: 200px;
}
ul {
  display: flex;
  justify-content: space-evenly;
}
</style>