因爲模仿釘釘的crm系統,有個下拉組件,自己就把他封裝起來,覺得還可以,下面時效果圖
使用案例
<template>
<div class="home">
<selectL v-model="formSearch" @change="staffChange"></selectL>
</div>
</template>
<script>
// @ is an alias to /src
import selectL from '../components/common/selectL'
export default {
components: { selectL },
name: 'home',
data() {
return {
formSearch: {}
}
},
methods:{
staffChange(){}
}
}
</script>
selectL.vue
<template>
<div class="selectL">
<div class="selectL_l" v-if="labelShow">
<el-select v-model="form.type" placeholder="請選擇">
<el-option
v-for="item in selectList.type"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="selectL_r">
<el-popover
v-model="tabs.popoverShow"
placement="bottom-end"
width="320"
trigger="click"
>
<el-input
slot="reference"
class="selectL_r_input"
placeholder="請選擇"
v-model="form.keyValue"
clearable
readonly
>
</el-input>
<div class="seletHome">
<el-tabs
:tab-position="tabs.tabPosition"
style="height: 420px;"
type="border-card"
v-model="active"
>
<el-tab-pane label="員工" name="0">
<div class="tab_connect">
<div class="tab_connect_l">
<p
v-for="(item,
index) in selectList.Letter"
:key="index"
:class="
tabConnect.letterActive == index
? 'isActive'
: ''
"
@click="letterSearchUser(index)"
>
{{ item }}
</p>
</div>
<div class="tab_connect_r">
<el-input
placeholder="請輸入內容"
prefix-icon="el-icon-search"
v-model="tabConnect.searchUser"
@keyup.enter="searchUser"
>
</el-input>
<el-cascader
@change="depSearchUser"
placeholder="請選擇篩選部門"
:options="depTree"
:show-all-levels="false"
></el-cascader>
<div class="userList-scorll">
<div
class="userList"
v-for="(item,
index) in selectList.userList"
:key="index"
>
<p>{{ item.title }}</p>
<div
class="userList_item"
v-for="(user,
userIn) in item.children"
:key="userIn"
@click="getUser(user)"
>
<img :src="user.img" />
<span>{{ user.name }}</span>
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="部門" name="1">
<div class="tab_connect">
<div class="tab_connect_l">
部門選擇
</div>
<div class="tab_connect_r">
<el-input
@blur="tabConnect.searchDepShow = false"
@focus="tabConnect.searchDepShow = true"
@change="searchDep"
placeholder="請輸入內容"
prefix-icon="el-icon-search"
v-model="tabConnect.searchDep"
>
</el-input>
<div v-show="tabConnect.searchDepShow">
<div
class="depList"
v-show="searchDep(item.label)"
v-for="(item,
index) in selectList.depList"
:key="index"
@click="getSearchDep(item)"
>
{{ item.label }}
</div>
</div>
<el-tree
v-show="!tabConnect.searchDepShow"
:data="depTree"
:props="defaultProps"
@node-click="handleNodeClick"
></el-tree>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</el-popover>
</div>
</div>
</template>
<script>
export default {
name: 'selectL',
props: {
formSearch: Object,
//select左邊是否顯示
labelShow: {
type: Boolean,
default: true
}
},
computed: {
keyValue: {
get() {
return this.form.keyValue
},
set() {
this.$emit('input', this.form)
}
}
},
data() {
return {
//下拉數據
selectList: {
Letter: ['A', 'B', 'C'],
type: [
{ value: 0, label: '協同' },
{ value: 1, label: '負責' }
],
//員工列表
userList: [
{
title: 'A',
children: [
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '撒旦',
id: 1
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '毛線',
id: 2
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '撒旦',
id: 1
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '毛線',
id: 2
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '撒旦',
id: 1
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '毛線',
id: 2
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '撒旦',
id: 1
}
]
},
{
title: 'B',
children: [
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '小米',
id: 1
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '小米',
id: 2
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '小米',
id: 1
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '小米',
id: 2
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '小米',
id: 1
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '小米',
id: 2
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '小米',
id: 1
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '小米',
id: 2
}
]
},
{
title: 'C',
children: [
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '忘了',
id: 1
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '忘了',
id: 2
},
{
img:
'https://static-legacy.dingtalk.com/media/lADPDgQ9rMEynzzNAhjNAhg_536_536.jpg',
name: '忘了',
id: 1
}
]
}
],
//部門列表
depList: [
{ value: 1, label: '財務' },
{ value: 2, label: '諮詢' }
],
// 員工offset
userOffset: []
},
//tree 數據格式
defaultProps: {
children: 'children',
label: 'label'
},
//tab 搜索框
tabConnect: {
searchDep: '', //部門本地篩選
searchUser: '', // 員工
depId: '', //部門id
letterActive: 0, // 當前活動字母
scrollTop: 0, // 當前滾動距離
searchDepShow: false // 是否顯示部門列表
},
//部門 樹狀
depTree: [
{
value: 'zhinan',
label: '全公司',
children: [
{
value: 'shejiyuanze',
label: '財務',
children: [
{
value: 'yizhi',
label: '一致'
},
{
value: 'fankui',
label: '反饋'
},
{
value: 'xiaolv',
label: '效率'
},
{
value: 'kekong',
label: '可控'
}
]
}
]
}
],
tabs: {
tabPosition: 'right',
popoverShow: false
},
active: '0',
// 反饋數據
form: {
type: 1,
keyValue: '',
keyId: -1
}
}
},
watch: {
active(val) {
if (val == '0' && this.tabs.popoverShow) {
this.getUserOffset()
this.addUserListScorll()
}
},
'tabs.popoverShow': {
deep: true,
handler: function(newVal) {
if (newVal) {
this.getUserOffset()
this.addUserListScorll()
} else {
this.removeUserListScorll()
}
}
}
},
methods: {
// 獲取員工列表各個距離
getUserOffset() {
this.selectList.userOffset = []
let num = this.selectList.Letter.length
let arr = [0]
let dv = document.getElementsByClassName('userList')
this.$nextTick(() => {
for (let i = 0; i < num; i++) {
arr.push(dv[i].offsetTop)
}
for (let i = 1; i < arr.length; i++) {
let obj = {
min: arr[i - 1],
max: arr[i]
}
this.selectList.userOffset.push(obj)
}
})
},
//移除監聽
removeUserListScorll() {
let scroll = document.getElementsByClassName('userList-scorll')[0]
scroll.removeEventListener('scroll', () => {
this.userListScorll()
})
},
//添加監聽
addUserListScorll() {
let scroll = document.getElementsByClassName('userList-scorll')[0]
scroll.addEventListener('scroll', () => {
this.userListScorll(scroll.scrollTop)
})
},
//員工滾動事件
userListScorll(val) {
let num = this.selectList.userOffset
for (let i = 0; i < num.length; i++) {
if (val > num[i].min && val <= num[i].max) {
this.tabConnect.letterActive = i
return
}
}
},
// 搜索員工
searchUser() {
this.getUserList()
},
// 字母篩選員工移動滾動條
letterSearchUser(index) {
let num = document.getElementsByClassName('userList')[index]
.offsetTop
document.getElementsByClassName('userList-scorll')[0].scrollTop =
num - 93
this.tabConnect.letterActive = index
},
// 部門篩選員工
depSearchUser(val) {
this.tabConnect.depId = val.length - 1
this.getUserList()
},
//選擇員工
getUser(user) {
this.form.keyValue = user.name
this.keyValue = user.name
this.form.keyId = user.id
this.tabs.popoverShow = false
this.$emit('change',this.form)
},
// 模糊查詢部門列表
searchDep(val) {
if (
this.tabConnect.searchDep == '' ||
this.tabConnect.searchDep == null
) {
return true
}
if (val.indexOf(this.tabConnect.searchDep) == -1) {
return false
} else {
return true
}
},
//搜索列表 單擊獲取部門
getSearchDep(item) {
this.keyValue = item.name
this.form.keyValue = item.label
this.form.keyId = item.value
this.tabs.popoverShow = false
},
//部門選擇
handleNodeClick(data) {
this.keyValue = data.name
this.form.keyValue = data.label
this.form.keyId = data.value
this.tabs.popoverShow = false
},
//list 獲取員工列表
getUserList() {},
//list 獲取部門列表
getDepList() {},
//tree 獲取部門樹狀
getDepTree() {}
},
created() {
this.getUserList() //獲取員工列表
this.getDepList() //獲取部門列表
this.getDepTree() //獲取部門樹狀
}
}
</script>
<style lang="less">
.el-popover {
padding: 0;
}
.selectL {
.selectL_l {
width: 82px;
.el-select {
textarea,
input[type='password'],
input[type='text'] {
color: #909399;
box-shadow: 0 0 0px 1000px #f5f5f5 inset;
-webkit-box-shadow: 0 0 0px 1000px #f5f5f5 inset;
}
}
.el-input__inner {
border-radius: 4px 0 0 4px;
}
}
.selectL_r {
.el-input__inner {
width: 240px;
border-radius: 0 4px 4px 0;
}
}
}
.seletHome {
.el-tabs__content {
height: 100%;
}
.el-tab-pane {
height: 100%;
}
.el-tabs--right .el-tabs__header.is-right {
margin-left: 0;
}
.el-tabs {
width: 320px;
}
.el-tabs__nav {
white-space: normal;
}
.el-tabs--right.el-tabs--border-card .el-tabs__header.is-right {
border-left: none;
}
.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right {
border: none;
}
.el-tabs__item {
line-height: 1.2;
color: #4e617c;
cursor: pointer;
padding: 9px;
font-size: 13px;
height: auto;
width: 32px;
}
.el-tabs--border-card > .el-tabs__content {
padding: 0;
}
.tab_connect_r {
.el-input {
width: 236px;
margin: 0 10px 10px;
}
}
}
</style>
<style lang="less" scoped>
.selectL {
display: flex;
}
.seletHome {
.tab_connect {
display: flex;
justify-content: flex-start;
.tab_connect_l {
width: 32px;
overflow-y: scroll;
height: 410px;
padding: 5px 10px;
p {
color: #ccc;
text-align: center;
cursor: pointer;
}
p:hover {
font-size: 16px;
color: #ff7c35;
}
.isActive {
font-size: 16px;
color: #ff7c35;
}
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
.tab_connect_r {
border-left: 1px solid #eceff5;
padding: 9px 0;
height: 420px;
.userList-scorll {
height: 327px;
overflow-y: scroll;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
.userList {
p {
background-color: #f5f9ff;
height: 24px;
line-height: 24px;
font-weight: 700;
padding-left: 10px;
}
div {
cursor: pointer;
padding: 5px 10px;
display: flex;
justify-items: center;
img {
width: 24px;
height: 24px;
border-radius: 50%;
margin-right: 10px;
}
span {
line-height: 24px;
}
}
div:hover {
background-color: #73acff;
color: #fff;
}
}
.depList {
padding: 5px 10px;
cursor: pointer;
}
.depList:hover {
background: #f5f5f5;
}
}
}
}
</style>