直接上代码 这个是我自己写的示例 比较简单 有注释 很容易看懂
<template>
<div id="multipleMain" class="fd-main">
<div :class="[{'fd-select-body-buttom': !flag}, {'fd-select-body': flag}]" @click="selectClick">
<input class="fd-content" v-model="currentCheckNr" type="text"/>
</div>
<div class="fd-down">
<ul class="fd-list" v-show="flag">
<li class="fd-list-children" :class="{'fd-checked': isActive(item.code)}" v-for="item in cityList"
:key="item.code" @click="clickLi(item)">{{item.name}}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'selectMultiple',
props: {list: {type: Array}},
data: function () {
return {
cityList: [{
code: 1,
name: '成都',
codeType: '10001'
}, {
code: 2,
name: '重庆',
codeType: '10002'
}, {
code: 3,
name: '绵阳',
codeType: '10003'
}],
flag: false,
clickFlag: false,
currentIndex: '',
currentChecked: [],
currentCheckedParams: [],
isExist: false
};
},
mounted() {
// eslint-disable-next-line consistent-this
const that = this;
// 用于监听点击 非本区域 也就是点击这个组件以外的任意地方
document.addEventListener('click', e => {
if (!that.$el.contains(e.target)) {
that.flag = false;
}
});
},
created() {
if (this.list) {
this.cityList = this.list;
}
},
computed: {
// 选中的这个数组中有内容的时候显示选中的内容 没有任何内容的时候 就显示文字提示
currentCheckNr() {
return this.currentChecked.length === 0 ? '请选择' : this.currentChecked;
}
},
methods: {
// 是否展示下拉框的方法
selectClick() {
this.flag = !this.flag;
},
// 单击选择某一项
clickLi(item) {
this.isExist = false;
this.clickFlag = !this.clickFlag;
for (const index in this.currentChecked) {
// 已经选中了 再次点击 就是取消 从选中的列表中移除
if (this.currentChecked[index] === item.name) {
this.currentChecked.splice(index, 1);
this.currentCheckedParams.splice(index, 1);
this.isExist = true;
}
}
// 不存在就把选择的对象名称放入currentChecked用于显示选中的中文项 对象存入currentCheckedParams中用于保存
if (!this.isExist) {
this.currentIndex = item.code;
this.currentChecked.push(item.name);
this.currentCheckedParams.push(item);
}
// 判断选中的对象是否激活
this.isActive(item.code);
},
isActive(code) {
for (const index in this.currentCheckedParams) {
if (this.currentCheckedParams[index].code === code) {
return true;
}
}
return false;
}
}
};
</script>
<style scoped>
.fd-select-body {
background-color: white;
width: 200px;
padding: 5px;
cursor: progress;
margin: auto;
border-radius: 5px;
}
.fd-select-body-buttom {
background-color: white;
width: 200px;
padding: 5px;
cursor: progress;
margin: auto;
border-radius: 5px;
}
.fd-list {
width: 200px;
margin: 1px auto auto;
background-color: white;
height: 200px;
overflow-y: scroll;
}
ul {
list-style-type: none;
}
.fd-main {
margin-top: 30px;
width: 200px;
}
.fd-down {
width: 200px;
position: absolute;
will-change: top, left;
transform-origin: center top;
}
.fd-list-children {
cursor: pointer;
padding: 5px 0;
}
.fd-list-children:hover {
background-color: darkgrey;
}
.fd-checked {
color: #47a3ff;
}
.fd-select-body::after {
content: " ";
background: url("../../../../images/toTop.png") no-repeat;
height: 15px;
width: 10px;
background-size: 100%;
float: right;
margin-top: 5px;
}
.fd-select-body-buttom::after {
content: " ";
background: url("../../../../images/toTop.png") no-repeat;
height: 15px;
width: 10px;
background-size: 100%;
float: right;
margin-top: -2px;
transform: rotate(180deg);
}
.fd-content {
width: 175px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 20px;
outline: none;
border: none;
}
</style>
附上组件在页面上使用的截图: