使用iview实现树的增删改

1 篇文章 0 订阅

先上代码

<template>
  <div>
    <template v-slot:content>
      <Tree :data="data5" :render="renderContent"></Tree>
    </template>
    <template v-slot:footer></template>
  </div>
</template>

<script>

export default {
  name: 'drawer-oepn-menu',
  props: {
    show: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      editState: false,
      data5: [
        {
          id: null,
          title: '全部',
          expand: true,
          // eslint-disable-next-line no-unused-vars
          render: (h, { root, node, data }) => {
            return h('span', {
              style: {
                display: 'inline-block',
                width: '100%'
              }
            }, [
              h('span', [
                h( "span", data.title)
              ]) 
            ]);
          },
          children: [
            {
              id: 1,
              title: '子',
              expand: true
            },
            {
              id: 2,
              title: '子2',
              expand: true
            }
          ]
        }
      ],
      buttonProps: {
        type: 'default',
        size: 'small'
      },
      // 输入框要修改的内容
      inputContent: "",
      // 修改前的TreeNode名称
      oldName: ""
    }
  },
  methods: {
    handleClose() {
      this.$emit('close')
    },
    // 树渲染逻辑
    renderContent(h, { root, node, data }) {
      return h("span", {
        class: "menu-tree",
        style: {
          display: 'inline-block',
          lineHeight: '1.6rem',
          width: '100%',
          cursor: 'pointer'
        },
        on: {
          click: () => {
            // 点击Tree节点触发
            data.editState ? '' : this.handleClickTreeNode(data)
          }
        }
      }, [
        h('span', [
          h(`${data.editState ? '' : 'span'}`, data.title),
          // 使用this.$createElement创建的节点可以获取到$ref,避免使用h无法获取到的bug
          this.$createElement(`${data.editState ? 'Input' : ''}`,
            {
              attrs: {
                value: `${data.editState ? data.title : ''}`,
                autofocus: true
              },
              ref: 'slotTreeInput' + data.id,
              style: {
                width: '12rem',
                cursor: 'auto'
              },
              on: {
                'on-change': (event) => {
                  this.inputContent = event.target.value
                },
                'on-blur': () => {
                  this.confirmTheChange(data)
                },
                // eslint-disable-next-line no-undef
                'on-enter': (event) => {
                  event.target.blur()
                }
              }
            }
          )
        ]),
        // 增删改按钮部分
        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: () => {
                  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);
        this.$nextTick(() => {
          if (this.$refs['slotTreeInput' + data.id]) {
            this.$refs['slotTreeInput' + data.id].focus()
          }
        }) 
      }
    },
    // 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 {
        data.title = this.inputContent
        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
}
/* .menu-tree:hover{color:aqua} */
.menu-tree:hover .btnNone{
   display: inline-block
}

.menu-tree:hover {
   font-weight: 600;
   color:#275cd4
}
.ivu-tree ul li {
    list-style: none;
    /* margin: 8px 0; */
    padding: 0;
    white-space: nowrap;
    outline: none;
}
</style>

最终所需要的效果图

<template>
  <div>
    <template v-slot:content>
      <Button @click="append" v-if="data5[0].children.length < 29">添加</Button>
      <Tree :data="data5" :render="renderContent"></Tree>
    </template>
    <template v-slot:footer></template>
  </div>
</template>

<script>

export default {
  name: 'drawer-oepn-menu',
  props: {
    show: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      editState: false,
      NODE_ID_START: 100,
      startId: null,
      data5: [
        {
          id: null,
          title: '全部',
          expand: true,
          // eslint-disable-next-line no-unused-vars
          render: (h, { root, node, data }) => {
            return h('span', {
              style: {
                display: 'inline-block',
                width: '100%'
              }
            }, [
              h('span', [
                h( "span", data.title)
              ]) 
            ]);
          },
          children: [
            {
              id: null,
              title: 'default',
              expand: true
            }
          ]
        }
      ],
      buttonProps: {
        type: 'default',
        size: 'small'
      },
      // 输入框要修改的内容
      inputContent: "",
      // 修改前的TreeNode名称
      oldName: ""
    }
  },
  watch: {
    show (val) {
      if (!val) { return }
      this.startId = this.NODE_ID_START
    }
  },
  methods: {
    handleClose() {
      this.$emit('close')
    },
    // 树渲染逻辑
    renderContent(h, { root, node, data }) {
      return h("span", {
        class: "menu-tree",
        style: {
          display: 'flex',
          lineHeight: '1.6rem',
          width: '100%',
          cursor: 'pointer',
          'min-width': '100px',
          'min-height': '20px',
          'justify-content': 'space-between'
        },
        on: {
          click: () => {
            // 点击Tree节点触发
            this.handleClickTreeNode(data)
          }
        }
      }, [
        h('span', [
          h(`${data.editState ? '' : 'span'}`, data.title),
          // 使用this.$createElement创建的节点可以获取到$ref,避免使用h无法获取到的bug
          this.$createElement(`${data.editState ? 'Input' : ''}`,
            {
              'class': {
                'err-input': data.title.length < 2 || data.title.length > 15
              },
              attrs: {
                value: `${data.editState ? data.title : ''}`,
                autofocus: true,
                placeholder: this.$t('2~15位字符')
              },
              ref: 'slotTreeInput' + data.id,
              style: {
                width: '12rem',
                cursor: 'auto'
              },
              on: {
                'on-change': (event) => {
                  this.handleInputChange(event, data)
                },
                'on-blur': () => {
                  this.confirmTheChange(data)
                },
                // eslint-disable-next-line no-undef
                'on-enter': (event) => {
                  event.target.blur()
                }
              }
            }
          )
        ]),
        // default教室只允许编辑
        h(`${!data.editState && data.id === null ? 'span' : ''}`, {
          class: "btnNone",
          style: { marginLeft: '1px' }
        }, [
          //操作按钮部分 
          // 编辑按钮
          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(`${!data.editState && data.id !== null ? '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-remove'
            }),
            style: {
              marginRight: '8px',
              borderRadius: '50%',
              width: '1.5rem',
              padding: '0',
              lineHeight: '0',
              height: '1.4rem'
            },
            on: {
              click: () => { this.remove(root, node, data) }
            }
          })
        ])
      ]);
    },
    // 控制Tree当前状态函数
    setStates(data) {
      var editState = data.editState
      if (editState) {
        this.$set(data, 'editState', false);
      } else {
        this.$set(data, 'editState', true);
        this.$nextTick(() => {
          if (this.$refs['slotTreeInput' + data.id]) {
            this.$refs['slotTreeInput' + data.id].focus()
          }
        }) 
      }
    },
    // Tree修改按钮
    editTree(data) {
      event.stopPropagation()
      this.inputContent = data.title
      this.oldName = data.title
      this.setStates(data)
    },
    // 添加按钮
    append() {
      event.stopPropagation()
      this.oldName = ''
      let children = this.data5[0].children
      let data = {
        title: '',
        id: ++this.startId,
        expand: true
      }
      children.push(data);
      this.setStates(data)
      // this.$set(data, 'children', children);
    },
    // 删除按钮
    remove(root, node, data) {
      event.stopPropagation()
      this.$Modal.confirm({
        content: `确定删除目录吗,如果改目录下有开放的模板,则该目录下的所有模板将移入${this.data5[0].children[0].title}目录`,
        loading: true,
        onOk: () => {
          setTimeout(() => {
            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.$Modal.remove();
          }, 1000);
        }
      });
    },
    // 确认修改树节点
    confirmTheChange(data) {
      console.log(this.oldName)
      if (this.inputContent.length > 15 || (this.inputContent.length > 0 && this.inputContent.length < 2)) { return }
      let arr = this.data5[0].children.map(item => item.title)
      if (arr.findIndex(x => x === this.inputContent) !== -1 && this.inputContent !== this.oldName) {
        return this.$Notice.open({
          title: '目录已存在',
          desc: '',
          duration: 0
        });
      }
      if (!this.inputContent && this.oldName.length === 0) {
        this.data5[0].children.splice(this.data5[0].children.findIndex(x => x.title === ''), 1)
      } else if (!this.inputContent && this.oldName) {
        return
      } else {
        data.title = this.inputContent
        this.setStates(data);
      }
      this.inputContent = ''
      this.oldName = ''
    },
    // 点击Tree节点触发
    handleClickTreeNode(data) {
      console.log("当前点击》》" + data.title)
      this.oldName = data.title
    },
    handleInputChange(e, data) {
      console.log(data.title)
      this.inputContent = event.target.value.replace(/\s*/g, "")
      if (this.inputContent.length < 2 || this.inputContent.length > 15) {
        event.target.classList.add('err-input') 
      } else {
        event.target.classList.remove('err-input')
      }
    }
  }
}
</script>

<style>
.IviewTree{
    width: 300px;
    text-align: left;
    margin: 0 auto;
}
.btnNone{
    display:none
}
/* .menu-tree:hover{color:aqua} */
.menu-tree:hover .btnNone{
   display: inline-block
}

.menu-tree:hover {
   font-weight: 600;
   color:#275cd4
}
.ivu-tree ul li {
    list-style: none;
    /* margin: 8px 0; */
    padding: 0;
    white-space: nowrap;
    outline: none;
}

.err-input.ivu-input  {
  border: 1px solid red;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值