element ui dropdown下拉 复选框+全选+搜索功能 组件 (开箱即食)

46 篇文章 3 订阅
12 篇文章 0 订阅

在这里插入图片描述在这里插入图片描述

element ui dropdown下拉 复选框+全选+搜索功能 组件 (开箱即食)
可以传入默认值默认选中,可以全选,可以搜索,点击确定把选中的值传给父级,开箱即食

<template>
  <div>
    <!-- 下拉有多选功能  还能输入搜索 -->
    <el-dropdown trigger="click" @visible-change="onVisibleChange" class="dropdown">
      <span class="el-dropdown-link">
        下拉菜单<i class="el-icon-arrow-down el-icon--right"></i>
      </span>
      <el-dropdown-menu slot="dropdown" :hide-on-click="false">
        <div class="drop">
          <div style="width: 100%">
            <el-input
              v-model="input"
              @input="inputEvent"
              class="input"
              size="mini"
              prefix-icon="el-icon-search"
              placeholder="搜索"
              clearable
              style="width: 100%"
            >
            </el-input>
          </div>
          <el-checkbox
            :indeterminate="isIndeterminate"
            v-model="checkAll"
            @change="handleCheckAllChange"
            class="checkAlls"
          >
            全选
          </el-checkbox>
          <div class="checkAllLine"></div>
          <el-checkbox-group
            v-model="isCheckIdList"
            v-if="checkboxLists.length > 0"
            @change="handleCheckedChange"
          >
            <div class="checkboxLists">
              <el-checkbox
                v-for="item in checkboxLists"
                :label="item[keys]"
                :key="item[keys]"
                style="display: block"
                class="checiboxItem"
              >
                {{ item.label }}
              </el-checkbox>
            </div>
          </el-checkbox-group>
          <div v-if="checkboxLists.length === 0" class="noData">无数据</div>
          <div class="footer">
            <el-button type="primary" plain size="mini" class="footer_close">
              关 闭
            </el-button>
            <el-button type="primary" size="mini" class="footer_sure" @click="determine">
              确 定
            </el-button>
          </div>
        </div>
      </el-dropdown-menu>
    </el-dropdown>
  </div>
</template>

<script>
/*
 *
 * 数据说明
 * 传进来的数据
 * checkBoxList 里面item一定有key是id,表示唯一值,label用来展示
 * checkBoxList: [{ id: "1", label: "张三", age: 5 },{ id: "2", label: "李四", age: 6 }] // 表示传进来的列表
 * defaultCheckBoxList:['1', '2', '3'] // 默认选中的值
 * keys: "id" // 表示 表示唯一值字段名称
 *
 * 向父级传值:
 * let obj = {
 *  initList, // 原始数组值
 *  initIsCheckId, // 原始id列表值
 *  isCheckIdList, // 选中的id列表值
 *  isCheckEdItem, // 选中的item列表值
 * };
 * this.$emit("checked", obj); // 把选中的信息抛出
 */

