123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <template>
- <el-select v-model="proxyValue"
- class="basic-select-tree"
- ref="selectTreeInputRef"
- :clearable="clearable"
- :placeholder="placeholder"
- :disabled="disabled"
- :style="{width}"
- @clear="clearValue"
- popper-class="basic-select-tree-popper">
- <el-option :label="selectOption.label" :value="selectOption.value">
- <el-tree class="select-tree-option"
- :key="optionProps.value"
- ref="selectTreeRef"
- :data="options"
- :props="optionProps"
- :node-key="optionProps.value"
- :default-expanded-keys="defaultExpandedKeys"
- :current-node-key="modelValue"
- :expand-on-click-node="false"
- @node-click="handleNodeClick">
- </el-tree>
- </el-option>
- </el-select>
- </template>
- <script>
- import { ElSelect, ElOption, ElTree } from 'element-plus'
- import { ref, watchEffect } from 'vue'
- import { useFormInput, useOptions } from '@cip/components/hooks/form-input'
- import { formInputProps, fromInputEmits } from '../../form-input-props'
- import { isArray, isNumber } from '@cip/utils/util'
- export default {
- components: { ElSelect, ElOption, ElTree },
- props: formInputProps,
- emits: [...fromInputEmits],
- setup (props, context) {
- const { width, updateStream, proxyValue, securityConfig, emitModelValue, emitOtherValue, ...formInput } = useFormInput(props, context)
- const { options, optionProps } = useOptions(props, false, updateStream)
- const defaultExpandedKeys = ref([])
- const selectOption = ref({ label: '', value: '' })
- const selectTreeInputRef = ref()
- const selectTreeRef = ref()
- // WARN: 移除了对securityConfig.value.treeProps的支持
- // tree组件配置
- // const treeProps = computed(() => {
- // return Object.assign({}, defaultProps, securityConfig.value?.treeProps, securityConfig.value?.optionProps)
- // })
- const formatOption = (data) => {
- const option = {}
- const keys = optionProps.value
- option.label = data[keys.label]
- option.value = data[keys.value]
- option.children = data[keys.children]
- return option
- }
- const findActiveOption = (treeData = []) => {
- const modelValue = props.modelValue
- for (let i = 0; i < treeData.length; i++) {
- const option = formatOption(treeData[i])
- if (option.value === modelValue) {
- selectOption.value = option
- return true
- }
- if (option.children?.length > 0) {
- const result = findActiveOption(option.children, modelValue)
- if (result) {
- defaultExpandedKeys.value.push(option.value)
- return result
- }
- }
- }
- }
- watchEffect(() => {
- const treeData = options.value
- defaultExpandedKeys.value = []
- findActiveOption(treeData)
- })
- // 切换选项
- const handleNodeClick = (data, node, treeInstance) => {
- const { isLeaf, level } = node
- // selectLevel是配置可选中层级,配置时注意需要配置成number类型
- if (securityConfig.value.selectLevel) {
- if (isNumber(securityConfig.value.selectLevel) && securityConfig.value.selectLevel !== level) return
- if (isArray(securityConfig.value.selectLevel) && !securityConfig.value.selectLevel.includes(level)) return
- }
- if (!securityConfig.value.leafOnly || (securityConfig.value.leafOnly && isLeaf)) {
- selectOption.value.label = data[optionProps.value.label]
- selectOption.value.value = data[optionProps.value.value]
- updateStream.appendValue(selectOption.value.value)
- updateStream.appendOtherValue(selectOption.value.label)
- updateStream.end()
- defaultExpandedKeys.value = []
- // 选中时收回下拉框
- selectTreeInputRef.value.blur()
- } else {
- selectTreeRef.value.setCurrentKey(props.modelValue)
- }
- }
- const clearValue = () => {
- updateStream.appendValue(undefined)
- updateStream.appendOtherValue(undefined)
- updateStream.end()
- }
- return {
- ...formInput,
- proxyValue,
- selectTreeInputRef,
- options,
- defaultExpandedKeys,
- width,
- selectTreeRef,
- optionProps,
- handleNodeClick,
- selectOption,
- clearValue
- }
- }
- }
- </script>
- <style lang="less" scope>
- .basic-select-tree{
- width: 100%;
- }
- .basic-select-tree-popper{
- .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;
- }
- .el-tree-node__label{
- font-weight: normal;
- }
- }
- .select-tree-option {
- .el-tree-node__content{
- height: 32px;
- padding: 0 20px;
- }
- .is-current>.el-tree-node__content .el-tree-node__label{
- color: #409EFF;
- }
- }
- </style>
|