70 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			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>
 |