123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- <template>
- <div
- class="org-select el-select major-select el-select--small"
- @click="switchOpen"
- >
- <div v-if="multiple" class="el-select__tags">
- <el-tag
- v-for="item in selectedList"
- :key="item.id"
- @close="deleteTag($event, item)"
- >{{ item.name }}</el-tag
- >
- </div>
- <div
- :class="[
- 'el-input el-input--small el-input--suffix',
- { 'is-focus': isFocus }
- ]"
- @mouseenter="inputHovering = true"
- @mouseleave="inputHovering = false"
- >
- <input
- ref="inputRef"
- type="text"
- autocomplete="off"
- :placeholder="placeholder"
- class="el-input__inner"
- :value="selectedOrg.name"
- readonly
- />
- <span class="el-input__suffix">
- <span class="el-input__suffix-inner">
- <i
- v-show="!showClose"
- :class="[
- 'el-select__caret',
- 'el-input__icon',
- 'el-icon-arrow-up',
- { 'is-reverse': visible }
- ]"
- ></i>
- <i
- v-if="showClose"
- class="el-select__caret el-input__icon el-icon-circle-close"
- @click="handleClearClick"
- ></i>
- </span>
- </span>
- </div>
- <el-popover
- popper-class="org-popover"
- placement="bottom-start"
- trigger="manual"
- v-model="visible"
- >
- <div ref="popoverRef" slot="reference"></div>
- <div class="org-popover-tree" v-clickoutside="handleClose">
- <el-tree
- ref="OrgTree"
- :data="orgs"
- default-expand-all
- node-key="id"
- :props="defaultProps"
- check-on-click-node
- :expand-on-click-node="false"
- @node-click="nodeClick"
- >
- <span
- :class="['custom-tree-node', { 'is-select': checkSelected(data) }]"
- slot-scope="{ node, data }"
- >
- <span>{{ node.label }}</span>
- <span>
- <i class="el-icon-check"></i>
- </span>
- </span>
- </el-tree>
- </div>
- </el-popover>
- </div>
- </template>
- <script>
- import { organizationList } from "../../modules/base/api";
- import Clickoutside from "element-ui/src/utils/clickoutside";
- export default {
- name: "org-select",
- props: {
- value: {
- type: [Array, String]
- },
- placeholder: { type: String, default: "请选择" },
- multiple: {
- type: Boolean,
- default: false
- },
- disabled: {
- type: Boolean,
- default: false
- },
- clearable: {
- type: Boolean,
- default: true
- }
- },
- directives: { Clickoutside },
- data() {
- return {
- selectedOrg: {},
- selectedOrgList: [],
- selectedOrgIds: [],
- visible: false,
- isFocus: false,
- inputHovering: false,
- orgs: [],
- defaultProps: {
- label: "name"
- }
- };
- },
- computed: {
- showClose() {
- let hasValue = this.multiple
- ? Array.isArray(this.value) && this.value.length > 0
- : this.value !== undefined && this.value !== null && this.value !== "";
- let criteria = this.clearable && this.inputHovering && hasValue;
- return criteria;
- }
- },
- watch: {
- value(val, oldval) {
- if (val !== oldval) this.initSelected(val);
- }
- },
- mounted() {
- this.getList();
- },
- methods: {
- async getList() {
- const orgs = await organizationList();
- this.orgs = orgs || [];
- if (this.orgs.length) {
- this.orgs[0].children.sort((a, b) => {
- if (a.type === "PRINTING_HOUSE") return 1;
- if (b.type === "PRINTING_HOUSE") return -1;
- return 0;
- });
- }
- if (this.value) this.initSelected(this.value);
- },
- switchOpen() {
- if (this.visible) {
- this.handleClose();
- } else {
- this.handleOpen();
- }
- },
- handleOpen() {
- this.isFocus = true;
- setTimeout(() => {
- this.visible = true;
- }, 200);
- },
- handleClose() {
- this.visible = false;
- this.isFocus = false;
- },
- getSelectedData(selectedIds) {
- let selectedData = [];
- if (!selectedIds.length) return [];
- const findTree = list => {
- list.forEach(item => {
- if (selectedIds.includes(item.id)) {
- selectedData.push({ ...item });
- }
- if (item.children && item.children.length) {
- findTree(item.children);
- }
- });
- };
- findTree(this.orgs);
- return selectedData;
- },
- initSelected(val) {
- if (!this.orgs.length) return;
- if (this.multiple) {
- const selectedIds = val || [];
- const selectedData = this.getSelectedData(selectedIds);
- this.selectedOrg = {};
- this.selectedOrgList = selectedData;
- } else {
- const selectedIds = val ? [val] : [];
- const selectedData = this.getSelectedData(selectedIds);
- if (selectedData.length) {
- this.selectedOrg = { ...selectedData[0] };
- this.selectedOrgList = selectedData;
- } else {
- this.selectedOrg = {};
- this.selectedOrgList = [];
- }
- }
- this.updateSelectOrgIds();
- this.emitChange();
- },
- nodeClick(data) {
- if (!this.multiple) {
- this.selectedOrg = { ...data };
- this.selectedOrgList = [{ ...data }];
- this.updateSelectOrgIds();
- this.visible = false;
- this.emitChange();
- return;
- }
- if (this.selectedOrgIds.includes(data.id)) {
- this.selectedOrgList = this.selectedOrgList.filter(
- item => item.id !== data.id
- );
- } else {
- this.selectedOrgList.push({ ...data });
- }
- this.updateSelectOrgIds();
- this.emitChange();
- },
- updateSelectOrgIds() {
- this.selectedOrgIds = this.selectedOrgList.map(item => item.id);
- },
- checkSelected(data) {
- return this.selectedOrgIds.includes(data.id);
- },
- deleteTag(event, data) {
- if (this.selectedOrgIds.includes(data.id)) {
- this.selectedOrgList = this.selectedOrgList.filter(
- item => item.id !== data.id
- );
- this.updateSelectOrgIds();
- this.emitChange();
- }
- event.stopPropagation();
- },
- handleClearClick(event) {
- event.stopPropagation();
- this.selectedOrgList = [];
- this.selectedOrg = {};
- this.updateSelectOrgIds();
- this.emitChange();
- this.handleClose();
- },
- emitChange() {
- this.$emit(
- "input",
- this.multiple ? this.selectedOrgIds : this.selectedOrgIds[0]
- );
- this.$emit(
- "change",
- this.multiple ? this.selectedOrgList : this.selectedOrgList[0]
- );
- }
- }
- };
- </script>
- <style lang="scss">
- .org-select {
- width: 220px;
- }
- .org-popover {
- &.el-popover {
- width: 300px;
- padding: 0;
- }
- &-tree {
- max-height: 300px;
- overflow: auto;
- padding: 5px 0;
- }
- .custom-tree-node {
- .el-icon-check {
- display: none;
- }
- &.is-select {
- color: #3a5ae5;
- .el-icon-check {
- display: block;
- }
- }
- }
- }
- </style>
|