【Vue】-组件开发-一个树组件

我们来自己搞一个树组件

1. 创建 Vue 项目

如果你还没有创建 Vue 项目,可以使用 Vue CLI 快速创建:

vue create my-tree-component
cd my-tree-component

2. 安装依赖

确保安装了 Vue Router 和 Vuex(如果需要状态管理):

npm install vue-router vuex --save

3. 创建 Tree 组件

src/components 目录下创建 Tree.vue 文件:

<template><div class="tree"><ul><tree-node v-for="node in data" :key="node.id" :node="node"></tree-node></ul></div>
</template><script>
import TreeNode from './TreeNode.vue';export default {name: 'Tree',components: {TreeNode},props: {data: {type: Array,required: true}}
};
</script><style scoped>
.tree ul {list-style-type: none;padding-left: 20px;
}
</style>

4. 创建 TreeNode 组件

src/components 目录下创建 TreeNode.vue 文件:

<template><li><span @click="toggle">{{ node.name }}</span><ul v-if="isOpen"><tree-node v-for="child in node.children" :key="child.id" :node="child"></tree-node></ul></li>
</template><script>
export default {name: 'TreeNode',props: {node: {type: Object,required: true}},data() {return {isOpen: false};},methods: {toggle() {this.isOpen = !this.isOpen;}}
};
</script><style scoped>
li {cursor: pointer;
}
</style>

5. 使用 Tree 组件

src/App.vue 中使用 Tree 组件:

<template><div id="app"><tree :data="treeData"></tree></div>
</template><script>
import Tree from './components/Tree.vue';export default {name: 'App',components: {Tree},data() {return {treeData: [{id: 1,name: 'Node 1',children: [{ id: 2, name: 'Child Node 1' },{ id: 3, name: 'Child Node 2' }]},{id: 4,name: 'Node 2',children: [{ id: 5, name: 'Child Node 3' }]}]};}
};
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>

6. 运行项目

运行项目以查看效果:

npm run serve

7. 功能扩展

  • 搜索功能:添加一个搜索框,根据输入过滤树节点。
  • 拖拽排序:使用第三方库如 vuedraggable 实现节点的拖拽排序。
  • 懒加载:对于大型树结构,可以实现懒加载,仅在展开节点时加载子节点数据。

功能扩展的实现

1. 搜索功能

修改 Tree.vue 组件

Tree.vue 中添加一个搜索框,并根据输入过滤树节点。

<template><div class="tree"><input type="text" v-model="searchQuery" placeholder="Search..." /><ul><tree-node v-for="node in filteredData" :key="node.id" :node="node"></tree-node></ul></div>
</template><script>
import TreeNode from './TreeNode.vue';
import { filterTree } from '@/utils/treeUtils';export default {name: 'Tree',components: {TreeNode},props: {data: {type: Array,required: true}},data() {return {searchQuery: ''};},computed: {filteredData() {if (!this.searchQuery) return this.data;return filterTree(this.data, this.searchQuery);}}
};
</script><style scoped>
.tree ul {list-style-type: none;padding-left: 20px;
}
</style>
创建 treeUtils.js 工具文件

src/utils 目录下创建 treeUtils.js 文件,用于实现树节点的过滤功能。

export function filterTree(data, query) {const lowerCaseQuery = query.toLowerCase();return data.filter(node => {if (node.name.toLowerCase().includes(lowerCaseQuery)) {return true;}if (node.children && node.children.length > 0) {node.children = filterTree(node.children, query);return node.children.length > 0;}return false;});
}

2. 拖拽排序

安装 vuedraggable

首先,安装 vuedraggable 库:

npm install vuedraggable
修改 Tree.vue 组件

Tree.vue 中引入 vuedraggable 并使用它来实现拖拽排序。

