写angular2项目时,需要用到tree结构。测试了一部分,在这里记录下。因为官网的样式与我想要的有些出入,因此还要对官网样式做修改。

达到的效果

初渲染:

右击之后:

官网相关

官网地址:https://ng.ant.design/components/tree/zh#api

官网样式:

官网代码:

import { Component } from '@angular/core';
import { NzFormatEmitEvent } from 'ng-zorro-antd/tree';@Component({selector: 'nz-demo-tree-draggable',template: ` <nz-tree [nzData]="nodes" nzDraggable nzBlockNode (nzOnDrop)="nzEvent($event)"> </nz-tree> `
})
export class NzDemoTreeDraggableComponent {nodes = [{title: '0-0',key: '00',expanded: true,children: [{title: '0-0-0',key: '000',expanded: true,children: [{ title: '0-0-0-0', key: '0000', isLeaf: true },{ title: '0-0-0-1', key: '0001', isLeaf: true },{ title: '0-0-0-2', key: '0002', isLeaf: true }]},{title: '0-0-1',key: '001',children: [{ title: '0-0-1-0', key: '0010', isLeaf: true },{ title: '0-0-1-1', key: '0011', isLeaf: true },{ title: '0-0-1-2', key: '0012', isLeaf: true }]},{title: '0-0-2',key: '002'}]},{title: '0-1',key: '01',children: [{title: '0-1-0',key: '010',children: [{ title: '0-1-0-0', key: '0100', isLeaf: true },{ title: '0-1-0-1', key: '0101', isLeaf: true },{ title: '0-1-0-2', key: '0102', isLeaf: true }]},{title: '0-1-1',key: '011',children: [{ title: '0-1-1-0', key: '0110', isLeaf: true },{ title: '0-1-1-1', key: '0111', isLeaf: true },{ title: '0-1-1-2', key: '0112', isLeaf: true }]}]},{title: '0-2',key: '02',isLeaf: true}];nzEvent(event: NzFormatEmitEvent): void {console.log(event);}
}

我借鉴的官网代码

import { Component } from '@angular/core';
import { NzContextMenuService, NzDropdownMenuComponent } from 'ng-zorro-antd/dropdown';
import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree';@Component({selector: 'nz-demo-tree-directory',template: `<nz-treenzBlockNode[nzData]="nodes"(nzClick)="activeNode($event)"(nzDblClick)="openFolder($event)"[nzTreeTemplate]="nzTreeTemplate"></nz-tree><ng-template #nzTreeTemplate let-node let-origin="origin"><span class="custom-node"><span *ngIf="!node.isLeaf" (contextmenu)="contextMenu($event, menu)"><i nz-icon [nzType]="node.isExpanded ? 'folder-open' : 'folder'" (click)="openFolder(node)"></i><span class="folder-name">{{ node.title }}</span><span class="folder-desc">created by {{ origin.author | lowercase }}</span></span><span *ngIf="node.isLeaf" (contextmenu)="contextMenu($event, menu)"><i nz-icon nzType="file"></i><span class="file-name">{{ node.title }}</span><span class="file-desc">modified by {{ origin.author | lowercase }}</span></span></span></ng-template><nz-dropdown-menu #menu="nzDropdownMenu"><ul nz-menu><li nz-menu-item (click)="selectDropdown()">Action 1</li><li nz-menu-item (click)="selectDropdown()">Action 2</li></ul></nz-dropdown-menu>`,styles: [`nz-tree {overflow: hidden;margin: 0 -24px;padding: 0 24px;}.custom-node {cursor: pointer;line-height: 24px;margin-left: 4px;display: inline-block;}.file-name,.folder-name {margin-left: 4px;}.file-desc,.folder-desc {padding: 0 8px;display: inline-block;background: #87ceff;color: #ffffff;position: relative;left: 12px;}`]
})
export class NzDemoTreeDirectoryComponent {// activated nodeactivatedNode?: NzTreeNode;nodes = [{title: 'parent 0',key: '100',author: 'NG ZORRO',expanded: true,children: [{ title: 'leaf 0-0', key: '1000', author: 'NG ZORRO', isLeaf: true },{ title: 'leaf 0-1', key: '1001', author: 'NG ZORRO', isLeaf: true }]},{title: 'parent 1',key: '101',author: 'NG ZORRO',children: [{ title: 'leaf 1-0', key: '1010', author: 'NG ZORRO', isLeaf: true },{ title: 'leaf 1-1', key: '1011', author: 'NG ZORRO', isLeaf: true }]}];openFolder(data: NzTreeNode | NzFormatEmitEvent): void {// do something if u wantif (data instanceof NzTreeNode) {data.isExpanded = !data.isExpanded;} else {const node = data.node;if (node) {node.isExpanded = !node.isExpanded;}}}activeNode(data: NzFormatEmitEvent): void {this.activatedNode = data.node!;}contextMenu($event: MouseEvent, menu: NzDropdownMenuComponent): void {this.nzContextMenuService.create($event, menu);}selectDropdown(): void {// do something}constructor(private nzContextMenuService: NzContextMenuService) {}
}

