最新有一个新的需求,即在iview tree的自定义节点基础上,对当前节点进行相关的操作,参考相关博客,整理了以下两种方案。
- 右键弹出相关操作按钮 参考博客
实现细节:
<template>
<div>
<Tree
:data="kindData"
:render="renderContent"
></Tree>
<Button
type="primary"
@click="submit"
>提交</Button>
</div>
</template>
<script>
import $ from 'jquery/dist/jquery'
export default {
data () {
return {
editState: false,
// 输入框要修改的内容
inputContent: '',
// 修改前的TreeNode名称
oldName: '',
kindData: [
{
"expand": true,
"title": "父节点1",
"id": null,
"code": "01",
"parentCode": "0",
"children": [
{
"tr_parentCode": "01",
"tr_userid": null,
"tr_name": "11",
"count": "0",
"tr_code": "0101",
"tr_count": 15,
"title": "子节点1",
"id": null,
"code": "0101",
"parentCode": "01",
"nodeKey": 1
}
],
"nodeKey": 0
},
{
"expand": true,
"title": "父节点2",
"id": null,
"code": "02",
"parentCode": "0",
"children": [
{
"tr_parentCode": "02",
"tr_userid": null,
"tr_name": "子节点2-1",
"count": "0",
"tr_code": "0202",
"tr_count": 0,
"title": "子节点2-1",
"id": null,
"code": "0202",
"parentCode": "02",
"nodeKey": 3
},
{
"tr_parentCode": "02",
"tr_userid": null,
"tr_name": "子节点2-2",
"count": "0",
"tr_code": "0203",
"tr_count": 0,
"title": "子节点2-2",
"id": null,
"code": "0203",
"parentCode": "02",
"nodeKey": 4
}
],
"nodeKey": 2
},
{
"expand": true,
"title": "父节点3",
"id": null,
"code": "07",
"parentCode": "0",
"children": [
{
"tr_parentCode": "07",
"tr_userid": null,
"tr_name": "子节点3-1",
"count": "0",
"tr_code": "0700",
"tr_count": 23,
"title": "子节点3-1",
"id": null,
"code": "0700",
"parentCode": "07",
"nodeKey": 49
}
],
"nodeKey": 48
},
{
"expand": true,
"title": "父节点4",
"id": "1377",
"code": "48f84f52884845b999bcf4f3d5978a39",
"parentCode": "0",
"children": [],
"nodeKey": 55
}
]
}
},
methods: {
// 生成唯一id
uuid () {
var s = []
var hexDigits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
}
s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = '-'
var uuid = s.join('')
return uuid
},
renderContent (h, { root, node, data }) {
return h(
'span',
{
class: 'myMenu',
domProps: {
id: data.code,
},
style: {
display: 'inline-block',
width: '100%',
},
on: {
click: ($event) => {
$event.stopPropagation()
},
},
},
[
h('span', [
h('Icon', {
props: { // data.children 属性存在,则证明是父节点
type: data.children ? 'ios-folder-open' : 'md-document'
},
style: {
marginRight: '8px',
marginTop: '-3px',
color: data.children ? '#ffcc00' : '',
fontSize: '18px',
},
}),
//开始
h(
'Dropdown',
{
props: {
transfer: true,
trigger: 'contextMenu',
placement: 'bottom',
},
nativeOn: {
mousedown: ($event) => {
$event.stopPropagation()
if ($event.button === 2) {//$event.button === 0鼠标左键 $event.button === 2鼠标右键 $event.button === 1鼠标滚轮
//引入jquery 连续点击右键出下拉菜单,将上一个下拉菜单隐藏
var dropdownMenuId = "dropdown" + $($event.target).attr("id").substring(5);
$("#" + dropdownMenuId).css("display", "block");
$("#" + dropdownMenuId).parent(".ivu-select-dropdown").siblings(".ivu-select-dropdown").children(".ivu-dropdown-menu").css("display", "none");
}
},
},
},
[
h(`${data.editState ? '' : 'span'}`,{
domProps: { // 子组件的dom属性
id: 'title' + data.code,
},
}, data.title),
h(`${data.editState ? 'input' : ''}`,
{
attrs: {
value: `${data.editState ? data.title : ''}`,
autofocus: 'true',
},
domProps: {
id: 'title' + data.code,
},
style: {
width: '12rem',
cursor: 'auto',
},
on: {
change: (event) => {
this.inputContent = event.target.value
},
},
}),
h(
`${data.editState ? 'span' : ''}`,
{
style: {
marginLeft: '.5rem',
},
},
[
// 确认按钮
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'md-checkmark',
}),
style: {
// marginRight: '8px',
border: 0,
background: 'rgba(0,0,0,0)',
fontSize: '1.3rem',
outline: 'none',
},
on: {
click: (event) => {
this.confirmTheChange(data)
},
},
}),
// 取消按钮
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'md-close',
}),
style: {
border: '0',
background: 'rgba(0,0,0,0)',
fontSize: '1.3rem',
outline: 'none',
},
on: {
click: () => {
this.CancelChange(data)
},
},
}),
]
),
h(
'DropdownMenu',
{
slot: 'list',
style: {
display: 'block',
},
domProps: {
id: 'dropdown' + data.code,
},
},
[
h(
'DropdownItem',
{
style: {
fontSize: '14px !important',
color: '#333',
textAlign: 'center',
display: data.children ? 'block' : 'none',
},
nativeOn: {
click: ($event) => {
$event.stopPropagation()
this.addNode(root, node, data)
},
},
},
'添加同级目录'
),
h(
'DropdownItem',
{
style: {
fontSize: '14px !important',
color: '#1081CE',
textAlign: 'center',
},
nativeOn: {
click: ($event) => {
$event.stopPropagation()
this.addChildNode(root, node, data)
},
},
},
'添加子节点'
),
h(
'DropdownItem',
{
style: {
fontSize: '14px !important',
color: '#19BE6B',
textAlign: 'center',
},
nativeOn: {
click: ($event) => {
$event.stopPropagation()
this.editTree(data)
},
},
},
'修改'
),
h(
'DropdownItem',
{
style: {
fontSize: '14px !important',
color: '#FF0000',
textAlign: 'center',
},
nativeOn: {
click: ($event) => {
$event.stopPropagation()
this.remove(root, node, data)
},
},
},
'删除'
),
]
),
]
),
//结束
]),
]
)
},
// 添加同级目录
addNode (root, node, data) {
const children = {
expand: true,
title: '新建父节点',
id: '',
code: this.uuid(),
parentCode: '0',
children: [],
nodeKey: Number(Math.random()).toString().substr(3, length),
}
this.kindData.push(children)
},
// 添加子节点
addChildNode (root, node, data) {
data.expand = true
const children = data.children || []
children.push({
title: '新建子节点',
expand: true,
})
this.$set(data, 'children', children)
},
// Tree修改按钮
editTree (data) {
this.inputContent = data.title
this.oldName = data.title
this.setStates(data)
},
// 控制Tree当前状态函数
setStates (data) {
var editState = data.editState
if (editState) {
this.$set(data, 'editState', false)
} else {
this.$set(data, 'editState', true)
}
},
// 确认修改树节点
confirmTheChange (data) {
if (!this.inputContent) {
this.$Notice.warning({
title: '当前输入有误',
})
} else {
if (this.oldName !== this.inputContent) {
this.$Modal.confirm({
title: '提示',
content: `您确定将 “${this.oldName}” 重命名为 “ ${this.inputContent} ” 吗?`,
onOk: () => {
data.title = this.inputContent
this.$Message.info('修改成功')
},
onCancel: () => {
this.$Message.info('取消')
},
})
this.setStates(data)
} else {
this.setStates(data)
}
}
},
// 取消修改树节点
CancelChange (data) {
this.$Notice.info({
title: '取消修改',
})
this.setStates(data)
},
// 删除按钮
remove (root, node, data) {
// 1. 删除 子节点
// 2. 删除 父节点
// el===node,这个node是否含有children参数,有的话,就是删除 fu节点,没有就是删除zi节点
// 删除父节点的话 ,需要判断当前节点下所有的子节点.splice(index, node.childrem.length)
if (node.children) {
console.log("fujiedian")
var curIndex = (this.kindData || []).findIndex((el) => el.code === data.code)
this.kindData.splice(curIndex, 1)
// 根据父节点的parent去找它下面的所有子节点
// const child = root.find(el => el === node)
// console.log(parentKey)
} else {
console.log("zijiedian")
const parentKey = root.find(el => el === node).parent;
const parent = root.find(el => el.nodeKey === parentKey).node;
const index = parent.children.indexOf(data);
console.log(parentKey)
console.log(parent)
console.log(index)
parent.children.splice(index, 1);
this.$Message.info('删除成功');
}
},
submit () {
console.log(this.kindData)
}
},
}
</script>
- hover提示可操作按钮 参考博客
实现细节:
<template>
<div class="IviewTree">
<Tree :data="data5" :render="renderContent"></Tree>
</div>
</template>
<script>
export default {
data() {
return {
editState: false,
data5: [
{
title: '父节点1',
expand: true,
render: (h, { root, node, data }) => {
return h(
'span',
{
style: {
display: 'inline-block',
width: '100%',
},
},
[
h('span', [
h('Icon', {
props: {
type: 'ios-folder',
},
style: {
marginRight: '8px',
},
}),
h('span', data.title),
]),
]
)
},
children: [
{
title: '子节点1',
expand: true,
children: [
{
title: '子节点1-1',
expand: true,
},
{
title: '子节点1-2',
expand: true,
},
],
},
],
},
{
title: '父节点2',
expand: true,
render: (h, { root, node, data }) => {
return h(
'span',
{
style: {
display: 'inline-block',
width: '100%',
},
},
[
h('span', [
h('Icon', {
props: {
type: 'ios-folder',
},
style: {
marginRight: '8px',
},
}),
h('span', data.title),
]),
]
)
},
children: [
{
title: '子节点2',
expand: true,
children: [
{
title: '子节点2-1',
expand: true,
},
{
title: '子节点2-2',
expand: true,
},
],
},
],
},
],
buttonProps: {
type: 'default',
size: 'small',
},
// 输入框要修改的内容
inputContent: '',
// 修改前的TreeNode名称
oldName: '',
}
},
methods: {
// 树渲染逻辑
renderContent(h, { root, node, data }) {
return h(
'span',
{
class: 'hhhaha',
style: {
display: 'inline-block',
lineHeight: '1.6rem',
width: '100%',
cursor: 'pointer',
},
on: {
click: () => {
// 点击Tree节点触发
data.editState ? '' : this.handleClickTreeNode(data)
},
},
},
[
h('span', [
h('Icon', {
props: {
type: `${
data.children == undefined || data.children.length == 0
? 'md-document'
: 'ios-folder'
}`,
},
style: {
marginRight: '8px',
},
}),
h(`${data.editState ? '' : 'span'}`, data.title),
h(`${data.editState ? 'input' : ''}`, {
attrs: {
value: `${data.editState ? data.title : ''}`,
autofocus: 'true',
},
style: {
width: '12rem',
cursor: 'auto',
},
on: {
change: (event) => {
this.inputContent = event.target.value
},
},
}),
]),
// 增删改按钮部分
h(
`${data.editState ? '' : 'span'}`,
{
class: 'btnNone',
style: { marginLeft: '1rem' },
},
[
//操作按钮部分
// 编辑按钮
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'ios-brush-outline',
}),
style: {
marginRight: '8px',
borderRadius: '50%',
width: '1.5rem',
lineHeight: '0',
padding: '0',
height: '1.4rem',
},
on: {
click: () => {
this.editTree(data)
},
},
}),
// 添加按钮
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'ios-add',
}),
style: {
marginRight: '8px',
borderRadius: '50%',
width: '1.5rem',
lineHeight: '0',
padding: '0',
height: '1.4rem',
},
on: {
click: () => {
this.append(data)
},
},
}),
// 删除按钮
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'ios-remove',
}),
style: {
marginRight: '8px',
borderRadius: '50%',
width: '1.5rem',
padding: '0',
lineHeight: '0',
height: '1.4rem',
},
on: {
click: () => {
this.remove(root, node, data)
},
},
}),
]
),
// 确认/取消修改部分
h(
`${data.editState ? 'span' : ''}`,
{
style: {
marginLeft: '.5rem',
},
},
[
// 确认按钮
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'md-checkmark',
}),
style: {
// marginRight: '8px',
border: 0,
background: 'rgba(0,0,0,0)',
fontSize: '1.3rem',
outline: 'none',
},
on: {
click: (event) => {
this.confirmTheChange(data)
},
},
}),
// 取消按钮
h('Button', {
props: Object.assign({}, this.buttonProps, {
icon: 'md-close',
}),
style: {
border: '0',
background: 'rgba(0,0,0,0)',
fontSize: '1.3rem',
outline: 'none',
},
on: {
click: () => {
this.CancelChange(data)
},
},
}),
]
),
]
)
},
// 控制Tree当前状态函数
setStates(data) {
var editState = data.editState
if (editState) {
this.$set(data, 'editState', false)
} else {
this.$set(data, 'editState', true)
}
},
// Tree修改按钮
editTree(data) {
event.stopPropagation()
this.inputContent = data.title
this.oldName = data.title
this.setStates(data)
},
// 添加按钮
append(data) {
event.stopPropagation()
const children = data.children || []
children.push({
title: '新建节点',
expand: true,
})
this.$set(data, 'children', children)
},
// 删除按钮
remove(root, node, data) {
event.stopPropagation()
this.$Modal.confirm({
title: '提示',
content: `您确定删除 “${data.title}” 吗?`,
onOk: () => {
const parentKey = root.find((el) => el === node).parent
const parent = root.find((el) => el.nodeKey === parentKey).node
const index = parent.children.indexOf(data)
parent.children.splice(index, 1)
this.$Message.info('删除成功')
},
onCancel: () => {
this.$Message.info('取消')
},
})
},
// 确认修改树节点
confirmTheChange(data) {
if (!this.inputContent) {
this.$Notice.warning({
title: '当前输入有误',
})
} else {
if (this.oldName !== this.inputContent) {
this.$Modal.confirm({
title: '提示',
content: `您确定将 “${this.oldName}” 重命名为 “ ${this.inputContent} ” 吗?`,
onOk: () => {
data.title = this.inputContent
this.$Message.info('修改成功')
},
onCancel: () => {
this.$Message.info('取消')
},
})
this.setStates(data)
} else {
this.setStates(data)
}
}
},
// 取消修改树节点
CancelChange(data) {
this.$Notice.info({
title: '取消修改',
})
this.setStates(data)
},
// 点击Tree节点触发
handleClickTreeNode(data) {
console.log('当前点击》》' + data.title)
},
},
}
</script>
<style>
.IviewTree {
width: 300px;
text-align: left;
margin: 0 auto;
}
.btnNone {
display: none;
}
/* .hhhaha:hover{color:aqua} */
.hhhaha:hover .btnNone {
display: inline-block;
}
.hhhaha:hover {
font-weight: 600;
color: #275cd4;
}
.ivu-tree ul li {
list-style: none;
/* margin: 8px 0; */
padding: 0;
white-space: nowrap;
outline: none;
}
</style>