<template>
  <div>
    <el-button type="info" @click="show = true">筛选</el-button>

    <el-dialog v-if="show" title="筛选" :visible.sync="show" width="960px">
      <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">全选 </el-checkbox>
      <div style="margin: 5px 0" />
      <div class="dash" />
      <div style="margin: 20px 0" />
      <!-- 所有的表格列，注意勾选的回显 -->
      <el-checkbox v-for="item in list" :key="item.prop" v-model="item.checked" :checked="item.checked" style="width: 90px">
        {{ item.label }}
      </el-checkbox>
      <div style="margin: 5px 0" />
      <div class="dash" />
      <div style="margin: 20px 0" />
      <!-- 使用draggable插件---绑定taglist对拖动后tagList的顺序进行修改 -->
      <draggable v-model="tagList">
        <el-tag v-for="tag in tagList" :key="tag.prop" type="danger">
          {{ tag.label }}
        </el-tag>
      </draggable>
      <span slot="footer">
        <el-button @click="show = false">取消</el-button>
        <el-button type="primary" @click="handleConfirm">确认</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import draggable from 'vuedraggable'; // 使用draggable插件---拖动筛选后的表头tag达到排序目的
export default {
  name: 'SiftTableColumn',
  components: {
    draggable
  },
  props: {
    allList: {
      // 所有选项
      type: Array,
      default: () => []
    },
    checkedList: {
      // 勾选过的选项，父组件在localstorage里取值，如果取不到值，默认为所有选项的值
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      tagList: [], // tag绑定的值
      list: [], // checkbox绑定的值
      show: false,
      isIndeterminate: false, // 全选是否半选
      checkAll: true // 是否全选
    };
  },
  watch: {
    // 监听记录的勾选数组变化，更新数据
    checkedList: {
      handler() {
        this.resetList();
      },
      deep: true,
      immediate: true
    },
    show() {
      this.resetList();
    },
    // 监听list的变化，如果某项被勾选或者取消勾选，更新tagList数据来使list勾选项与taglist保持一致且不改变tagList顺序
    list: {
      handler(val) {
        this.getAllChecked();
        const arr = val.filter((item) => item.checked);
        const arr1 = [];
        if (arr.length > this.tagList.length) {
          for (const item of arr) {
            const contain = this.tagList.find((it) => {
              return it.prop === item.prop;
            });
            if (!contain) {
              this.tagList.push(item);
            }
          }
        } else {
          for (const item of this.tagList) {
            const contain = arr.find((it) => {
              return it.prop === item.prop;
            });
            if (contain) {
              arr1.push(item);
            }
          }
          this.tagList = arr1;
        }
      },
      deep: true
    }
  },
  created() {
    this.resetList();
  },
  methods: {
    // 根据接收的val判断全选是否勾选，使list的所有checked属性变为val的值
    handleCheckAllChange(val) {
      this.list = this.allList.map((item) => ({
        ...item,
        checked: val
      }));
    },
    // 选择表头后按确认时，将tagList的值存下来，用于下次父组件中checkedList取值，同时将checkedList的值更新为tagList
    handleConfirm() {
      let localColumns = localStorage.getItem(this.$route.name); // 存储名设为路由名方便不同页面复用
      localColumns = localColumns ? JSON.parse(localColumns) : {};
      this.$set(localColumns, localStorage.getItem('name'), this.tagList); // 使要存储的数组变成map对象，以存储不同的账号的选择的表头
      localStorage.setItem(this.$route.name, JSON.stringify(localColumns));
      this.$emit('update:checkedList', this.tagList);
      this.show = false;
    },
    // 判断接收到的allList和checkedList中是否具有相同的属性值对list赋值
    resetList() {
      this.list = this.allList.map((item) => ({
        ...item,
        checked: this.checkedList.some((it) => it.prop === item.prop)
      }));
      this.tagList = this.deepClone(this.checkedList);
      this.getAllChecked();
    },
    // 判断list中checked的数量来改变全选框中半选和全选的状态
    getAllChecked() {
      let num = 0;
      this.list.forEach((item) => {
        if (item.checked) {
          num++;
        }
      });
      this.isIndeterminate = num > 0 && num < this.list.length;
      this.checkAll = num === this.list.length;
    }
  }
};
</script>

<style lang="scss" scoped>
.dash {
  height: 0;
  border-top: 2px dashed #ccc;
  width: 100%;
}
::v-deep .el-tag--small {
  margin: 5px;
}
::v-deep .el-button--info {
  background-color: #f8456b;
  border-color: #f8456b;
}
::v-deep .el-checkbox__input.is-indeterminate .el-checkbox__inner {
  background-color: #f8456b;
  border-color: #f8456b;
}
::v-deep .el-checkbox__input.is-checked .el-checkbox__inner,
.el-checkbox__input.is-indeterminate .el-checkbox__inner {
  background-color: #f8456b;
  border-color: #f8456b;
}

::v-deep .el-checkbox__input.is-checked + .el-checkbox__label {
  color: #f8456b;
}

::v-deep .el-checkbox__input.is-focus .el-checkbox__inner {
  border-color: #f8456b;
}

::v-deep .el-checkbox__inner:hover {
  border-color: #f8456b;
}
</style>