我的大致代码(第一张图的)

创建一个组件

html的代码

<nz-tree[nzData]="nodes"nzDraggablenzCheckablenzBlockNode[nzCheckedKeys]="defaultCheckedKeys"[nzBeforeDrop]="beforeDrop"(nzCheckBoxChange)="nzCheck($event)"(nzOnDragEnter)="nzCheck2($event)"(nzOnDragEnd)="nzCheck3($event)"[nzTreeTemplate]="nzTreeTemplate"></nz-tree><ng-template #nzTreeTemplate let-node let-origin="origin"><span class="custom-node"><span *ngIf="!node.isLeaf"><span>{{ node.title }}</span></span><span *ngIf="node.isLeaf"><span  [class]='class(2)'>{{ node.title }}</span></span></span></ng-template>

css的代码

控制子叶节点字体颜色(自己随便写的)

  .red {color: red;}.orange {color: orange;}

ts代码

import { Component, OnInit } from '@angular/core';
import { NzContextMenuService, NzDropdownMenuComponent } from 'ng-zorro-antd/dropdown';
import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree';
import { NzFormatBeforeDropEvent } from 'ng-zorro-antd/tree';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';@Component({selector: 'app-text',templateUrl: './text.component.html',styleUrls: ['./text.component.less']
})
export class TextComponent implements OnInit {defaultCheckedKeys = ['10011'];
// 虚拟数据nodes = [{// 标题title: '富阳区',key: '100',// 设置节点是否展开expanded: true,// 子节点children: [{title: '街道',key: '1001',// 设置节点是否展开expanded: true,children: [{title: '自然村1',key: '10010',isLeaf: true,color: 'red'// // 设置节点本身是否选中// selected: true,// // 设置节点 Checkbox 是否选中// checked: true,},{title: '自然村2',key: '10011',// 设置为设置为叶子节点(叶子节点不可被拖拽模式放置)isLeaf: true,color: 'blue'},{title: '自然村3',key: '10012',// 设置为设置为叶子节点(叶子节点不可被拖拽模式放置)isLeaf: true},]},{title: '0-0-1',key: '1002',children: [{ title: '0-0-1-0', key: '10020', isLeaf: true }]},]},{// 标题title: '0-1',key: '101',// 设置节点是否展开expanded: false,// 子节点children: [{title: '0-1-1',key: '1011',children: [{ title: '0-1-1-0', key: '10030', isLeaf: true }]},{title: '0-1-2',key: '1012',children: [{ title: '0-1-2-0', key: '10040', isLeaf: true },{ title: '0-1-2-1', key: '10050', isLeaf: true },{ title: '0-1-2-2', key: '10060', isLeaf: true },]}]}];constructor(private nzContextMenuService: NzContextMenuService) { }ngOnInit(): void {}//    点击树节点 Checkbox 触发nzCheck(event: NzFormatEmitEvent): void {console.log(event);}// 在拖动的元素进入到放置目标时执行nzCheck2(event: NzFormatEmitEvent): void {console.log('在拖动的元素进入到放置目标时执行');// 这个触动太频繁了,不建议要// console.log(event);}// (nzOnDragEnd)nzCheck3(event: NzFormatEmitEvent): void {console.log('用户完成元素拖动后触发');console.log(event);}// 拖拽前校验beforeDrop(arg: NzFormatBeforeDropEvent): Observable<boolean> {// if insert node into another node, wait 1s// 如果将节点插入另一个节点,等待1sconsole.log('如果将节点插入另一个节点,等待1s');console.log(arg);if (arg.pos === 0) {return of(true).pipe(delay(1000));} else {return of(false);}}//  方法// tslint:disable-next-line:typedefclass(id) {// 这个id就是返回的0、1、2const ids = Number(id);if (ids === 1) {return 'red';}else if (ids === 2) {return 'orange';}}
}

