vue实现自定义树形组件

欢迎点击关注-前端面试进阶指南:前端登顶之巅-最全面的前端知识点梳理总结

*分享一个使用比较久的🪜

效果展示:

在这里插入图片描述

近期的一个功能需求,实现一个树形结构:可点击,可拖拽,右侧数据可以拖拽到对应的节点内,可创建文件夹、可创建文件、编辑文件名、可删除等等;

渲染列表数据的时候,列表的子项还是列表。针对多层级的列表,我们采用tree的方式,从根节点一次创建绑定子节点的方式,可以递归式的调用本身,对我们的树形结构进行展示;并且支持多余的树形拓展;

代码区域

1、创建TreeList文件夹,其中创建:fonts文件夹、index.js文件、tools.js文件、Tree.js文件、VueTreeList.vue文件;
2、fonts文件夹主要用来存放icon图标的,这里就不展示了,依据项目在阿里矢量图标内新增,然后在VueTreeList.vue内进行替换

使用

源代码地址

 <vue-tree-listref="VueTreeList":model="treeData" // 初识数据源,treeData: new Tree([]),:activeId="activeId" // 选中的id及背景色default-leaf-node-name="新建文件" // 默认创建文件名称default-tree-node-name="新建目录" // 默认创建文件夹名称:default-expanded="isExpanded" // 默认是否展开文件夹@click="handleOnClick" // 点击当前节点@moveGraph="moveGraph" // 右侧数据拖拽至当前节点触发,可删除不使用@add-node="handleOnAddNode" // 点击创建节点@end-edit="handleOnChangeNameEnd" // 点击编辑当前节点的名称@delete-node="deleteNode" // 点击删除当前节点@drop="handleDrop" // 拖拽上下节点我已注释掉,依据需求自身放开@drop-before="hadnleDropBefore" // 开始拖拽之前的触发函数@drop-after="handleDropAfter" // 结束拖拽完之后的触发函数loadDataApi="/api/tree-dir" // 点击左侧icon,触发远程加载填充子数据Api接口
>
</vue-tree-list>
1.1 创建index.js文件,也是往外暴露的入口文件;(文章并未按照思路排序)
/*** Created by ayou on 17/7/21.*/import VueTreeList from './VueTreeList'
import { Tree, TreeNode } from './Tree'VueTreeList.install = Vue => {Vue.component(VueTreeList.name, VueTreeList)
}export default VueTreeListexport { Tree, TreeNode, VueTreeList }
1.2 创建tools.js文件;
/*** Created by ayou on 18/2/6.*/var handlerCacheexport const addHandler = function(element, type, handler) {handlerCache = handlerif (element.addEventListener) {element.addEventListener(type, handler, false)} else if (element.attachEvent) {element.attachEvent('on' + type, handler)} else {element['on' + type] = handler}
}export const removeHandler = function(element, type) {if (element.removeEventListener) {element.removeEventListener(type, handlerCache, false)} else if (element.detachEvent) {element.detachEvent('on' + type, handlerCache)} else {element['on' + type] = null}
}// depth first search
export const traverseTree = (root) => {const { children, parent, ...newRoot } = root;if (children && children.length > 0) {newRoot.children = children.map(traverseTree);}return newRoot;
};
1.2 创建Tree.js文件;
import { traverseTree } from './tools'export class TreeNode {constructor(data) {const { id, isLeaf, editNode } = datathis.id = typeof id !== 'undefined' ? id : Math.floor(new Date().valueOf() * (Math.random() + 1))this.parent = nullthis.children = nullthis.isLeaf = !!isLeafthis.editNode = editNode || falsefor (const key in data) {if (key !== 'id' && key !== 'children' && key !== 'isLeaf') {this[key] = data[key]}}}changeName(name) {this.name = name}changeNodeId(id) {this.id = id}addChildren(children) {if (!this.children) {this.children = []}if (Array.isArray(children)) {children.forEach(child => {child.parent = thischild.pid = this.id})this.children.push(...children)} else {const child = childrenchild.parent = thischild.pid = this.idthis.children.push(child)}}// remove selfremove() {const parent = this.parentconst index = parent.children.findIndex(child => child === this)parent.children.splice(index, 1)}// remove child_removeChild(child, bool) {const index = this.children.findIndex(c => bool ? c.id === child.id : c === child)if (index !== -1) {this.children.splice(index, 1)}}isTargetChild(target) {let parent = target.parentwhile (parent) {if (parent === this) {return true}parent = parent.parent}return false}moveInto(target) {if (this.name === 'root' || this === target) {return}if (this.isTargetChild(target)) {return}if (target.isLeaf) {return}this.parent.removeChild(this)this.parent = targetthis.pid = target.idif (!target.children) {target.children = []}target.children.unshift(this)}findChildIndex(child) {return this.children.findIndex(c => c === child)}_canInsert(target) {if (this.name === 'root' || this === target) {return false}if (this.isTargetChild(target)) {return false}this.parent.removeChild(this)this.parent = target.parentthis.pid = target.parent.idreturn true}insertBefore(target) {if (!this._canInsert(target)) returnconst pos = target.parent.findChildIndex(target)target.parent.children.splice(pos, 0, this)}insertAfter(target) {if (!this._canInsert(target)) returnconst pos = target.parent.findChildIndex(target)target.parent.children.splice(pos + 1, 0, this)}toString() {return JSON.stringify(traverseTree(this))}
}export class Tree {constructor(data) {this.root = new TreeNode({ name: 'root', isLeaf: false, id: 0 })this.initNode(this.root, data)return this.root}initNode(node, data) {data.forEach(_data => {const child = new TreeNode(_data)if (_data.children && _data.children.length > 0) {this.initNode(child, _data.children)}node.addChildren(child)})}
}
1.3 创建VueTreeList.vue文件;

