前言

这是一个非常基础的 组织树 前端项目,不需要搭建环境,只需要引入一个 vue 库即可,复制粘贴代码块到 TXT 文本另存为 html 双击打开就能用。

我是没想到这次考试内容居然是在 A4 纸上用水性笔手写出来一棵树并带有增删改查功能。1个半小时的考试时间,提示可以用任意框架,我就是个傻X非要钻牛角尖偏不使用成熟的框架、或者内置写好的组件,导致代码只写完了一部分,最后喜提50分,就差10分及格气死我了,所以考完试复盘写下了这个 Demo 顺便复习一下 CSS、JS。

功能

1.展示默认树内容;

2.鼠标悬浮选中树节点右键弹出菜单;

3.添加节点、删除节点、修改节点。

代码

先说个 BUG ,直接点 CSDN 复制代码会导致鼠标悬浮的 onmouseover Unicode 开头字符 &#111 变成 &#959 ,然后悬浮效果获取节点 ID 功能就失效了,点击复制后,务必手动替换一下 onmouseover,文章下方附有图片解释这个问题。
展示效果图放在最后面了,先上代码:

<!DOCTYPE html>
<html lang="">
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>menu</title><script src="./vue.min.js"></script>
</head>
<body>
<div id="app"><p>选择节点ID:{{hoverId}}&emsp;下一个ID:{{lastId}}</p><div class="box" @click.right="fnRightClick($event)" @click.left="fnLeftClick($event)"><div class="tree" v-html="treeHtml"></div></div><div class="menu" v-if="menuVisibleState" :style="{left: menuLeft,top: menuTop}"><div class="btn" @click="fnOpenCreate()"><span>新增</span></div><div class="btn" @click="fnOpenModify()"><span>修改</span></div><div class="btn" @click="fnDelete()"><span>删除</span></div></div><div class="wrapper" v-if="formVisibleState"><div class="dialog"><div class="form"><div><label for="name">组织名称:</label><input type="text" id="name" v-model="name"></div><div><label for="desc">组织描述:</label><textarea rows="10" id="desc" v-model="desc"></textarea></div><div class="btn-group"><button @click="fnCommit()">提交</button><button @click="fnCloseCreate()">取消</button></div></div></div></div>
</div>
</body>
<script>const app = new Vue({el: '#app',component: {},data: {id: '',name: '',desc: '',treeHtml: '',hoverId: '',lastId: 12,detail: {},menuLeft: 0,menuTop: 0,menuVisibleState: false,formVisibleState: false,orgDataList: [{id: 1, label: '1', desc: '',children: [{id: 4, label: '1-1', desc: '',children: [{id: 5, label: '1-1-1', desc: '', children: []}]},{id: 10, label: '1-2', desc: '',children: [{id: 11, label: '1-2-1', desc: '', children: []}]}]},{id: 2, label: '2', desc: '',children: [{id: 6, label: '2-1', desc: '',children: [{id: 7, label: '2-1-1', desc: '', children: []}]}]},{id: 3, label: '3', desc: '',children: [{id: 8, label: '3-1', desc: '',children: [{id: 9, label: '3-1-1', desc: '', children: []}]}]}],},mounted() {},method: {}});// 打开创建窗口function fnOpenCreate() {app.menuVisibleState = falseapp.formVisibleState = true}// 打开修改窗口function fnOpenModify() {app.menuVisibleState = falseapp.formVisibleState = truefnOperateNode(app.hoverId, [], app.orgDataList, 'detail')app.id = app.detail.idapp.name = app.detail.labelapp.desc = app.detail.descapp.children = app.detail.children}// 删除function fnDelete() {fnOperateNode(app.hoverId, [], app.orgDataList, 'delete')app.menuVisibleState = false}// 关闭创建窗口function fnCloseCreate() {app.formVisibleState = false}// 左键事件function fnLeftClick() {app.menuVisibleState = false}// 右键事件function fnRightClick(event) {event.preventDefault()let e = eventapp.menuLeft = e.clientX + "px"app.menuTop = e.clientY + "px"app.menuVisibleState = true}// 提交function fnCommit() {if (app.id) {let val = {id: app.id,label: app.name,desc: app.desc,children: app.children}fnOperateNode(app.id, val, app.orgDataList, 'modify')fnGeneratorTreeNode(app.orgDataList)app.id = ''} else {let val = {id: app.lastId,label: app.name,desc: app.desc,children: []}if (app.hoverId) {fnOperateNode(app.hoverId, val, app.orgDataList, 'create')} else {app.$set(app.orgDataList, app.orgDataList.length, val, 'create')fnGeneratorTreeNode(app.orgDataList)}app.lastId = app.lastId + 1}app.formVisibleState = falseapp.id = ''app.name = ''app.desc = ''app.children = []}// 查找、操作节点function fnOperateNode(id, val, dataList, type) {if (dataList && dataList.length) {for (let i = 0; i < dataList.length; i++) {if (dataList[i] && dataList[i].id == id) {if (type == 'create') {app.$set(dataList[i].children, dataList[i].children.length, val)fnGeneratorTreeNode(app.orgDataList)} else if (type == 'detail') {app.detail = dataList[i]} else if (type == 'modify') {dataList[i] = valfnGeneratorTreeNode(app.orgDataList)} else if (type == 'delete') {dataList.splice(i,1)console.log(app.orgDataList)fnGeneratorTreeNode(app.orgDataList)}} else if (dataList[i].children && dataList[i].children.length) {fnOperateNode(id, val, dataList[i].children, type)}}}}// 悬浮选中IDfunction fnSetHoverId(id) {app.hoverId = id}// 移除悬浮选中IDfunction fnUnsetHoverId() {app.hoverId = ''}// 生成根节点 htmlfunction fnGeneratorTreeNode(dataList) {app.treeHtml = ''dataList.forEach((item) => {if (item) {app.treeHtml += '<div class="node"><div class="content"><span οnmοuseοver="fnSetHoverId(' + item.id + ')">' + item.label + '</span>';if (item.children && item.children.length) {app.treeHtml += fnGeneratorLeafNode(item.children)}app.treeHtml += '</div></div>'}})}// 生成叶节点 htmlfunction fnGeneratorLeafNode(dataList) {let content = ''for (let i = 0; i < dataList.length; i++) {content += '<div class="node"><div class="content"><span οnmοuseοver="fnSetHoverId(' + dataList[i].id + ')">' + dataList[i].label + '</span>';if (dataList[i].children && dataList[i].children.length) {content += fnGeneratorLeafNode(dataList[i].children)}content += '</div></div>'}return content}fnGeneratorTreeNode(app.orgDataList)</script>
<style>* {padding: 0;margin: 0;}html, body {width: 100%;height: 100%;}ul {list-style: none;}#app {width: 100%;height: 100%;}.box {width: 100%;height: 100%;background-color: #ffffff;}.menu {width: 100px;height: auto;position: fixed;display: flex;flex-direction: column;align-items: center;justify-content: center;border: 1px solid #000000;border-radius: 5px;background-color: #ffffff;}.menu .btn {width: 80px;height: 20px;padding: 10px;text-align: center;}.menu .btn:hover {background-color: black;}.menu .btn:hover span {color: #ffffff;}.tree {padding: 50px;}.node {padding-left: 20px;width: 100%;height: 100%;cursor: pointer;}.wrapper {width: 100%;height: 100%;position: fixed;top: 0;right: 0;bottom: 0;left: 0;z-index: 1000;background-color: black;opacity: 0.7;text-align: center;}.dialog {width: 320px;height: 300px;z-index: 1001;background-color: #ffffff;display: inline-block;vertical-align: middle;text-align: left;}.wrapper:after {height: 100%;width: 0px;content: "";display: inline-block;text-align: center;vertical-align: middle;}.form {width: 100%;height: 100%;display: flex;flex-direction: column;justify-items: start;justify-content: left;padding: 20px;}.form input {width: 280px;line-height: 25px;margin-bottom: 10px;}.form textarea {width: 280px;}button {width: 50px;height: 30px;}label {font-size: 14px;}.btn-group {margin-bottom: -1px;}
</style>
</html>