解释

主要还是要看官网的api

1、事件

  • 在拖动目标上触发事件 (源元素)
    ondragstart - 用户开始拖动元素时触发
    ondrag - 元素正在拖动时触发
    ondragend - 用户完成元素拖动后触发

  • 释放目标时触发的事件

    ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件 在拖动的元素进入到放置目标时执行
    ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
    ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
    ondrop - 在一个拖动过程中,释放鼠标键时触发此事件

2、nz-tree参数

nzCheckedKeys 指定选中复选框的树节点 子节点被指定时,父节点默认选中,父亲选中的样式点,本身选中的为对号
nzExpandedKeys 展开指定的树节点 这个属性可以在数组里定义=== expanded
[nzSelectedKeys] 指定选中的树节点 指定的节点背景变了,感觉没啥用

我的代码里使用的

 [nzData]="nodes"  绑定数据nzDraggable  设置节点可拖拽nzCheckable 节点前添加 Checkbox 复选框nzBlockNode      是否节点占据一行[nzCheckedKeys]="defaultCheckedKeys"  上面解释了(nzCheckBoxChange)="nzCheck($event)"  点击树节点 Checkbox 触发(nzOnDragEnter)="nzCheck2($event)"       dragenter 触发时调用(nzOnDragEnd)="nzCheck3($event)"    dragend 触发时调用[nzTreeTemplate]="nzTreeTemplate"     自定义节点,用这个来改变子叶节点的颜色

3、NzTreeNodeOptions props参数

就是数据数组里要使用的,放ts里面虚拟数据里的

解释参数

  expanded: true(设置节点是否展开),这个常用isLeaf(是否为叶子节点),html里常用这个参数来判断并设置样式……

参数对比

selected: true( 设置节点本身是否选中),checked: true(设置节点 Checkbox 是否选中) 与 defaultCheckedKeys(指定选中复选框的树节点 子节点被指定时,父节点默认选中),这两者看起来很类似,但不一样,可以看看效果:

4、子叶节点样式(这里改变了字体颜色)

这里是通过自定义目录结构实现的,就是[nzTreeTemplate]="nzTreeTemplate"部分,模板里,通过设置动态class,既可以使用单一样式,还可以根据后台返回的参数进行判断,选择性显示样式


我这里用1、2作为判断条件,实际开发里,要看接口返回的状态码

5、拖拽设置

nzDraggable 设置节点可拖拽
html代码里已经设置了可以拖拽,我们要做的是,要在拖拽之后进行判断,看是否满足拖拽条件。具体的看上面写的“事件”。

我的完整代码(包括右击后的代码)

新建一个组件,把这些代码放进去(ts代码要修改一下)

html代码

