zy-vue-library/components/view_tree/index.vue

70 lines
1.8 KiB
Vue

<template>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" class="mb-10" />
<el-tree
ref="treeRef"
:props="prop"
:node-key="nodeKey"
accordion
:data="data"
:filter-node-method="fnFilterNode"
:default-expanded-keys="[defaultExpandedKeys]"
@node-click="nodeClick"
/>
</template>
<script setup>
import { ref, watch, watchEffect } from "vue";
import { ElInput, ElTree } from "element-plus";
import "element-plus/es/components/input/style/css";
import "element-plus/es/components/tree/style/css";
defineOptions({
name: "AppViewTree",
});
const props = defineProps({
prop: {
type: Object,
default: () => ({ children: "children", label: "name" }),
},
nodeKey: { type: String, default: "id" },
defaultExpandedKeys: { type: String, default: "" },
api: { type: Function, required: true },
});
const emits = defineEmits(["node-click", "throw-data"]);
const refresh = defineModel("refresh", { type: Boolean, default: false });
const treeRef = ref(null);
const filterText = ref("");
const data = ref([]);
watch(filterText, (val) => {
treeRef.value.filter(val);
});
watchEffect(() => {
if (refresh.value) fnGetTreeData();
});
const fnFilterNode = (value, data) => {
if (!value) return true;
return data.name.includes(value);
};
const fnGetTreeData = async () => {
const value = await props.api();
fnAddLevel(value);
data.value = value;
emits("throw-data", value);
refresh.value = false;
};
fnGetTreeData();
const fnAddLevel = (value, level = 1) => {
value.forEach((item) => {
item.level = level;
if (item.children && item.children.length) {
fnAddLevel(item.children, level + 1);
}
});
};
const nodeClick = (data) => {
emits("node-click", data);
};
</script>
<style scoped lang="scss"></style>