展示效果

右键显示操作菜单

弹窗

直接复制代码导致鼠标悬浮事件失效


实现组织树和增删改查 国电南瑞前端考试题目相关推荐

  1. html+js+css 调用jquery 工人信息管理功能(增删改查)前端实现,以及调用实现鼠标拖尾粒子效果的js库

    html + js + css 调用jquery以及underscore.min.js(配合代码实现鼠标粒子效果)实现全前端信息管理基本功能(增删改查) 先附上我运行的一段视频,手机打开清晰一点或者直 ...

  2. jstree插件对树操作增删改查的使用

    1.插件说明 jstree官方地址:https://www.jstree.com bootstrap官方地址:https://v3.bootcss.com font-awesome官方地址:http: ...

  3. 实现ztree结合jquery的smartMenu.js插件对目录树的增删改查

    问题:项目上遇到一个问题,需要作出一个目录树显示相关内容的层级结构关系. 插件: 目录树插件,在这里我选用了ztree,十分方便好用(UI有待提升哈~)下方是ztree插件 需要的自取 ztree插件 ...

  4. b+树的增删改查_考研计算机 | 如何理解m阶B树?

    2021计算机考研:如何理解m阶B树?对m阶B树定义的理解一棵m阶的B树满足下列条件:1.每个结点至多有m棵子树.2.除根结点外,其它每个分支至少有m/2棵子树.3.根结点至少有两棵子树(除非B树只有 ...

  5. vue实现树形结构增删改查

    其实很多公司都会有类似于用户权限树的增删改查功能,正好最近我刚写了一个树形结构的增删改,在这里和大家分享一下,如果有不合理的地方欢迎评论,我会尽快优化~~ 先附上一下效果图 这个是没有点击编辑时,产品 ...

  6. SpringBoot+MyBatisPlus+Vue 前后端分离项目快速搭建【后端篇】【快速生成后端代码、封装结果集、增删改查、模糊查找】【毕设基础框架】

    前后端分离项目快速搭建[后端篇] 数据库准备 后端搭建 1.快速创建个SpringBoot项目 2.引入依赖 3.编写代码快速生成代码 4.运行代码生成器生成代码 5.编写application.pr ...

  7. 可编辑树Ztree的使用(包括对后台数据库的增删改查)

    找了很多网上关于Ztree的例子和代码才搞定. 首先,关于Ztree的代码不介绍了,网上下载之后,引用下列四个文件就能使用了. 1.关于配置选项.主要通过回调函数来实现向后台发送数据,实现增删改查. ...

  8. vue+element实现树状表格的增删改查;使用el-table树形数据与懒加载实现树状表格增删改查

    以下代码可以直接复制使用 一.情景: 列表是一个树状表格,可以无限添加下级,以及对列表的某一行进行增删改查(目前查没有写). 原博链接 二.本篇是在原博主的代码基础上添加了部分功能. 功能1: 给树状 ...

  9. MySQL知识盘点(增删改查)

    文章目录 一.Mysql数据库 1.1 概念 1.2 数据库的分类 二.数据库管理系统 2.1 概念 2.2 常见数据库管理系统 三.MySQL 3.1 简介 3.2 卸载 3.3 配置环境变量 3. ...

最新文章

  1. Android之四大组件概念讲解
  2. LCS2005客户端配置详解:LCS2005系列之二
  3. 大数据市场规模5年将达8000亿 交易平台忙圈地
  4. 让DB2数据库更牢靠
  5. javaweb关于用户是否登录全局判断,没有登录跳转到登录界面
  6. 我从未看过荒原写作背景_您从未听说过的最佳数据科学认证
  7. linux 64 32 编译支持,在64位linux上编译32位程序 for i386 intel
  8. 快速入门上手第一课 | 从云计算到 Serverless
  9. 基于mapreducer的图算法
  10. java连不上mysql_eclipse连接不上mysql
  11. C# 获取微信二维码
  12. 华为手机无法安装ADB和HDB的处理
  13. JZOJ 幽幽子与森林
  14. winscp 登录 am4379 的 linux系统 连接被意外关闭
  15. YOLOv3目标检测算法——通俗易懂的解析
  16. python中的变量不需要声明
  17. delphi Treeview用法
  18. python自动化通过邮件发送测试结果
  19. 如何有效预防XSS?这几招管用!!!
  20. java用scanner循环输入_Scanner怎么实现连续输入

热门文章

  1. 安卓图片加载框架Gilde的用法
  2. 读书笔记 - 《富甲美国》
  3. educoderpython答案计算机问题之递归_educoderpython答案计算机问题之递归第一关_Python练习题详解之递归(小白友好)......
  4. 详解Reflect:Reflect和Object的异同,Reflect的一些内置方法以及方法注意点
  5. 【题库】上海学校心理咨询-普通心理学-考点解析 5.2 记忆系统
  6. C语言 (atoi函数实现)
  7. python轻松入门——爬取豆瓣Top250时出现403报错(418报错,爬虫)
  8. Jenkins部署分支报Finished: UNSTABLE的问题解决
  9. Python将字典转换为csv
  10. linux macos命令一样吗,macos命令跟Linux命令有什么区别