<!-- <nz-tree[nzData]="nodes"nzDraggablenzCheckablenzBlockNode(nzCheckBoxChange)="nzCheck($event)"(nzOnDragEnter)="nzCheck2($event)"(nzOnDragEnd)="nzCheck3($event)"[nzBeforeDrop]="beforeDrop"[nzTreeTemplate]="nzTreeTemplate"></nz-tree><ng-template #nzTreeTemplate let-node let-origin="origin"><span class="custom-node"><span *ngIf="!node.isLeaf"><span>{{ node.title }}</span></span><span *ngIf="node.isLeaf"><span  [class]='class(2)'>{{ node.title }}</span></span></span></ng-template> --><nz-tree[nzData]="nodes"nzDraggablenzCheckablenzBlockNode[nzCheckedKeys]="defaultCheckedKeys"(nzCheckBoxChange)="nzCheck($event)"(nzOnDragEnter)="nzCheck2($event)"(nzOnDragEnd)="nzCheck3($event)"[nzBeforeDrop]="beforeDrop"[nzTreeTemplate]="nzTreeTemplate"(nzContextMenu)='ContextMenu($event)'
>
</nz-tree>
<ng-template #nzTreeTemplate let-node let-origin="origin"><span class="custom-node"><!-- 这里可以修改父节点样式  给span添加样式,这里我什么都没添加 --><span *ngIf="!node.isLeaf" (contextmenu)="contextMenu($event, menu)"><span>{{ node.title }}</span></span><!-- 子叶节点 --><span *ngIf="node.isLeaf" (contextmenu)="contextMenu($event, menu)"><span  [class]='class(2)'>{{ node.title }}</span></span></span>
</ng-template>
<nz-dropdown-menu #menu="nzDropdownMenu"><ul nz-menu><li nz-menu-item (click)="selectDropdown1()">修改</li><li nz-menu-item (click)="selectDropdown2()">添加子选项</li><li nz-menu-item (click)="selectDropdown3()">删除</li></ul></nz-dropdown-menu><!-- 添加跟节点 -->
<!-- nzWidth='800' -->
<nz-modal [(nzVisible)]="isVisible1" nzTitle="新增根部信息" (nzOnCancel)="handleCancel1()" (nzOnOk)="handleOk1()" ><form nz-form><nz-form-item><nz-form-label [nzSpan]="6" nzFor="name">名称:</nz-form-label><nz-form-control [nzSpan]="14"><input nz-input name="name" type="text" id="name"></nz-form-control></nz-form-item ></form>
</nz-modal>
<!-- 修改(需要把信息拿过来) -->
<nz-modal [(nzVisible)]="isVisible2" nzTitle="修改信息" (nzOnCancel)="handleCancel2()" (nzOnOk)="handleOk2()" ><form nz-form><nz-form-item><nz-form-label [nzSpan]="6" nzFor="name">名称:</nz-form-label><nz-form-control [nzSpan]="14"><input nz-input name="name" type="text" id="name" [(ngModel)]="title1"></nz-form-control></nz-form-item ></form>
</nz-modal>
<!-- 添加子节点 -->
<nz-modal [(nzVisible)]="isVisible3" nzTitle="添加子节点" (nzOnCancel)="handleCancel3()" (nzOnOk)="handleOk3()" ><form nz-form><nz-form-item><nz-form-label [nzSpan]="6" nzFor="name">父级名称:</nz-form-label><nz-form-control [nzSpan]="14"><input nz-input name="name" type="text" id="name" [(ngModel)]="title1" [disabled]="true" ></nz-form-control></nz-form-item ><nz-form-item><nz-form-label [nzSpan]="6" nzFor="name2">子级名称:</nz-form-label><nz-form-control [nzSpan]="14"><input nz-input name="name2" type="text" id="name2" [(ngModel)]="title2"></nz-form-control></nz-form-item ></form>
</nz-modal>

css代码:

.red {color: red;
}
.orange {color: orange;
}

ts代码

