111 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div class="ai-select">
 | |
|     <el-select
 | |
|         style="width: 100%;"
 | |
|         clearable
 | |
|         :value="value"
 | |
|         :size="$attrs.size || 'small'"
 | |
|         :filterable="isAction"
 | |
|         v-bind="$attrs"
 | |
|         v-on="$listeners">
 | |
|       <template v-if="isAction">
 | |
|         <el-option v-for="op in actionOps" :key="op.id"
 | |
|                    :label="op[actionProp.label]" :value="op[actionProp.value]"/>
 | |
|       </template>
 | |
|       <template v-else>
 | |
|         <el-option
 | |
|             v-for="(item, index) in selectList"
 | |
|             :key="index"
 | |
|             :label="item.dictName"
 | |
|             :value="item.dictValue"/>
 | |
|       </template>
 | |
|     </el-select>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   name: 'AiSelect',
 | |
| 
 | |
|   model: {
 | |
|     prop: 'value',
 | |
|     event: 'change'
 | |
|   },
 | |
|   watch: {
 | |
|     instance: {
 | |
|       deep: true,
 | |
|       handler(v) {
 | |
|         v && this.isAction && !this.options.toString() && this.getOptions()
 | |
|       }
 | |
|     },
 | |
|     value(v) {
 | |
|       this.$emit("select", this.isAction ? this.options.find(e => e[this.actionProp.value] == v) :
 | |
|           this.selectList.find(e => e.dictValue == v))
 | |
|     }
 | |
|   },
 | |
|   props: {
 | |
|     value: {default: null},
 | |
|     selectList: {
 | |
|       type: Array
 | |
|     },
 | |
| 
 | |
|     width: {
 | |
|       type: String,
 | |
|       default: '216'
 | |
|     },
 | |
|     instance: Function,
 | |
|     action: {default: ""},
 | |
|     prop: {
 | |
|       default: () => ({})
 | |
|     }
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       options: [],
 | |
|       filter: ""
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     selectWidth() {
 | |
|       if (this.width.indexOf('px') > -1) {
 | |
|         return this.width
 | |
|       }
 | |
|       return `${this.width}px`
 | |
|     },
 | |
|     isAction() {
 | |
|       return !!this.action
 | |
|     },
 | |
|     actionOps() {
 | |
|       return this.options.filter(e => !this.filter || e[this.actionProp.label].indexOf(this.filter) > -1)
 | |
|     },
 | |
|     actionProp() {
 | |
|       return {
 | |
|         label: 'label',
 | |
|         value: 'id',
 | |
|         ...this.prop
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   methods: {
 | |
|     getOptions() {
 | |
|       this.instance?.post(this.action, null, {
 | |
|         params: {size: 999}
 | |
|       }).then(res => {
 | |
|         if (res?.data) {
 | |
|           this.options = res.data.records || res.data
 | |
|         }
 | |
|       })
 | |
|     }
 | |
|   },
 | |
|   created() {
 | |
|     this.getOptions()
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| :deep( .ai-select .el-select ) {
 | |
|   width: 100%;
 | |
| }
 | |
| </style>
 |