el-tree-select是一个含有下拉菜单的树形选择器,结合了 el-tree 和 el-select 两个组件的功能。
因为包含了el-tree的功能,我们可以自定义tree的节点,创造出想要的组件
使用default插槽可以自定义节点内容,它的default插槽相当于el-tree的default插槽
<template><el-tree-selectv-model="dirCode":data="treeData":highlight-current="true":props="defaultProps"clearablefilterablenode-key="pathCode":placeholder="placeholder"@clear="handleClear"><template #default="{ node, data }"><div class="custom-tree-node" @click="data.pathCode !== '-1' ? handleNodeClick(data) : ''"><div class="tree-icon"><!-- 这里的svg-icon是我自己加的,可以改成element-plus中的icon ----><svg-icon class="file" icon-class="file"></svg-icon></div><div class="tree-label one-line"><span class="tree-label-text one-line">{{ node.label }}</span></div></div></template></el-tree-select>
</template>
使用:model-value="modelValue"可以在适合用组件时直接v-model绑定值
我这里使用的是setup式的语法,当然也可以使用setup()方法
<script setup>
import { ref, reactive, watch, onMounted } from 'vue'
import { getDirectory } from 'api/autoOperations/scriptManage'const props = defineProps({placeholder: {type: String,default: '请选择目录',required: false},code: {type: String,default: '',required: false},path: {type: String,default: '',required: false}
})let dirCode = ref('')
let dirPath = ref('')
const treeData = ref([])const emits = defineEmits(['change'])// 树状图默认配置
const defaultProps = reactive({children: 'children',label: 'pathName',isLeaf(data, node) {return data.isLeaf == 'true'}
})watch(() => props.code, (val) => {if (val) {dirCode.value = val}
}, {immediate: true,deep: true
})
watch(() => props.path, (val) => {if (val) {dirPath.value = val}
}, {immediate: true,deep: true
})onMounted(() => {getTreeData()
})// 这里从数据库获取数据
const getTreeData = () => {}const handleNodeClick = (data) => {dirCode.value = data.pathCodedirPath.value = data.dirPathemits('change', {dirPath: dirPath.value,dirCode: dirCode.value})
}const handleClear = () => {dirCode.value = ''dirPath.value = ''emits('change', {dirPath: dirPath.value,dirCode: dirCode.value})
}</script>
这是我的自定义样式,用的scss
<style lang="scss" scoped>
.custom-tree-node {display: flex;justify-content: space-between;align-items: center;width: calc(100% - 24px);font-size: 12px;line-height: 24px;.tree-icon {width: 20px;display: flex;align-items: center;.file {width: 20px;font-size: 20px;vertical-align: text-bottom;}}.tree-label {width: 100%;height: 24px;line-height: 24px;.tree-label-text {display: inline-block;max-width: calc(100% - 30px);}}
}
</style>
最后是效果图