export default {
  data() {
    return {
      input: "",
      state2: "",
      checkAll: false,
      isCheckIdList: [], // 选中的
      isIndeterminate: false,
      checkboxLists: [],
      initList: [], // initList: [{ id: "1", label: "张三11", age: 5 }, { id: "2", label: "李四", age: 6 },],
      initIsCheckId: [], // 初始化id列表
    };
  },
  props: {
    keys: {
      type: String,
      default: "id", // 模拟数据 唯一值 是id
    },
    checkBoxList: {
      type: Array,
      default: [
        // 模拟数据 从父组件传进来的数据格式
        { id: "1", label: "张三", age: 5 },
        { id: "2", label: "李四", age: 6 },
        { id: "3", label: "王五", age: 7 },
        { id: "4", label: "赵六 ", age: 8 },
        { id: "5", label: "小英", age: 9 },
        { id: "6", label: "王麻子", age: 10 },
        { id: "7", label: "王小二", age: 11 },
        { id: "8", label: "老王", age: 12 },
        { id: "9", label: "小李", age: 13 },
      ],
    },
    defaultCheckBoxList: {
      type: Array,
      default: ["3", "4", "5"], // 模拟数据 默认选中的id列表
    },
  },

  mounted() {
    this.init();
  },

  methods: {
    init() {
      let { defaultCheckBoxList = [], checkBoxList = [] } = this;
      this.initList = checkBoxList;
      this.checkboxLists = this.deepClone(checkBoxList); // 深拷贝一下
      if (defaultCheckBoxList.length === 0) return;
      let arr = this.getIdList();
      this.initIsCheckId = this.deepClone(arr);
      this.isCheckIdList = arr;
      this.defaultCheckAllStatus();
      // 默认选中 end
    },

    // 提取id列表
    getIdList() {
      let { defaultCheckBoxList, keys = "id" } = this;
      // 默认选中 start
      let item = defaultCheckBoxList[0];
      let types = Object.prototype.toString.call(item);
      let arr = [];
      // 传的是id字符串
      if (types === "[object String]") arr = defaultCheckBoxList;
      // 传的是数组对象包含id
      if (types === "[object Object]") arr = defaultCheckBoxList.map((x) => x[keys] + "");
      // 传的是id数字
      if (types === "[object Number]") arr = defaultCheckBoxList.map((x) => x + "");
      return arr;
    },

    // 确定
    determine() {
      console.log("isCheckIdList", this.isCheckIdList);
      let { keys, isCheckIdList, checkBoxList, initIsCheckId } = this;
      let isCheckEdItem = checkBoxList.filter((x) => isCheckIdList.includes(x[keys]));
      let initList = this.deepClone(this.initList);
      let obj = {
        initList, // 原始数组值
        initIsCheckId, // 原始id列表值
        isCheckIdList, // 选中的id列表值
        isCheckEdItem, // 选中的itemList值
      };
      console.log("obj", obj);
      this.$emit("checked", obj); // 把选中的信息抛出
    },

    onVisibleChange(v) {
      console.log("是否展示:", v);
      if (!v) {
        // 关闭后
        let initArId = this.initIsCheckId.sort().toString();
        let isCheckIdList = this.isCheckIdList.sort().toString();
        console.log("关闭dropdown,前后选项是否相同:", initArId === isCheckIdList);
        if (initArId === isCheckIdList) return; // 选中的值相同 可不请求
        this.determine();
      }
    },

    // 输入事件
    inputEvent(val = "") {
      val = (val + "").toLowerCase();
      let arr = [];
      if (val === "") {
        // 输入为空 把原始数组赋值
        let ars = this.deepClone(this.initList);
        this.checkboxLists = ars;
      } else {
        // 有输入的内容 提取和输入的内容 匹配列表的label 相关内容
        arr = this.checkboxLists.filter((x) => x.label.includes(val));
        this.checkboxLists = arr;
      }
      this.defaultCheckAllStatus();
    },

    // 默认全选状态
    defaultCheckAllStatus() {
      // 选中的和原始值长度一样 全选
      this.checkAll = this.isCheckIdList.length === this.initList.length;

      // 选中的大于0 并且小于原始数组长度,半选状态
      this.isIndeterminate =
        this.isCheckIdList.length > 0 && this.isCheckIdList.length < this.initList.length;
    },

    // 点击全选
    handleCheckAllChange(val) {
      let { keys, checkboxLists } = this;
      let idList = checkboxLists.map((x) => x[keys]);
      this.isCheckIdList = val ? idList : [];
      this.isIndeterminate = false;
      //
      this.$emit("isCheckEdfn", { isCheckIdList: this.isCheckIdList });
    },

    // 点击 某一项
    handleCheckedChange(value) {
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.checkboxLists.length;
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.checkboxLists.length;
    },

    // 深拷贝
    deepClone(source) {
      if (typeof source !== "object" || source == null) {
        return source;
      }
      const target = Array.isArray(source) ? [] : {};
      for (const key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          if (typeof source[key] === "object" && source[key] !== null) {
            target[key] = this.deepClone(source[key]);
          } else {
            target[key] = source[key];
          }
        }
      }
      return target;
    },
  },
};
</script>

<style lang="scss" scoped>
.dropdown {
  cursor: pointer;
}
.drop {
  padding: 10px;
}
.input {
  width: 100px;
  margin: 0 auto;
  width: 100%;
}
.checkAlls {
  margin-top: 5px;
  padding-bottom: 5px;
  display: block;
}
.checkAllLine {
  width: 75%;
  border-bottom: 1px solid #e4e4e4;
  margin: 0 auto;
}
.checkboxLists {
  max-height: 260px;
  padding-right: 10px;
  overflow-y: scroll;
  .checiboxItem {
    margin: 3px 0;
  }
}
.noData {
  margin: 20px 0;
  font-size: 14px;
  color: #ccc;
  width: 100%;
  text-align: center;
}
.footer {
  margin-top: 15px;
  width: 100%;
  text-align: center;
  .footer_sure {
    margin-left: 20px;
  }
}
</style>

  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Element UI提供了Dropdown组件,可以在下菜单中使用框。 在使用Dropdown组件时,我们首先需要引入Element UI库,然后在代码中使用`el-dropdown`和`el-dropdown-menu`来创建下菜单,再利用`el-checkbox-group`和`el-checkbox`来实现框。 以下是一个简单的示例代码: ``` <template> <div> <el-dropdown> <span class="el-dropdown-link"> 下菜单<i class="el-icon-arrow-down el-icon--right"></i> </span> <el-dropdown-menu> <el-checkbox-group v-model="selectedOptions"> <el-checkbox v-for="option in options" :label="option" :key="option">{{ option }}</el-checkbox> </el-checkbox-group> <el-button slot="dropdown-footer" @click="handleConfirm">确定</el-button> </el-dropdown-menu> </el-dropdown> </div> </template> <script> export default { data() { return { options: ['项1', '项2', '项3'], selectedOptions: [] }; }, methods: { handleConfirm() { console.log(this.selectedOptions); // 处理中的项 } } }; </script> ``` 上述代码中,我们使用了`el-dropdown`作为外层容器,通过点击下菜单按钮来展开或收起下菜单。在下菜单中,我们使用`el-checkbox-group`和`el-checkbox`来创建框列表,并通过`v-model`来绑定中的项。 当用户点击确定按钮时,我们可以通过`handleConfirm`方法来处理中的项。你可以根据实际需求来进行处理,比如发送请求、更新数据等。在示例代码中,我们只是简单地通过`console.log`打印中的项。 希望以上内容对你有帮助!如果还有其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端酱紫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值