自定义穿梭框封装

 

 后面有时间再来慢慢搞吧,暂且先这样, 有需要的可以把代码考过去继续弄

<template>
  <div id="app">
    <div class="f-transfer flex">
      <!-- left -->
      <div class="f-left">
        <div class="f-top flex flex-justify-between">
          <el-checkbox
            :indeterminate="isIndeterminate"
            v-model="checkAll"
            @change="handleCheckAllChange"
            >全选</el-checkbox
          >

          <span style="color: #606266"
            >{{ SelectNumLeft }}/{{ cities.length }}</span
          >
        </div>
        <div class="f-search">
          <el-input
            placeholder="请输入内容"
            prefix-icon="el-icon-search"
            @input="search"
            v-model="input2"
          >
          </el-input>
        </div>
        <div class="f-container">
          <el-checkbox-group
            v-model="checkedCities"
            @change="handleCheckedCitiesChange"
          >
            <el-checkbox
              v-for="city in cities"
              :label="city.key"
              :key="city.key"
              class="flex"
            >
              <el-row :gutter="20">
                <el-col :span="8">
                  <el-tooltip
                    class="item"
                    effect="dark"
                    :content="city.label"
                    placement="top"
                  >
                    <p class="emtys">{{ city.label }}</p>
                  </el-tooltip>
                </el-col>
                <el-col :span="12">
                  {{ city.phone }}
                </el-col>
                <el-col :span="2">
                  <span style="color: #76b9ed" @click="operate(city.key)"
                    >操作</span
                  >
                </el-col>
              </el-row>
            </el-checkbox>
          </el-checkbox-group>
        </div>

        <div style="padding: 8px 0">
          <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page.sync="currentPage"
            :pager-count="5"
            :page-sizes="[10, 20, 30]"
            :page-size="pageSize"
            small
            layout="prev, pager, next,sizes"
            :total="total"
          ></el-pagination>
        </div>
      </div>
      <!-- middle -->
      <div class="f-middle flex-column">
        <el-button style="margin: 10px" @click="leftDataFunc">
          <i class="el-icon-arrow-left"></i>
        </el-button>
        <el-button style="margin: 10px" @click="rightDataFunc">
          <i class="el-icon-arrow-right"></i>
        </el-button>
      </div>
      <!-- right -->
      <div class="f-right f-left">
        <div class="f-top flex flex-justify-between">
          <el-checkbox
            :indeterminate="isIndeterminateCheck"
            v-model="checkAllCheck"
            @change="handleCheckAllChangeCheck"
            >全选</el-checkbox
          >
          <span style="color: #606266"
            >{{ SelectNumRight }}/{{ citiesCheck.length }}</span
          >
        </div>
        <div class="f-search">
          <el-input
            placeholder="请输入内容"
            prefix-icon="el-icon-search"
            @input="searchCheck"
            v-model="input2Check"
          >
          </el-input>
        </div>
        <div class="f-container">
          <el-checkbox-group
            v-model="checkedCitiesCheck"
            @change="handleCheckedCitiesChangeCheck"
          >
            <el-checkbox
              v-for="city in citiesCheck"
              :label="city.key"
              :key="city.key"
              class="flex"
            >
              <el-row :gutter="20">
                <el-col :span="8">
                  <p class="emtys">{{ city.label }}</p>
                </el-col>
                <el-col :span="12">
                  {{ city.phone }}
                </el-col>
                <el-col :span="2">
                  <span style="color: #76b9ed" @click="operateCheck(city.key)"
                    >操作</span
                  >
                </el-col>
              </el-row>
            </el-checkbox>
          </el-checkbox-group>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      checkAll: false, //左侧全选状态
      checkedCities: [], //左侧勾选中的key数组
      cities: [], //左侧列表数据列表
      isIndeterminate: false, //左侧顶部选择状态
      input2: "", //左侧搜索value
      newCities: [], //左侧搜索时,数据暂存
      citiesStatus: true, //左侧是否进行暂存数据的状态
      currentPage: 1, //左侧当前第几页
      pageSize: 30, //左侧每页显示多少条数据
      total: 90, //左侧总条数
      //----------------------------
      checkAllCheck: false, //右侧全选状态
      checkedCitiesCheck: [], //右侧勾选中的key数组
      citiesCheck: [], //右侧列表数据列表
      isIndeterminateCheck: false, //右侧顶部选择状态
      input2Check: "", //右侧搜索value
      newCitiesCheck: [], //右侧搜索时,数据暂存
      citiesStatusCheck: true, //右侧是否进行暂存数据的状态
      //----------------------------------------
    };
  },
  mounted() {
    this.dataAdd();
  },
  watch: {
    checkedCities: {
      handler(newval) {
        if (newval.length == 0) {
          this.checkAll = false;
          this.isIndeterminate = false;
        }
      },
      deep: true,
      immediate: true,
    },
    checkedCitiesCheck: {
      handler(newval) {
        if (newval.length == 0) {
          this.checkAllCheck = false;
          this.isIndeterminateCheck = false;
        }
      },
      deep: true,
      immediate: true,
    },
  },
  computed: {
    SelectNumLeft() {
      return [...new Set(this.checkedCities)].length;
    },
    SelectNumRight() {
      return [...new Set(this.checkedCitiesCheck)].length;
    },
  },
  methods: {
    operate(key) {
      let result = this.cities.filter((item) => {
        return item.key == key;
      });
      let arry = this.citiesCheck;
      arry.push(result[0]);
      this.checkedCities = this.checkedCities.filter((key) => {
        return key != result[0].key;
      });
      this.cities = this.deleteObjectById(this.cities, result[0].key);
      this.citiesCheck = this.Deduplication(arry, "key");
    },
    //根据id删除对象
    deleteObjectById(arr, key) {
      return arr.filter((obj) => obj.key != key);
    },
    Deduplication(data, key) {
      var arr1 = data.filter(function (element, index, self) {
        return self.findIndex((el) => el[key] == element[key]) === index; 
      });
      // 在重新赋值给data
      return arr1;
    },
    search(val) {
      if (this.citiesStatus) {
        this.citiesStatus = false;
        this.newCities = this.cities;
      }
      let result = this.newCities.filter((item) => {
        return item.label.includes(val);
      });
      console.log(result, "======result");
      this.cities = result;

      if (!val) {
        this.cities = this.newCities;
      }
    },
    handleCheckAllChange(val) {
      if (val) {
        this.cities.forEach((item) => {
          this.checkedCities.push(item.key);
        });
      } else {
        this.checkedCities = [];
      }
      this.isIndeterminate = false;
    },
    handleCheckedCitiesChange(value) {
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.cities.length;
      this.isIndeterminate =
        checkedCount > 0 && checkedCount < this.cities.length;
    },
    rightDataFunc() {
      this.checkedCities = [...new Set(this.checkedCities)];
      this.checkedCities.forEach((key) => {
        let result = this.cities.filter((item) => {
          return key == item.key;
        })[0];
        this.citiesCheck.push(result);
        this.cities = this.deleteObjectById(this.cities, result.key);
        this.checkedCities = this.checkedCities.filter((key) => {
          return key != result.key;
        });
      });
    },
    handleSizeChange(val) {
      console.log(`每页 ${val} 条`);
      this.pageSize = val;
      this.dataAdd();
    },
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`);
      this.currentPage = val;
      this.dataAdd();
    },

    // ------------------------------------------------------
    leftDataFunc() {
      this.checkedCitiesCheck = [...new Set(this.checkedCitiesCheck)];
      this.checkedCitiesCheck.forEach((key) => {
        let result = this.citiesCheck.filter((item) => {
          return key == item.key;
        })[0];
        this.cities.push(result);
        this.citiesCheck = this.deleteObjectById(this.citiesCheck, result.key);
        this.checkedCitiesCheck = this.checkedCitiesCheck.filter((key) => {
          return key != result.key;
        });
      });
    },
    operateCheck(key) {
      let result = this.citiesCheck.filter((item) => {
        return item.key == key;
      });
      let arry = this.cities;
      arry.push(result[0]);
      this.checkedCitiesCheck = this.checkedCitiesCheck.filter((key) => {
        return key != result[0].key;
      });
      this.citiesCheck = this.deleteObjectById(this.citiesCheck, result[0].key);
      this.cities = this.Deduplication(arry, "key");
    },
    searchCheck(val) {
      if (this.citiesStatusCheck) {
        this.citiesStatusCheck = false;
        this.newCitiesCheck = this.citiesCheck;
      }
      let result = this.newCitiesCheck.filter((item) => {
        return item.label.includes(val);
      });
      console.log(result, "======result");
      this.citiesCheck = result;

      if (!val) {
        this.citiesCheck = this.newCitiesCheck;
      }
    },
    handleCheckAllChangeCheck(val) {
      if (val) {
        this.citiesCheck.forEach((item) => {
          this.checkedCitiesCheck.push(item.key);
        });
      } else {
        this.checkedCitiesCheck = [];
      }
      this.isIndeterminateCheck = false;
    },
    handleCheckedCitiesChangeCheck(value) {
      let checkedCountCheck = value.length;
      this.checkAllCheck = checkedCountCheck === this.citiesCheck.length;
      this.isIndeterminateCheck =
        checkedCountCheck > 0 && checkedCountCheck < this.citiesCheck.length;
    },

    //------------------------------------------
    dataAdd() {
      let array = [];
      for (let i = 0; i < this.pageSize; i++) {
        let s = (this.currentPage - 1) * this.pageSize + i;
        let obj = {
          key: s + 1,
          label: "王麻子" + (s + 1),
          phone: "15666667" + (s + 1),
          status: true,
        };
        array.push(obj);
      }
      this.cities = array;
    },
  },
};
</script>

<style>
.f-transfer .f-left {
  width: 320px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid #ccc;
}
.flex {
  display: flex !important;
  align-items: center;
}
.f-container::-webkit-scrollbar {
  width: 2px;
}
.f-container::-webkit-scrollbar-thumb {
  border-radius: 8px;
  background-color: #c6d1e2;
}
.f-container::-webkit-scrollbar-track {
  border-radius: 8px;
  background-color: #f2f7ff;
  border: 1px solid #f2f7ff;
}
.flex-column {
  display: flex;
  flex-direction: column;
}
.flex-justify-between {
  justify-content: space-between;
}
.f-transfer .f-left .f-top {
  background: #ccc;
  height: 30px;
  padding: 10px;
  line-height: 30px;
}
.emtys {
  padding: 0;
  margin: 0;
  width: 60px;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
.f-search {
  padding: 10px;
}
.f-transfer .f-left .f-container {
  height: 270px;
  overflow-y: auto;
  padding: 10px;
}
.el-checkbox-group {
  display: flex;
  flex-direction: column;
}
.el-checkbox {
  margin: 6px 0;
}
</style>

 

posted @ 2024-09-14 10:50  龙卷风吹毁停车场  阅读(58)  评论(0)    收藏  举报