在vue3中使用el-tree-select做一个树形下拉选择器

el-tree-select是一个含有下拉菜单的树形选择器,结合了 el-tree 和 el-select 两个组件的功能。

因为包含了el-tree的功能,我们可以自定义tree的节点,创造出想要的组件

使用default插槽可以自定义节点内容,它的default插槽相当于el-tree的default插槽

html 复制代码
<template>
    <el-tree-select
        v-model="dirCode"
        :data="treeData"
        :highlight-current="true"
        :props="defaultProps"
        clearable
        filterable
        node-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()方法

javascript 复制代码
<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.pathCode
    dirPath.value = data.dirPath
    emits('change', {
        dirPath: dirPath.value,
        dirCode: dirCode.value
    })
}

const handleClear = () => {
    dirCode.value = ''
    dirPath.value = ''
    emits('change', {
        dirPath: dirPath.value,
        dirCode: dirCode.value
    })
}

</script>

这是我的自定义样式,用的scss

html 复制代码
<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>

最后是效果图

相关推荐
前端_学习之路35 分钟前
React--Fiber 架构
前端·react.js·架构
coderlin_37 分钟前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
伍哥的传说1 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409191 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app
我在北京coding1 小时前
element el-table渲染二维对象数组
前端·javascript·vue.js
布兰妮甜1 小时前
Vue+ElementUI聊天室开发指南
前端·javascript·vue.js·elementui
SevgiliD1 小时前
el-button传入icon用法可能会出现的问题
前端·javascript·vue.js
我在北京coding1 小时前
Element-Plus-全局自动引入图标组件,无需每次import
前端·javascript·vue.js
鱼 空1 小时前
解决el-table右下角被挡住部分
javascript·vue.js·elementui
柚子8161 小时前
scroll-marker轮播组件不再难
前端·css