说明:支持点击创建远程数据,loadDataAjax方法,需要自己研究功能小编已实现;现有代码基本功能已经完善,需要依赖自己的项目进行变更和更改;treeNode可以直接访问和修改数据源的,需要读者自己发掘;

<template><div :class="['vtl', isMobile && 'isMobile']"><divv-if="model.name !== 'root'":id="model.id"class="vtl-node":class="{ 'vtl-leaf-node': model.isLeaf, 'vtl-tree-node': !model.isLeaf }"><div class="vtl-border vtl-up" :class="{ 'vtl-active': isDragEnterUp }" /><div:class="['vtl-node-main', { 'vtl-active': isDragEnterNode }]":style="{ fontSize: '10px' }"@drop="drop"@mouseover="mouseOver"@mouseout="mouseOut"@click.stop="handleCurClick"@dragover="dragOver"@dragenter="dragEnter"@dragleave="dragLeave"><spanv-if="!model.children"class="vtl-caret vtl-is-small"><iclass="vtl-icon"style="cursor: pointer; width: 11px;"></i></span><spanv-if="model.children"class="vtl-caret vtl-is-small"><iclass="vtl-icon":class="caretClass"style="cursor: pointer"@click.prevent.stop="toggle"></i><iv-if="isRemoteLoading"class="Custom_demo-spin-icon-load ivu-icon ivu-icon-ios-loading"style="font-size: 16px; margin-right: 3px; margin-top: -2px"></i></span><span v-if="model.isLeaf"><slotname="leafNodeIcon":expanded="expanded":model="model":root="rootNode"><istyle="cursor: pointer"class="vtl-icon vtl-menu-icon vtl-icon-file"></i></slot></span><span v-else><slotname="treeNodeIcon":expanded="expanded":model="model":root="rootNode"><imgclass="custom_img"style="width:15px;margin-right: 3px"src="../../../static/img/folder.png"alt=""/></slot></span><divv-if="!editable":class="['vtl-node-content',isShowClickBackg,{ custom_class_hiddle: isHover, custom_class_click: model.isLeaf }]":style="{color: model.matched ? '#D9262C' : null,cursor: 'pointer'}"><slotname="leafNameDisplay":expanded="expanded":model="model":root="rootNode">{{ model.name }}</slot></div><inputv-if="editable || handleInitEditable(model)"class="vtl-input"type="text"ref="nodeInput":value="model.name"@input="updateName"@blur="setUnEditable"@keyup.enter="setUnEditable"/><div class="vtl-operation" v-show="isHover"><!-- 新增设备 --><spantitle="新增设备"v-btn-key="rolespermiss.addDevice"@click.stop.prevent="createChild"v-if="(!model.isDevice || model.isDir === false) &&$route.path != '/autoMonitorBoard'"><slotname="addLeafNodeIcon":expanded="expanded":model="model":root="rootNode"><i class="vtl-icon vtl-icon-plus"></i></slot></span><!-- 编辑名称 --><spantitle="编辑名称"v-btn-key="rolespermiss.editFolder"@click.stop.prevent="setEditable(true)"v-if="!model.editNodeDisabled &&!model.isDevice &&$route.path != '/autoMonitorBoard'"><slotname="editNodeIcon":expanded="expanded":model="model":root="rootNode"><i class="vtl-icon vtl-icon-edit"></i></slot></span><!-- 删除节点 --><spantitle="删除节点"@click.stop.prevent="delNode"style="line-height: 14px;"v-if="$route.path != '/autoMonitorBoard'"v-btn-key="rolespermiss.deleteFolder"><slotname="delNodeIcon":expanded="expanded":model="model":root="rootNode"><i class="vtl-icon vtl-icon-trash"></i></slot></span><!-- 创建子目录 --><span:title="defaultAddTreeNodeTitle"@click.stop.prevent="addChild(false)"v-btn-key="rolespermiss.createFolder"v-if="!model.addTreeNodeDisabled &&!model.isLeaf &&!model.isDevice &&$route.path != '/autoMonitorBoard'"><slotname="addTreeNodeIcon":expanded="expanded":model="model":root="rootNode"><i class="vtl-icon vtl-icon-folder-plus-e"></i></slot></span><!-- 详情按钮 --><spantitle="设备详情"style="margin-top: -1px"@click.stop="handleViewDetail"v-btn-key="rolespermiss.folderDetail"v-if="!model.addTreeNodeDisabled && model.isLeaf && !model.isDevice"><Icon style="color: #d9262c" type="ios-paper-outline" /></span></div></div><divv-if="model.children &&model.children.length > 0 &&(expanded || model.expanded)"class="vtl-border vtl-bottom":class="{ 'vtl-active': isDragEnterBottom }"></div></div><div:class="{ 'vtl-tree-margin': model.name !== 'root' }"v-if="isFolder && (model.name === 'root' || expanded || model.expanded)"><item:model="model":title="model.name"v-for="model in model.children":key="model.id":activeId="activeId":loadDataApi="loadDataApi":rolespermiss="rolespermiss":requestHeader="requestHeader":default-tree-node-name="defaultTreeNodeName":default-leaf-node-name="defaultLeafNodeName":default-expanded="defaultExpanded"><template v-slot:leafNameDisplay="slotProps"><slot name="leafNameDisplay" v-bind="slotProps" /></template><template v-slot:addTreeNodeIcon="slotProps"><slot name="addTreeNodeIcon" v-bind="slotProps" /></template><template v-slot:addLeafNodeIcon="slotProps"><slot name="addLeafNodeIcon" v-bind="slotProps" /></template><template v-slot:editNodeIcon="slotProps"><slot name="editNodeIcon" v-bind="slotProps" /></template><template v-slot:delNodeIcon="slotProps"><slot name="delNodeIcon" v-bind="slotProps" /></template><template v-slot:leafNodeIcon="slotProps"><slot name="leafNodeIcon" v-bind="slotProps" /></template><template v-slot:treeNodeIcon="slotProps"><slot name="treeNodeIcon" v-bind="slotProps" /></template></item></div></div>
</template><script>
import { request } from "@/axios/index";
import { TreeNode } from "./Tree.js";
import { removeHandler } from "./tools.js";
import { isShowMobile } from "@/storage/storeutil";let compInOperation = null;export default {name: "vue-tree-list",props: {model: {type: Object},activeId: Number,rolespermiss: Object,loadDataApi: String,requestHeader: Object,defaultLeafNodeName: {type: String,default: "新建"},defaultTreeNodeName: {type: String,default: "新建"},defaultAddTreeNodeTitle: {type: String,default: "新建"},defaultExpanded: {type: Boolean,default: true}},data() {return {isHover: false,editable: false,isDragEnterUp: false,isDragEnterBottom: false,isDragEnterNode: false,isRemoteLoading: false,expanded: this.defaultExpanded,clickEditIcon: false};},computed: {rootNode() {var node = this.$parent;while (node._props.model.name !== "root") {node = node.$parent;}return node;},caretClass() {return this.model.expanded? "vtl-icon-caret-down": this.expanded? "vtl-icon-caret-down": "vtl-icon-caret-right";},isFolder() {return this.model.children && this.model.children.length;},isShowClickBackg() {const {model: { id }} = this;return { activeItem: id === this.activeId };},isMobile() {return isShowMobile();}// treeNodeClass() {//   const {//     model: { dragDisabled, disabled },//   } = this;//   return {//     "vtl-drag-disabled": dragDisabled,//     "vtl-disabled": disabled,//   };// },},methods: {updateName(e) {var oldName = this.model.name;this.model.changeName(e.target.value);this.rootNode.$emit("change-name", {id: this.model.id,oldName: oldName,newName: e.target.value,node: this.model});},// 点击左侧箭头异步加载子节点数据toggle() {if (this.model.expanded) {this.expanded = false;} else {this.expanded = !this.expanded;}this.model.expanded = false;},// 删除节点delNode() {this.rootNode.$emit("delete-node", this.model);},setEditable(bool) {this.clickEditIcon = bool || false;this.editable = true;this.$nextTick(() => {const $input = this.$refs.nodeInput;$input.focus();this.handleCurClick();});},setUnEditable(e) {if (this.editable === false) return;this.editable = false;this.model.editNode = false;var oldName = this.model.name;this.model.changeName(e.target.value);this.rootNode.$emit("change-name",{id: this.model.id,oldName: oldName,newName: e.target.value,eventType: "blur"},this.model);this.rootNode.$emit("end-edit",{id: this.model.id,oldName: oldName,newName: e.target.value},this.model,this.clickEditIcon);this.clickEditIcon = false;},// 新建目录handleInitEditable(row) {if (row.editNode) {this.setEditable();}},// 异步请求数据async loadDataAjax(Refresh) {if (Refresh) {this.model.isLeaf = true;}const { method, params, httpApi } = this.requestHeader || {};const httpUrl = this.model.isLeaf ? httpApi : this.loadDataApi;const requestParams = this.model.isLeaf? { treeDirId: this.model.id, ...(params || {}) }: { id: this.model.id, ...(params || {}) };try {this.isRemoteLoading = true;const { code, data, message } = await request(method || "GET",httpUrl,requestParams);if (code !== 0) {return ((this.expanded = false),(this.isRemoteLoading = false),this.$Message.error("失败," + message || "请求失败"));}const dataSource = this.model.isLeaf ? data.deviceList : data.data;if (!dataSource) {return (this.expanded = false), (this.isRemoteLoading = false);}if (Array.isArray(dataSource) && dataSource.length) {dataSource.forEach(item => {const node = new TreeNode(item);if (Refresh && this.expanded) {this.model._removeChild(node, true);}this.model.addChildren(node, true);});this.expanded = true;}this.isRemoteLoading = false;} catch (err) {this.expanded = false;this.isRemoteLoading = false;throw new Error(err);}},mouseOver() {if (this.model.disabled) return;this.isHover = true;},mouseOut() {this.isHover = false;},// 点击当前节点handleCurClick() {this.rootNode.$emit("click",{toggle: this.toggle,...this.model},this.editable);if (this.$route.path=='/autoMonitorBoard') {this.toggle()}},// 查看详情handleViewDetail() {this.rootNode.$emit("viewDetail", {...this.model});},// 新增子节点async addChild(isLeaf) {if (!this.expanded) {await this.loadDataAjax();this.handleAddChildren(isLeaf);} else {this.handleAddChildren(isLeaf);}},handleAddChildren(isLeaf) {const name = isLeaf ? this.defaultLeafNodeName : this.defaultTreeNodeName;this.expanded = true;var node = new TreeNode({ name, isLeaf, isDir: false });this.model.addChildren(node, true);this.rootNode.$emit("add-node", node);},createChild() {this.rootNode.$emit("create-child", {...this.model,loadDataAjax: this.loadDataAjax});},// dragStart(e) {//   if (!(this.model.dragDisabled || this.model.disabled)) {//     compInOperation = this;//     e.dataTransfer.setData("data", "data");//     e.dataTransfer.effectAllowed = "move";//     return true;//   }//   return false;// },// dragEnd() {//   compInOperation = null;// },dragOver(e) {e.preventDefault();return true;},dragEnter(ev) {this.isDragEnterNode = true;},dragLeave() {this.isDragEnterNode = false;},drop(ev) {if (ev.dataTransfer && ev.dataTransfer.getData("data")) {const data = JSON.parse(ev.dataTransfer.getData("data"));this.isDragEnterNode = false;this.$Modal.confirm({title: "提示",content: `是否确定要移入【${this.model.title}】目录中?`,closable: true,maskClosable: true,onOk: () => {this.axios.request("POST", "/api/move", {id: data.id,treeDirId: this.model.id}).then(response => {if (+response.code === 0) {this.$Message.success("移动成功!");this.rootNode.$emit("moveGraph");} else {// 提示错误this.$Notice.error({title: "查询失败",desc: response.message || "请求失败",duration: 5});}});}});return;}if (!compInOperation) return;const oldParent = compInOperation.model.parent;compInOperation.model.moveInto(this.model);this.isDragEnterNode = false;this.rootNode.$emit("drop", {target: this.model,node: compInOperation.model,src: oldParent});}//   dragEnterUp() {//     if (!compInOperation) return;//     this.isDragEnterUp = true;//   },//   dragOverUp(e) {//     e.preventDefault();//     return true;//   },//   dragLeaveUp() {//     if (!compInOperation) return;//     this.isDragEnterUp = false;//   },//   dropBefore() {//     if (!compInOperation) return;//     const oldParent = compInOperation.model.parent;//     compInOperation.model.insertBefore(this.model);//     this.isDragEnterUp = false;//     this.rootNode.$emit("drop-before", {//       target: this.model,//       node: compInOperation.model,//       src: oldParent,//     });//   },//   dragEnterBottom() {//     if (!compInOperation) return;//     this.isDragEnterBottom = true;//   },//   dragOverBottom(e) {//     e.preventDefault();//     return true;//   },//   dragLeaveBottom() {//     if (!compInOperation) return;//     this.isDragEnterBottom = false;//   },//   dropAfter() {//     if (!compInOperation) return;//     const oldParent = compInOperation.model.parent;//     compInOperation.model.insertAfter(this.model);//     this.isDragEnterBottom = false;//     this.rootNode.$emit("drop-after", {//       target: this.model,//       node: compInOperation.model,//       src: oldParent,//     });//   },},beforeCreate() {this.$options.components.item = require("./VueTreeList").default;},beforeDestroy() {removeHandler(window, "keyup");}
};
</script><style lang="less">
@font-face {font-family: "icomoon";src: url("fonts/icomoon.eot?ui1hbx");src: url("fonts/icomoon.eot?ui1hbx#iefix") format("embedded-opentype"),url("fonts/icomoon.ttf?ui1hbx") format("truetype"),url("fonts/icomoon.woff?ui1hbx") format("woff"),url("fonts/icomoon.svg?ui1hbx#icomoon") format("svg");font-weight: normal;font-style: normal;
}.vtl-icon {font-family: "icomoon" !important;font-style: normal;font-weight: normal;font-variant: normal;text-transform: none;line-height: 1;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;&.vtl-menu-icon {margin-right: 4px;&:hover {color: inherit;}}&:hover {color: #d9262c;}
}.vtl-icon-file:before {content: "\e906";
}
.vtl-icon-folder:before {content: "\e907";
}
.vtl-icon-caret-down:before {font-size: 16px;content: "\e901";
}
.vtl-icon-caret-right:before {font-size: 16px;content: "\e900";
}
.vtl-icon-edit:before {content: "\e902";font-size: 18px;
}
.vtl-icon-folder-plus-e:before {content: "\e903";
}
.vtl-icon-plus:before {content: "\e904";font-size: 16px;
}
.vtl-icon-trash:before {content: "\e905";
}.vtl {cursor: default;margin-left: -3px;
}
.vtl-border {height: 5px;&.vtl-up {margin-top: -5px;background-color: transparent;}&.vtl-bottom {background-color: transparent;}&.vtl-active {border-bottom: 2px dashed pink;}
}.vtl-node-main {display: flex;align-items: center;margin: 2.5px auto 2.5px -1px;.vtl-input {border: none;min-width: 200px;border-bottom: 1px solid blue;}&:hover {background-color: #f0f0f0;}&.vtl-active {outline: 1.5px dashed #d9262c;}.vtl-operation {display: flex;margin-left: 1rem;height: 18px;letter-spacing: 1px;span {margin-right: 10px;}.vtl-icon {color: #d9262c;vertical-align: sub;}}
}.vtl-node-content {white-space: nowrap;padding: 1px 0px;
}.activeItem {background: #ccc;
}
.custom_class_click {cursor: pointer;
}.custom_class_hiddle {overflow: hidden;text-overflow: ellipsis;
}.vtl-item {cursor: pointer;
}
.vtl-tree-margin {margin-left: 2em;
}.Custom_demo-spin-icon-load {font-size: 18px;color: #d9262c;animation: ani-demo-spin 1s linear infinite;
}
@keyframes ani-demo-spin {from {transform: rotate(0deg);}50% {transform: rotate(180deg);}to {transform: rotate(360deg);}
}
.demo-spin-col {height: 100px;position: relative;border: 1px solid #eee;
}.vtl-caret {display: flex;.vtl-icon {width: 28px;text-align: right;}
}.isMobile {.vtl {margin-left: 3px;}.vtl-node-content {white-space: nowrap;padding: 1px 0px;font-size: 2.6em;}.custom_img {width: 2.5em !important;}.vtl-icon-caret-down:before,.vtl-icon-caret-right:before,.vtl-icon-plus:before,.vtl-icon-edit:before,.vtl-icon-trash:before,.vtl-icon-folder-plus-e:before {font-size: 30px;}.vtl-node-main .vtl-operation {height: auto;}
}
</style>

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

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

相关文章

六、Json 数据的交互处理

文章目录 一、JSON 数据的交互处理1、为什么要使用 JSON2、JSON 和 JavaScript 之间的关系3、前端操作 JSON3.1 JavaScript 对象与 JSON 字符串之间的相互转换 4、JAVA 操作 JSON4.1 Json 的解析工具&#xff08;Gson、FastJson、Jackson&#xff09;4.2 ResponseBody 注解、Re…

Fedora Linux 的家族(一):官方版本

导读本文将对 Fedora Linux 官方版本进行更详细的介绍。共有五个 版本&#xff1a; Fedora Workstation、Fedora Server、Fedora IoT、Fedora CoreOS 和 Fedora Silverblue。Fedora Linux 下载页面目前显示其中三个为 官方 版本&#xff0c;另外两个为 新兴 版本。本文将涵盖所…

LOIC(low orbit ion cannon)

前言 重要的话说三遍&#xff1a; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上&#xff01;&#xff01;&#xff01; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上&#xff01;&#xff01;&#xff01; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上…

【C++初阶】list的常见使用操作

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

关闭jenkins插件提醒信息

jenkins提醒信息和安全警告可以帮助我们了解插件或者jenkins的更新情况&#xff0c;但是有些插件是已经不维护了&#xff0c;提醒却一直存在&#xff0c;看着糟心&#xff0c;就像下面的提示 1、关闭插件提醒 找到如下位置&#xff1a;系统管理-系统配置-管理监控配置 打开管…

线性代数的学习和整理11: 子式与余子式

目录 1 原始矩阵A 2 子式&#xff08;都是行列式&#xff09; 2.1 k阶子式&#xff08;行数列数即可&#xff09; 比如1阶子式&#xff1a;因为只有1行1列 比如2阶子式&#xff1a;因为有2行2列 比如3阶子式&#xff1a;因为有3行3列 2.2 k阶主子式 {行序号数组} {列序号…

java对时间序列根据阈值进行连续性分片

问题描述&#xff1a;我需要对一个连续的时间戳list进行分片&#xff0c;分片规则是下一个数据比当前数据要大于某一个阈值则进行分片&#xff1b; 解决方式&#xff1a; 1、输入的有顺序的list &#xff0c;和需要进行分片的阈值 2、调用方法&#xff0c;填入该排序的list和阈…

阿里云轻量应用服务器Linux-Centos7下Oracle19c的配置

初始环境&#xff1a;阿里云轻量应用服务器已经安装Oracle19c 具体目标&#xff1a;配置Oracle Database 19c 目录 第一步&#xff1a;切换到Oracle命令行第二步&#xff1a;新建用户和表空间第三步&#xff1a;切换用户第四步&#xff1a;在当前用户下创建一些表第五步&#x…

SQL Server 2019导入txt数据

1、选择导入数据 2、选择Flat file Source 选择文件&#xff0c;如果第一行不是列名&#xff0c;就不勾选。 3、下一步 可以看看数据是否是对的 4、下一步 选择SQL server Native Client 11&#xff0c;数据库选择导入进的库 输入连接数据库的名字和要导入的数据库 下一…

【Jetpack】Navigation 导航组件 ⑤ ( NavigationUI 类使用 )

文章目录 一、NavigationUI 类简介二、NavigationUI 类使用流程1、创建 Fragment2、创建 NavigationGraph3、Activity 导入 NavHostFragment4、创建菜单5、Activity 界面开发 NavigationUI 的主要逻辑 ( 重点 )a、添加 Fragment 布局b、处理 Navigation 导航逻辑 ( 重点 )c、启…

设计模式--工厂模式(Factory Pattern)

一、 什么是工厂模式 工厂模式&#xff08;Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种创建对象的接口&#xff0c;但是将对象的实例化过程推迟到子类中。工厂模式允许通过调用一个共同的接口方法来创建不同类型的对象&#xff0c;而无需暴露对…

Python爬虫武汉市二手房价格数据采集分析:Linear Regression、XGBoost和LightGBM|代码分享...

全文链接&#xff1a;http://tecdat.cn/?p31958 分析师&#xff1a;Yan Liu 我国有大量的资金都流入了房地产行业&#xff0c;同时与其他行业有着千丝万缕的联系&#xff0c;可以说房地产行业对推动我国深化改革、经济发展、工业化和城市化具有不可磨灭的作用&#xff08;点击…

java八股文面试[java基础]——字节码

字节码技术应用 字节码技术的应用场景包括但不限于AOP&#xff0c;动态生成代码&#xff0c;接下来讲一下字节码技术相关的第三方类库&#xff0c;第三方框架的讲解是为了帮助大家了解字节码技术的应用方向&#xff0c;文档并没有对框架机制进行详细分析&#xff0c;有兴趣的可…

为什么海外专利申请含金量高?

为什么海外专利申请含金量高&#xff1f;通常&#xff0c;具有较大市场价值的发明才需要在国外申请专利保护&#xff0c;专利的海外申请数量是衡量经济和创新价值的重要指标&#xff0c;即专利全球性指标。我国海外专利申请量比重过低&#xff0c;说明专利的创造性未达到国外专…

注解和class对象和mysql

注解 override 通常是用在方法上的注解表示该方法是有重写的 interface 表示一个注解类 比如 public interface override{} 这就表示是override是一个注解类 target 修饰注解的注解表示元注解 deprecated 修饰某个元素表示该元素已经过时了 1.不代表该元素不能用了&…

查漏补缺 - 构造函数,原型,this,原型链,继承

目录 1&#xff0c;构造函数2&#xff0c;原型3&#xff0c;this4&#xff0c;原型链1&#xff0c;特点2&#xff0c;Object.prototype.toString()3&#xff0c;instanceof 运算符4&#xff0c;Object.getPrototypeOf()5&#xff0c;创建空原型对象6&#xff0c;面试题 5&#…

Vue2向Vue3过度核心技术自定义指令

目录 1 自定义指令1.指令介绍2.自定义指令3.自定义指令语法4.指令中的配置项介绍5.代码示例6.总结 2 自定义指令-指令的值1.需求2.语法3.代码示例 3 自定义指令-v-loading指令的封装1.场景2.需求3.分析4.实现5.准备代码 1 自定义指令 1.指令介绍 内置指令&#xff1a;v-html、v…

【无需公网IP】在树莓派上搭建Web站点

目录 1.概述 2.使用 Raspberry Pi Imager 安装 Raspberry Pi OS 3.设置 Apache Web 服务器 3.1测试 web 站点 3.2安装静态样例站点 3.3将web站点发布到公网 3.4安装 Cpolar 3.5cpolar进行token认证 3.6生成cpolar随机域名网址 3.7生成cpolar二级子域名 3.8将参数保存…

基于Android的课程教学互动系统 微信小程序uniapp

教学互动是学校针对学生必不可少的一个部分。在学校发展的整个过程中&#xff0c;教学互动担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类教学互动程序也在不断改进。本课题所设计的springboot基于Android的教学互动系统&#xff0c;使用SpringBoot框架&am…

接口幂等性设计的最佳实现

一、什么是幂等 二、为什么需要幂等 三、接口超时了&#xff0c;到底如何处理&#xff1f; 四、如何设计幂等 全局的唯一性ID 幂等设计的基本流程 五、实现幂等的8种方案 selectinsert主键/唯一索引冲突 直接insert 主键/唯一索引冲突 状态机幂等 抽取防重表 token令牌 悲观锁…