弹窗组件
<template>
<div id="dialogCatalog">
<el-dialog
title="产品目录管理"
:close-on-click-modal="false"
:close-on-press-escape="false"
:visible.sync="dialogVisible"
width="500px"
:before-close="handleClose">
<div v-loading="isLoading" class="comp-tree">
<!-- <el-button class="comp-tr-top"
type="primary"
size="small"
@click="handleAddTop">添加顶级节点</el-button> -->
<!-- tree -->
<el-tree ref="SlotTree"
:data="setTree"
:props="defaultProps"
default-expand-all
:expand-on-click-node="false"
highlight-current
:node-key="NODE_KEY">
<div class="comp-tr-node" slot-scope="{ node, data }">
<!-- 编辑状态 -->
<template v-if="data.isEdit">
<el-input v-model="data.name"
autofocus
size="mini"
maxlength='20'
:class="isClassName"
@input="handleInput(node, data)"
minlength='2'
:ref="'slotTreeInput'+data[NODE_KEY]"
@blur.stop="nodeEditPass(node, data)"
@keyup.enter.native="$event.target.blur()"></el-input>
</template>
<!-- 非编辑状态 -->
<template v-else>
<!-- 名称: 新增节点增加class(is-new) -->
<span class="comp-tr-node--name">
{{ node.label }}
</span>
<!-- 按钮 -->
<span class="comp-tr-node--btns">
<!-- 新增 -->
<el-button icon="el-icon-plus"
v-if="!(node.level ==2 && node.data.name=='default') && node.level !==3"
size="mini"
@click="handleAdd(node, data)"></el-button>
<!-- 编辑 -->
<el-button icon="el-icon-edit"
v-if="node.level !==1 &&!(node.level ==2 && node.data.name=='default')"
size="mini"
@click="handleEdit(node, data)"></el-button>
<!-- 删除 -->
<el-button icon="el-icon-delete"
v-if="node.level !==1&&!(node.level ==2 && node.data.name=='default')"
size="mini"
@click="handleDelete(node, data)"></el-button>
</span>
</template>
</div>
</el-tree>
</div>
<div>注意:删除目录后,该目录下的所有产品将移入default目录</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleClose()">关闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import * as launch from '@/api/admin/launch.js'
export default {
name: 'DialogCatalog',
props: {
isDialogCatalog: {
type: Boolean,
default: false
}
},
watch: {
isDialogCatalog: function () {
if (!this.isDialogCatalog) { return }
this.getCatalogTree()
this.dialogVisible = this.isDialogCatalog
this.startId = this.NODE_ID_START
}
},
data () {
return {
dialogVisible: false,
parallelTree: [],
choiseTree: {},
isLoading: false, // 是否加载
setTree: [], // tree数据
NODE_KEY: 'id', // id对应字段
MAX_LEVEL: 3, // 设定最大层级
NODE_ID_START: 100, // 新增节点id,逐次递减
startId: null,
defaultProps: { // 默认设置
children: 'children',
label: 'name'
},
initParam: { // 新增参数
name: '目录',
pid: 0,
isEdit: true,
children: []
},
isClassName: '',
isUpdata: false
}
},
methods: {
getCatalogTree () {
launch.getCatalogTree().then(res => {
this.setTree = JSON.parse(JSON.stringify(res.data))
})
},
handleNodeClick (d, n, s) { // 点击节点
d.isEdit = false// 放弃编辑状态
},
handleClose () {
this.dialogVisible = false
this.$emit('data_close')
},
handleInput (_node, _data) {
if (_data.name.trim().length < 2 || _data.name.trim().length > 20 || _node.parent.data.children.some(x => x.name === _data.name && x.id !== _data.id)) {
this.isClassName = 'is_error'
} else {
this.isClassName = ''
}
},
handleDelete (_node, _data) { // 删除节点
console.log(_node, _data)
// 二次确认
const ConfirmFun = () => {
this.$confirm('是否删除此节点?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
launch.delMenu(_data.id).then(res => {
this.getCatalogTree()
})
}).catch(() => {})
}
// // 判断是否新增: 新增节点直接删除,已存在的节点要二次确认
// _data[this.NODE_KEY] < this.NODE_ID_START ? DeletOprate() : ConfirmFun()
ConfirmFun()
},
// 退出编辑状态
nodeEditPass (_node, _data) { // 修改节点
if (this.isClassName.length !== 0) { return }
console.log(_data)
if (this.isUpdata) {
const obj = {
label: _data.label,
isEdit: false,
pid: _data.pid,
children: []
}
launch.updataMenu(obj).then(res => {
this.isUpdata = false
if (_data.isEdit) {
this.$set(_data, 'isEdit', false)
}
})
} else {
const obj = {
id: _data.id,
label: _data.label,
isEdit: false,
pid: _data.pid,
children: _data.children
}
launch.addMenu(obj).then(res => {
if (_data.isEdit) {
this.$set(_data, 'isEdit', false)
}
})
}
if (_data.isEdit) {
this.$set(_data, 'isEdit', false)
}
},
handleEdit (_node, _data) { // 编辑节点
this.isUpdata = true
if (!_data.isEdit) {
this.$set(_data, 'isEdit', true)
}
_data.isEdit = true
// 输入框聚焦
this.$nextTick(() => {
if (this.$refs['slotTreeInput' + _data[this.NODE_KEY]]) {
this.$refs['slotTreeInput' + _data[this.NODE_KEY]].$refs.input.focus()
}
})
},
handleAdd (_node, _data) { // 新增节点
this.isUpdata = false
// 判断层级
if (_node.level >= this.MAX_LEVEL) {
this.$message.warning('当前已达到' + this.MAX_LEVEL + '级,无法新增!')
return false
}
// 判断是否存在
// if (this.handleIsTreeItem(_data.name)) { return false }
// 参数修改
const obj = JSON.parse(JSON.stringify(this.initParam))// copy参数
obj.pid = _data[this.NODE_KEY]// 父id
obj[this.NODE_KEY] = ++this.startId// 节点id:逐次递减id
// 判断是否存在
console.log(_data.children)
for (let i = 1; i < 100; i++) {
obj.name = '目录' + i
if (!_data.children.some(x => x.name === obj.name)) {
break
}
}
// 判断字段是否存在
if (!_data.children) {
this.$set(_data, 'children', [])
}
// 展开节点
if (!_node.expanded) {
_node.expanded = true
}
// 新增数据
_data.children.push(obj)
}
// handleAddTop () { // 添加顶部节点
// const obj = JSON.parse(JSON.stringify(this.initParam))// copy参数
// obj[this.NODE_KEY] = --this.startId// 节点id:逐次递减id
// this.setTree.push(obj)
// }
}
}
</script>
<style lang="less" scoped>
.comp-tree .comp-tr-node .comp-tr-node--btns {
margin-left: 10px;
opacity: 0;
transition: opacity 0.1s;
}
/* common */
.show-btns,
.comp-tree .is-current > .el-tree-node__content .comp-tr-node--btns,
.comp-tree .el-tree-node__content:hover .comp-tr-node--btns {
opacity: 1;
}
/* common end */
.comp-tree {
width: auto;
max-width: 700px;
max-height: 80vh;
padding: 0;
overflow: auto;
}
.comp-tree .comp-tr-top {
width: 100px;
margin-bottom: 2em;
}
.comp-tree .comp-tr-node .is_error .el-input__inner {
border: 1px solid #ff2020;
}
.comp-tree .comp-tr-node .comp-tr-node--name {
display: inline-block;
line-height: 40px;
min-height: 40px;
}
.comp-tree .comp-tr-node .comp-tr-node--btns .el-button {
transform: scale(0.8);
border: 0;
padding: 0 5px;
background: none;
}
.comp-tree .comp-tr-node .comp-tr-node--btns .el-button + .el-button {
margin-left: -1px;
}
</style>