192 lines
4.6 KiB
Vue
192 lines
4.6 KiB
Vue
<template>
|
|
<el-popover
|
|
placement="bottom"
|
|
trigger="click"
|
|
v-model="participantsPopover"
|
|
>
|
|
<div class="api">
|
|
<dept-tree treeDivId="entrustTree"
|
|
ref="entrustDeptTree"
|
|
@treeDblClick="handleUserNodeDbClick"
|
|
showUser
|
|
allDept
|
|
:editable="false"
|
|
style="width: 200px;height: 500px;overflow: auto">
|
|
</dept-tree>
|
|
</div>
|
|
<div
|
|
slot="reference"
|
|
class="el-select"
|
|
>
|
|
<div
|
|
class="el-select__tags"
|
|
ref="tags"
|
|
:style="{ 'max-width': inputWidth - 32 + 'px', width: '100%' }">
|
|
<transition-group @after-leave="resetInputHeight">
|
|
<el-tag
|
|
v-for="item in selected"
|
|
:key="item.id"
|
|
:closable="true"
|
|
:hit="false"
|
|
type="info"
|
|
@close="deleteTag($event, item)"
|
|
disable-transitions>
|
|
<span class="el-select__tags-text">{{ item.name }}</span>
|
|
</el-tag>
|
|
</transition-group>
|
|
</div>
|
|
|
|
<el-input
|
|
ref="reference"
|
|
:placeholder="placeholder"
|
|
>
|
|
<template slot="suffix">
|
|
<i :class="['el-select__caret', 'el-input__icon', 'el-icon-' + iconClass]"></i>
|
|
</template>
|
|
</el-input>
|
|
</div>
|
|
|
|
|
|
</el-popover>
|
|
</template>
|
|
|
|
<script>
|
|
import eventHub from '@/common/eventHub'
|
|
import {valueEquals} from './util'
|
|
|
|
export default {
|
|
name: "personSelect",
|
|
props: {
|
|
value: {
|
|
type: [String, Array],
|
|
default: []
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
inputWidth: 0,
|
|
participantsPopover: false,
|
|
selected: [],
|
|
deptUser: []
|
|
}
|
|
},
|
|
computed: {
|
|
iconClass() {
|
|
return this.participantsPopover ? 'arrow-up is-reverse' : 'arrow-up'
|
|
},
|
|
},
|
|
watch: {
|
|
value(val, oldVal) {
|
|
this.resetInputHeight();
|
|
this.setSelected();
|
|
}
|
|
},
|
|
methods: {
|
|
resetInputHeight() {
|
|
this.$nextTick(() => {
|
|
if (!this.$refs.reference) return;
|
|
let inputChildNodes = this.$refs.reference.$el.childNodes;
|
|
let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
|
|
const tags = this.$refs.tags;
|
|
const sizeInMap = this.initialInputHeight || 40;
|
|
input.style.height = this.selected.length === 0
|
|
? sizeInMap + 'px'
|
|
: Math.max(
|
|
tags ? (tags.clientHeight + (tags.clientHeight > sizeInMap ? 6 : 0)) : 0,
|
|
sizeInMap
|
|
) + 'px';
|
|
if (this.visible && this.emptyText !== false) {
|
|
this.broadcast('ElSelectDropdown', 'updatePopper');
|
|
}
|
|
});
|
|
},
|
|
resetInputWidth() {
|
|
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
|
|
},
|
|
setSelected() {
|
|
let result = [];
|
|
if (Array.isArray(this.value)) {
|
|
this.value.forEach(value => {
|
|
result.push(this.getOption(value));
|
|
});
|
|
}
|
|
this.selected = result;
|
|
this.$nextTick(() => {
|
|
this.resetInputHeight();
|
|
});
|
|
},
|
|
setDeptUser(data) {
|
|
if (!data) {
|
|
data = []
|
|
}
|
|
this.deptUser = [...data]
|
|
this.setSelected()
|
|
},
|
|
getOption(value) {
|
|
const option = this.deptUser.find(item => item.id === value)
|
|
if (option) return option
|
|
const newOption = {
|
|
id: value,
|
|
name: value,
|
|
shortName: value
|
|
}
|
|
return newOption
|
|
},
|
|
deleteTag(event, tag) {
|
|
let index = this.selected.indexOf(tag);
|
|
if (index > -1) {
|
|
const value = this.value.slice();
|
|
value.splice(index, 1);
|
|
this.$emit('input', value);
|
|
this.emitChange(value);
|
|
this.$emit('remove-tag', tag.value);
|
|
}
|
|
event.stopPropagation();
|
|
},
|
|
emitChange(val) {
|
|
if (!valueEquals(this.value, val)) {
|
|
this.$emit('change', val);
|
|
}
|
|
},
|
|
handleUserNodeDbClick(nodeId, node) {
|
|
this.$refs['entrustDeptTree'].cancelSelectedNode()
|
|
const id = node.id
|
|
if (this.value.includes(id)) {
|
|
return
|
|
}
|
|
let value = []
|
|
if (this.value.length) {
|
|
value = [].concat(this.value, node.id)
|
|
} else {
|
|
value = [].concat(node.id)
|
|
}
|
|
|
|
this.$emit('input', value)
|
|
},
|
|
},
|
|
created() {
|
|
eventHub.$on('deptUser', this.setDeptUser)
|
|
},
|
|
mounted() {
|
|
const reference = this.$refs.reference;
|
|
|
|
this.$nextTick(() => {
|
|
if (reference && reference.$el) {
|
|
this.inputWidth = reference.$el.getBoundingClientRect().width;
|
|
}
|
|
});
|
|
},
|
|
beforeDestroy() {
|
|
eventHub.$off('deptUser', this.setDeptUser)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
|
|
</style>
|