|
|
@@ -0,0 +1,176 @@
|
|
|
+<template>
|
|
|
+ <el-select
|
|
|
+ ref="select"
|
|
|
+ v-bind="$attrs"
|
|
|
+ v-model="value"
|
|
|
+ :loading="loading"
|
|
|
+ :placeholder="placeholderProxy"
|
|
|
+ :clearable="clearableProxy"
|
|
|
+ popper-class="o-select-option"
|
|
|
+ @visible-change="onVisibleChange"
|
|
|
+ @change="onChange"
|
|
|
+ >
|
|
|
+ <!-- <el-option
|
|
|
+ v-for="option in options"
|
|
|
+ :key="option.value"
|
|
|
+ :label="option.label"
|
|
|
+ :value="option.value"
|
|
|
+ /> -->
|
|
|
+ <el-option
|
|
|
+ value=""
|
|
|
+ label=""
|
|
|
+ >
|
|
|
+ <el-tree
|
|
|
+ ref="selectTree"
|
|
|
+ :data="options"
|
|
|
+ :props="props"
|
|
|
+ @node-click="handleNodeClick"
|
|
|
+ />
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'TreeSelect',
|
|
|
+ props: {
|
|
|
+ schema: {
|
|
|
+ type: Object,
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ placeholder: {
|
|
|
+ type: String,
|
|
|
+ default: void 0
|
|
|
+ },
|
|
|
+ clearable: {
|
|
|
+ type: [Boolean, String],
|
|
|
+ default: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ loaded: false,
|
|
|
+ loading: false,
|
|
|
+ optionData: null,
|
|
|
+ props: {
|
|
|
+ label: this.schema.label || '',
|
|
|
+ value: this.schema.value || ''
|
|
|
+ },
|
|
|
+ value: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ placeholderProxy () {
|
|
|
+ return this.schema.placeholder || this.placeholder
|
|
|
+ },
|
|
|
+ clearableProxy () {
|
|
|
+ return !!this.schema.placeholder
|
|
|
+ },
|
|
|
+ options () {
|
|
|
+ if (this.loaded) {
|
|
|
+ return this.optionData || []
|
|
|
+ }
|
|
|
+ const { option } = this.schema
|
|
|
+ return this.$attrs.value && option ? [option] : []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created () {
|
|
|
+ const { options, remote } = this.schema
|
|
|
+ this.optionData = options
|
|
|
+ this.loaded = !remote
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onVisibleChange (visible) {
|
|
|
+ if (visible && !this.loaded && !this.loading) {
|
|
|
+ this.loading = true
|
|
|
+ this.loadSelectOptions(this.schema).then(
|
|
|
+ ({ data }) => {
|
|
|
+ this.optionData = data
|
|
|
+ this.loading = false
|
|
|
+ this.loaded = true
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ this.loading = false
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleNodeClick (node) {
|
|
|
+ this.$refs.select.blur() // 隐藏下拉框
|
|
|
+ console.log(node)
|
|
|
+ this.value = node[this.schema.label]
|
|
|
+ this.$emit('input', node[this.schema.value])
|
|
|
+ this.$emit('change', node[this.schema.value])
|
|
|
+ },
|
|
|
+ mergeCondition (condition) {
|
|
|
+ const { options, remote } = this.schema
|
|
|
+ if (remote) {
|
|
|
+ this.schema.condition = { ...this.schema, ...condition }
|
|
|
+ this.optionData = options
|
|
|
+ this.loaded = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ loadSelectOptions () {
|
|
|
+ const { pagination, remote, condition } = this.schema
|
|
|
+ return pagination
|
|
|
+ ? remote({
|
|
|
+ ...condition,
|
|
|
+ pageSize: 10,
|
|
|
+ pageNum: 1
|
|
|
+ }).then(({ data, totalCount }) => {
|
|
|
+ if (totalCount <= 10) {
|
|
|
+ return { data }
|
|
|
+ }
|
|
|
+ return remote({
|
|
|
+ ...condition,
|
|
|
+ pageSize: totalCount,
|
|
|
+ pageNum: 1
|
|
|
+ })
|
|
|
+ })
|
|
|
+ : remote(this.schema)
|
|
|
+ },
|
|
|
+ onChange (value) {
|
|
|
+ this.$emit('input', value)
|
|
|
+ this.$emit('change', value)
|
|
|
+ },
|
|
|
+ getOptions () {
|
|
|
+ return this.optionData || []
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style scoped>
|
|
|
+.el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
|
|
|
+ height: auto;
|
|
|
+ max-height: 274px;
|
|
|
+ padding: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+.el-select-dropdown__item.selected {
|
|
|
+ font-weight: normal;
|
|
|
+}
|
|
|
+ul li >>> .el-tree .el-tree-node__content {
|
|
|
+ height: auto;
|
|
|
+ padding: 0 20px;
|
|
|
+}
|
|
|
+.el-tree-node__label {
|
|
|
+ font-weight: normal;
|
|
|
+}
|
|
|
+.el-tree >>> .is-current .el-tree-node__label {
|
|
|
+ color: #409eff;
|
|
|
+ font-weight: 700;
|
|
|
+}
|
|
|
+.el-tree >>> .is-current .el-tree-node__children .el-tree-node__label {
|
|
|
+ color: #606266;
|
|
|
+ font-weight: normal;
|
|
|
+}
|
|
|
+
|
|
|
+.el-theme1 .el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after{
|
|
|
+ content: '';
|
|
|
+}
|
|
|
+.serarchInput{
|
|
|
+ padding: 10px 20px;
|
|
|
+}
|
|
|
+</style>
|