<template><div class="tree"><input type="text" v-model="searchQuery" placeholder="Search..." /><draggable v-model="filteredData" @change="onDragChange"><tree-node v-for="node in filteredData" :key="node.id" :node="node"></tree-node></draggable></div>
</template><script>
import TreeNode from './TreeNode.vue';
import draggable from 'vuedraggable';
import { filterTree } from '@/utils/treeUtils';export default {name: 'Tree',components: {TreeNode,draggable},props: {data: {type: Array,required: true}},data() {return {searchQuery: '',localData: [...this.data]};},computed: {filteredData: {get() {if (!this.searchQuery) return this.localData;return filterTree(this.localData, this.searchQuery);},set(value) {this.localData = value;}}},methods: {onDragChange(event) {console.log('Drag change:', event);// 处理拖拽后的变化,例如更新父组件的数据this.$emit('update:data', this.localData);}}
};
</script><style scoped>
.tree ul {list-style-type: none;padding-left: 20px;
}
</style>

3. 懒加载

修改 TreeNode.vue 组件

TreeNode.vue 中实现懒加载功能。

<template><li><span @click="toggle">{{ node.name }}</span><ul v-if="isOpen"><draggable v-model="node.children" @change="onDragChange"><tree-node v-for="child in node.children" :key="child.id" :node="child"></tree-node></draggable></ul></li>
</template><script>
import draggable from 'vuedraggable';export default {name: 'TreeNode',components: {draggable},props: {node: {type: Object,required: true}},data() {return {isOpen: false,hasLoadedChildren: false};},methods: {toggle() {if (!this.hasLoadedChildren && this.node.children && this.node.children.length === 0) {this.loadChildren();}this.isOpen = !this.isOpen;},loadChildren() {// 模拟异步加载子节点setTimeout(() => {this.node.children = [{ id: 101, name: 'Lazy Child 1' },{ id: 102, name: 'Lazy Child 2' }];this.hasLoadedChildren = true;}, 1000);},onDragChange(event) {console.log('Drag change:', event);// 处理拖拽后的变化,例如更新父组件的数据this.$emit('update:node', { ...this.node, children: this.node.children });}}
};
</script><style scoped>
li {cursor: pointer;
}
</style>

4. 更新 App.vue

确保 App.vue 中的 Tree 组件能够接收和处理数据更新。

<template><div id="app"><tree :data="treeData" @update:data="updateTreeData"></tree></div>
</template><script>
import Tree from './components/Tree.vue';export default {name: 'App',components: {Tree},data() {return {treeData: [{id: 1,name: 'Node 1',children: [{ id: 2, name: 'Child Node 1' },{ id: 3, name: 'Child Node 2' }]},{id: 4,name: 'Node 2',children: [{ id: 5, name: 'Child Node 3' }]}]};},methods: {updateTreeData(newData) {this.treeData = newData;}}
};
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>

5. 运行项目

运行项目以查看效果:

npm run serve

基本的功能就都具备了,当然实际生产中可能会碰到各种新的需求,慢慢来扩展即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/60128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

昇思大模型平台打卡体验活动:项目1基于MindSpore实现BERT对话情绪识别

基于MindSpore实现BERT对话情绪识别 1. 模型简介 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是由Google于2018年末开发并发布的一种新型语言模型&#xff0c;基于Transformer架构中的Encoder&#xff0c;并且具有双向编码的特性。…

vue+Springboot实现简单文件上传到本地

实现效果 点击上传文件按钮后&#xff0c;选择需要上传的文件&#xff0c;如果是图片的话&#xff0c;上传成功后可以直接在下面预览。 前端页面 <template><div class"file-upload"><el-upload:headers"getUploadConfig(token).headers"…

云原生周刊:Istio 1.24.0 正式发布

云原生周刊&#xff1a;Istio 1.24.0 正式发布 开源项目推荐 Kopf Kopf 是一个简洁高效的 Python 框架&#xff0c;只需几行代码即可编写 Kubernetes Operator。Kubernetes&#xff08;K8s&#xff09;作为强大的容器编排系统&#xff0c;虽自带命令行工具&#xff08;kubec…

使用 Spring Boot 进行加密和解密:SecretKeySpec 和 Cipher

在现代软件开发中&#xff0c;数据加密和解密是保护敏感信息的重要手段。本文将介绍如何在 Spring Boot 项目中使用 Java 的 SecretKeySpec 和 Cipher 类来实现对称加密和解密。 为什么选择对称加密&#xff1f; 对称加密算法使用相同的密钥进行加密和解密。其主要优点包括速…

解决 Vue3、Vite 和 TypeScript 开发环境下跨域的问题,实现前后端数据传递

引言 本文介绍如何在开发环境下解决 Vite 前端&#xff08;端口 3000&#xff09;和后端&#xff08;端口 80&#xff09;之间的跨域问题&#xff1a; 在开发环境中&#xff0c;前端使用的 Vite 端口与后端端口不一致&#xff0c;会产生跨域错误提示&#xff1a; Access to X…

Java项目实战II基于微信小程序的订餐系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导 一、前言 随着移动互联网技术的飞速发展&#xff0…

闯关leetcode——202. Happy Number

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/happy-number/description/ 内容 Write an algorithm to determine if a number n is happy. A happy number is a number defined by the following process: Starting with any positive inte…

toRef,toRefs,toRaw

假设有一个响应式对象 state&#xff0c;我们只想独立地访问和修改其中的某个属性&#xff0c;比如 count&#xff1a; toRef import { reactive, toRef } from vue;// 创建一个响应式对象 const state reactive({count: 0,message: "Hello Vue 3" });// 使用 toR…

昇思大模型平台打卡体验活动:项目4基于MindSpore实现Roberta模型Prompt Tuning

基于MindNLP的Roberta模型Prompt Tuning 本文档介绍了如何基于MindNLP进行Roberta模型的Prompt Tuning&#xff0c;主要用于GLUE基准数据集的微调。本文提供了完整的代码示例以及详细的步骤说明&#xff0c;便于理解和复现实验。 环境配置 在运行此代码前&#xff0c;请确保…

中国药品注册审批数据库- 药品注册信息查询与审评进度查询方法

药品的注册、审评审批进度信息是医药研发相关人员每天都会关注的信息&#xff0c;为了保证药品注册申请受理及审评审批进度信息的公开透明&#xff0c;CDE药审中心提供药品不同注册分类序列及药品注册申请受理的审评审批进度信息查询服务。但因CDE官网的改版导致很大一部分人不…

FMC 扩展子卡6 路 422,8 组 LVDS,8 路 GPIO

FMC 扩展子卡6 路 422,8 组 LVDS,8 路 GPIO 卡是一款支持多路 LVCMOS 和 LVDS 信号互转的 FMC 扩展子板。它能支持 6 路 422 信号的输入 / 输出 ,8 组 LVDS 信号的输入 / 输出和 8 路 GPIO 信号的输入 / 输出。本产品基于一些逻辑转换芯片而设计&#xff0c;能实现差分信号转单…

项目管理-招标文书都有哪些文件且各自作用

招标文书是招标过程中使用的一系列文件&#xff0c;它们定义了招标的条件、规则、程序和要求。 以下是一些常见的招标文书及其作用&#xff1a; 1. 招标公告/招标邀请书&#xff1a; - 作用&#xff1a;公开告知潜在的投标者有关招标项目的相关信息&#xff0c;包括项目…

C++builder中的人工智能(21):Barabási–Albert model(BA)模型

在此之前&#xff0c;大多数网络被想当然的认为是随机的&#xff0c;因此连接度分布可以近似用泊松分布来表示&#xff0c;而巴拉巴西与其学生阿尔伯特、郑浩雄通过对万维网度分布测量的结果却显示万维网度分布服从幂律分布&#xff0c;存在枢纽节点&#xff08;拥有大量链接的…

MyBatis3-获取参数值的方式、查询功能及特殊SQL执行

目录 准备工作 获取参数值的方式&#xff08;重点&#xff09; 查询功能 查询一个实体类对象 查询一个list集合 查询单个数据 查询一条数据为map集合 查询多条数据为map集合 特殊SQL执行 模糊查询 批量删除 动态设置表名 添加功能获取自增的主键 准备工作 模块My…

链表(Linkedlist)

序言 我们都了解链表是一种数据的存储结构&#xff0c;在Java使用中逻辑与c&#xff0c;c语言数据结构别无二致&#xff0c;但主要由于Java中不存在指针的说法&#xff0c;从而导致在实现过程中的代码不同&#xff0c;所以在学习的过程中我们无需过于担心&#xff0c;逻辑都是…

jupyter添加、删除、查看内核

以下操作均在pytorch环境中操作 1.检查是否有ipykernel python -m ipykernel --version2.没有就安装 python -m pip install ipykernel3.查看内核环境列表 jupyter kernelspec list4.添加内核 python -m ipykernel install --user --name 环境名称 --display-name "在…

【分布式事务】二、NET8分布式事务实践: DotNetCore.CAP 框架 、 消息队列(RabbitMQ)、 多类型数据库(MySql、MongoDB)

介绍 DotNetCore.CAP简称CAP, [CAP]是一个用来解决微服务或者分布式系统中分布式事务问题的一个开源项目解决方案, 同样可以用来作为 EventBus 使用,CAP 拥有自己的特色,它不要求使用者发送消息或者处理消息的时候实现或者继承任何接口,拥有非常高的灵活性。我们一直坚信…

利用pythonstudio写的PDF、图片批量水印生成器,可同时为不同读者生成多组水印

现在很多场合需要将PDF或图片加水印&#xff0c;本程序利用pythonstudio编写。 第一步 界面 其中&#xff1a; LstMask:列表框 PopupMenu:PmnMark LstFiles:列表框 PopupMenu:PmnFiles OdFiles:文件选择器 Filter:PDF文件(.PDF)|.PDF|图像文件(.JPG)|.JPG|图像文件(.png…

面试:TCP、UDP如何解决丢包问题

文章目录 一、TCP丢包原因、解决办法1.1 TCP为什么会丢包1.2 TCP传输协议如何解决丢包问题1.3 其他丢包情况&#xff08;拓展&#xff09;1.4 补充1.4.1 TCP端口号1.4.2 多个TCP请求的逻辑1.4.3 处理大量TCP连接请求的方法1.4.4 总结 二、UDP丢包2.1 UDP协议2.1.1 UDP简介2.1.2…

Python的函数(补充浅拷贝和深拷贝)

一、定义 函数的定义&#xff1a;实现【特定功能】的代码块。 形参&#xff1a;函数定义时的参数&#xff0c;没有实际意义 实参&#xff1a;函数调用/使用时的参数&#xff0c;有实际意义 函数的作用&#xff1a; 简化代码提高代码重用性便于维护和修改提高代码的可扩展性…