import { Component, OnInit } from '@angular/core';
import { NzFormatBeforeDropEvent } from 'ng-zorro-antd/tree';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { NzFormatEmitEvent, NzTreeComponent, NzTreeNodeOptions } from 'ng-zorro-antd/tree';
import { NzContextMenuService, NzDropdownMenuComponent } from 'ng-zorro-antd/dropdown';
import { NzTreeNode } from 'ng-zorro-antd/tree';
import { NzModalService } from 'ng-zorro-antd/modal';@Component({selector: 'app-text',templateUrl: './text.component.html',styleUrls: ['./text.component.less']
})
export class TextComponent implements OnInit {defaultCheckedKeys = ['10011'];nodes = [{// 标题title: '富阳区',key: '100',// 设置节点是否展开expanded: true,// 子节点children: [{title: '街道',key: '1001',// 设置节点是否展开expanded: true,children: [{title: '自然村1',key: '10010',isLeaf: true,color: 'red'},{title: '自然村2',key: '10011',// 设置为设置为叶子节点(叶子节点不可被拖拽模式放置)isLeaf: true,color: 'blue',// 设置节点本身是否选中selected: true,// 设置节点 Checkbox 是否选中checked: true,},{title: '自然村3',key: '10012',// 设置为设置为叶子节点(叶子节点不可被拖拽模式放置)isLeaf: true},]},{title: '0-0-1',key: '1002',children: [{ title: '0-0-1-0', key: '10020', isLeaf: true }]},]},{// 标题title: '0-1',key: '101',// 设置节点是否展开expanded: false,// 子节点children: [{title: '0-1-1',key: '1011',children: [{ title: '0-1-1-0', key: '10030', isLeaf: true }]},{title: '0-1-2',key: '1012',children: [{ title: '0-1-2-0', key: '10040', isLeaf: true },{ title: '0-1-2-1', key: '10050', isLeaf: true },{ title: '0-1-2-2', key: '10060', isLeaf: true },]}]}];isVisible1 = false;isVisible2 = false;isVisible3 = false;activatedNode?: NzTreeNode;// 右击选中修改时,要修改的title,右击添加时父级的titletitle1: any = '';// 右击添加时的子级的title2title2: any = '';constructor(private nzContextMenuService: NzContextMenuService,private modal: NzModalService) { }ngOnInit(): void {}//   点击树节点 Checkbox 触发nzCheck(event: NzFormatEmitEvent): void {console.log(event);}// 在拖动的元素进入到放置目标时执行nzCheck2(event: NzFormatEmitEvent): void {console.log('在拖动的元素进入到放置目标时执行');// 这个触动太频繁了,不建议要// console.log(event);}// (nzOnDragEnd)nzCheck3(event: NzFormatEmitEvent): void {console.log('用户完成元素拖动后触发');console.log(event);}//  方法// tslint:disable-next-line:typedefclass(id) {const ids = Number(id);if (ids === 1) {return 'red';} else if (ids === 2) {return 'orange';}}// 拖拽前校验beforeDrop(arg: NzFormatBeforeDropEvent): Observable<boolean> {// if insert node into another node, wait 1s// 如果将节点插入另一个节点,等待1sconsole.log('如果将节点插入另一个节点,等待1s');console.log(arg);if (arg.pos === 0) {return of(true).pipe(delay(1000));} else {return of(false);}}// 每次右击时,会触发这个方法(为了添加右击后的选项)contextMenu($event: MouseEvent, menu: NzDropdownMenuComponent): void {this.nzContextMenuService.create($event, menu);}// 右击数的节点触发// tslint:disable-next-line:typedefContextMenu(e) {console.log('右击数的节点触发');console.log(e.node.origin);this.title1 = e.node.origin.title;}// 添加跟节点showModal1(): void {this.isVisible1 = true;}handleOk1(): void {console.log('Button ok clicked!');this.isVisible1 = false;}handleCancel1(): void {console.log('Button cancel clicked!');this.isVisible1 = false;}// 修改// tslint:disable-next-line:adjacent-overload-signaturesselectDropdown1(): void {console.log('修改');this.isVisible2 = true;}handleOk2(): void {console.log('Button ok clicked!');this.isVisible2 = false;}handleCancel2(): void {console.log('Button cancel clicked!');this.isVisible2 = false;}// 添加子节点// tslint:disable-next-line:adjacent-overload-signaturesselectDropdown2(): void {console.log('添加子选项');this.isVisible3 = true;}handleOk3(): void {console.log('Button ok clicked!');this.isVisible3 = false;}handleCancel3(): void {console.log('Button cancel clicked!');this.isVisible3 = false;}selectDropdown3(): void {console.log('删除');this.modal.confirm({nzTitle: '您确定删除吗?',nzContent: this.title1,nzOkText: '确定',nzOkType: 'danger',nzOnOk: () => console.log('OK'),nzCancelText: '取消',nzOnCancel: () => console.log('Cancel')});}
}

zorro的Tree树形控件操作相关推荐

  1. 《实用VC编程之玩转控件》第15课:Tree树形控件

    本文转载自:VC驿站 https://www.cctry.com/thread-297465-1-1.html 1.控件简介: Tree树形控件也是我们编程过程中比较常用的一个控件,而且在其他软件中也 ...

  2. elementui tree获取父节点_vue_elementUI_ tree树形控件 获取选中的父节点ID

    一,  vue_elementUI_ tree树形控件 1.1默认点击tree节点的第一个(注意不是checked选中) :expand-on-click-node="false" ...

  3. Element Tree 树形控件自定义显示样式与hover事件绑定实现添加、删除和修改

    Element Tree 树形控件自定义显示样式与hover事件绑定实现添加.删除和修改 最近在搞erp项目对应后台的管理功能,为了加速开发使用了 vue-element-admin 开发,使用的是e ...

  4. vue 树形控件可编辑_vue.js element-ui组件改iview 第一期 tree树形控件

    此为第一期修改,后期也适配了其他组件,更多查看我得文章 element-ui组件的tree树形控件修改源码改为iview组件 实现原理 修改了element-ui源码,把源码里面的tree模块提取出来 ...

  5. Element ui tree树形控件获取当前节点id和父节点id

    低版本Element ui tree树形控件获取当前节点id和父节点id的方法:点击查看 最新版本Element ui tree树形控件获取当前节点id和父节点id教程: 1.找到node_modul ...

  6. React 组件封装之 Tree 树形控件

    React 组件封装之 Tree 树形控件 一.Tree 树形结构 二.使用案例 三.API 使用指南 四.源代码 五.总结 一.Tree 树形结构 组件说明: 实现树形控件,适用于组织架构.文章列表 ...

  7. vue+element tree(树形控件数据格式)组件(1)

    vue+element tree(树形控件数据格式)组件(1), 最近做了第一个组内可以使用的组件,虽然是最简版,也废了不少力.各位前辈帮我解决问题,才勉强搞定.让我来记录这个树形组件的编写过程和期间 ...

  8. Element-UI实现Tree 树形控件节点添加图标

    Element-UI实现Tree 树形控件节点添加图标: 属于自定义节点内容,可以通过两种方法进行树节点内容的自定义:render-content 和  scoped slot. 1.scoped s ...

  9. vue+element-ui之tree树形控件有关子节点和父节点之间的各种选中关系详解

    做后端管理系统,永远是最蛋疼.最复杂也最欠揍的事情,也永远是前端开发人员最苦逼.最无奈也最尿性的时刻.蛋疼的是需求变幻无穷,如同二师兄的三十六般变化:复杂的是开发难度寸步难行,如同蜀道难,难于上青天: ...

最新文章

  1. c语言24点游戏流程图,C语言解24点游戏程序
  2. 2021考研c语言编程题,2021c语言编程例题及答案.docx
  3. 用vuejs如何实现ajax,vue.js如何实现ajax
  4. 分享19个高质量架构视频!吃透它,妥妥让你进大厂!
  5. systemtap notes
  6. 效率低的日子怎么办?
  7. 目标检测分类损失函数——Cross entropy、Focal loss
  8. Erlang 之父 Joe Armstrong 逝世,享年 68 岁
  9. Servlet的request.getRemoteAddr()方法回去地址是0:0:0:0:0:0:0:1
  10. 机器学习傻瓜的深入研究
  11. 20/23种设计模式---C++实现
  12. Sentaurus TCAD模型创建、激活电极等
  13. 谋定而后动,常怀敬畏之心--生产库DBA必备素质
  14. 百度人脸识别 人脸识别模型_人脸识别的现代君主制
  15. c语言编程线性规划,使用C语言实现单纯形法求解线性规划问题.doc
  16. 让树莓派不再吃灰(Raspberry+Docker+Portainer+青龙面板+甜糖+网心云)
  17. 区块链服务网络(BSN)技术详解
  18. python3今日头条App电商数据抓取
  19. Ubuntu20.04 conda安出错,成功解决:solving environment:failed with initial frozen solve.Retrying with flexibl
  20. RAM、ROM、emmc、iNand、SD卡、mmc 与 Nandflash 的区别

热门文章

  1. BI中的特殊语言——MDX
  2. linux启动盘制作hdd无法启动不了,我的U盘安装了pe重启后不认u盘,已在bois设置了第一启动为hdd为什么?求助!...
  3. 14、RowBounds分页
  4. java网络封包_java网络编程(套接字)
  5. 虚拟环境的作用及搭建
  6. 【嗜血GO笔记】如何在goclipse 中配置代码自动补全。
  7. kaldi中文语音识别(1)
  8. 事务的acid属性是指_什么是事务的acid性质
  9. “马云,未来十年我们拼什么”
  10. Python-OpenCV图像水平/垂直/水平垂直翻转