vue中实现下拉菜单单选,多选,查询选中

vue中实现下来菜单单选,多选,查询选中

1.展示效果

在这里插入图片描述

代码展示:

<template>
    <el-dialog
            title="帮助"
            :visible.sync="dialogVisible"
            width="40%"
            customClass="flowHelp"
    >
    <div>
    <!-- 下拉有多选功能  还能输入搜索 -->
    <el-dropdown trigger="click" @visible-change="onVisibleChange" class="dropdown">
      <span class="el-dropdown-link">
       <div class="menu_text"> 下拉菜单<i class="el-icon-arrow-down el-icon--right"></i></div>
      </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" @click="onVisibleChange">
              关 闭
            </el-button>
            <el-button type="primary" size="mini" class="footer_sure" @click="determine">
              确 定
            </el-button>
          </div>
        </div>
      </el-dropdown-menu>
    </el-dropdown>
  </div>
    </el-dialog>
</template>

<script>
    export default {
        data () {
            return {
                dialogVisible: false,
                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 },
                    { id: '10', label: '李四', age: 6 },
                    { id: '11', label: '王五', age: 7 },
                    { id: '12', label: '赵六 ', age: 8 },
                    { id: '13', label: '小英', age: 9 },
                    { id: '14', label: '王麻子', age: 10 },
                    { id: '15', label: '王小二', age: 11 },
                    { id: '16', label: '老王', age: 12 },
                    { id: '17', label: '小李', age: 13 },
                    { id: '18', label: '李四', age: 6 },
                    { id: '19', label: '王五', age: 7 },
                    { id: '20', label: '赵六 ', age: 8 }
                ]
            },
            defaultCheckBoxList: {
                type: Array,
                default: () => ['3', '4', '5'] // 模拟数据 默认选中的id列表  default: () => ['3', '4', '5']
            }
        },
        components: {},
        mounted () {
            this.init1()
        },
        methods: {
            init () {
                this.dialogVisible = true
            },
            init1 () {
                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]
                console.log('默认选中的id', item)
                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 + '')
                console.log('arrarrarrarr', arr)
                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) {
                // console.log('sourcesourcesourcesource', 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]
                        }
                    }
                }
                // console.log('targettargettargettarget:::', target)
                return target
            }

        }
    }
</script>

<style>
    .flowHelp {
        height: 30%;
    }
</style>

<style>
.dropdown {
  cursor: pointer;
}
.drop {
  padding: 10px;
}
/* 设置宽度 */
/* .menu_text {
    width: 200px;
    height: 30px;
    background-color: aqua;
} */
.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>

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

骨子里的偏爱

上传不易,还请多多支持。

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

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

打赏作者

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

抵扣说明:

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

余额充值