一、效果
具备功能:
- 新增根节点、刷新树、展开全部
- 新增子节点、编辑、删除
2、组件
<template>
<div class="white-body-view">
<el-tree id="my-tree"
ref="tree"
class="tree-view structure-tree scroll-bar"
:data="treeData"
highlight-current
:default-expand-all="treeExpandAll"
:props="defaultProps"
check-strictly
:default-expanded-keys="[1,2]"
:node-key="treeNodeKey"
@node-click="handleNodeClick"
:auto-expand-parent="false"
:expand-on-click-node="false">
<span slot-scope="{ node, data }"
class="custom-tree-node">
<span class="tooltip">
<span class="add-f-s-14">{
{ data.name }}</span>
</span>
<div v-if="node.isCurrent === true&&itemShow===true"
class="operation-view">
<i style="color:#ffffff"
class="small-operation-btn el-icon-plus"
@click.stop="handleAdd(data)" />
<i style="color:#ffffff"
class="small-operation-btn el-icon-edit"
@click.stop="handleEdit(data)" />
<i style="color:#ffffff"
class="small-operation-btn el-icon-delete"
@click.stop="handleDelete(data)" />
</div>
</span>
</el-tree>
</div>
</template>
<script>
export default {
props: {
// 列表数据
treeData: {
type: Array,
default: function () {
return []
}
},
// 树节点是否默认展开
treeExpandAll: {
type: Boolean,
default: true
},
// 树节点唯一标识
treeNodeKey: {
type: String,
default: ''
},
// 子节点展示新增删除编辑图标
itemShow: {
type: Boolean,
default: true
}
},
data () {
return {
defaultProps: {
children: 'children',
label: 'name'
},
selectItem: {}
}
},
watch: {
treeExpandAll (e) {
this.treeExpandAll = e
console.log(e)
}
},
mounted () {
},
methods: {
// 添加新增按钮
handleAdd (data) {
this.$emit('addItem', data)
},
// 点击删除按钮
handleDelete (data) {
this.$emit('deleteItem', data)
},
// 点击编辑按钮
handleEdit (data) {
this.selectItem = data
this.$emit('editItem', JSON.parse(JSON.stringify(data)))
},
// ============== 组件内事件 结束=============
// ============== -----------------------------------父组件回调事件 开始=============
// 添加新记录,树形列表回显
treeAddItem (data) {
this.$refs.tree.append(data, data.parentUid)
},
// 选中事件
handleNodeClick (data) {
this.$emit('handleNodeClick', data)
},
// 删除节点
treeDeleteItem (val) {
this.$refs.tree.remove(val)
},
// 修改记录,树形列表回显
treeEditItem (val) {
Object.assign(this.selectItem, val)
this.selectItem = {}
}
// ============== 父组件回调事件 结束=============
}
}
</script>
<style lang="scss" scoped>
.white-body-view {
width: 100%;
min-width: 320px;
}
.structure-tree {
.el-scrollbar .el-scrollbar__wrap {
overflow-x: hidden;
}
#my-tree .el-tree > .el-tree-node {
min-width: 100%;
display: inline-block;
}
.el-tree-node__content {
margin-bottom: 10px;
}
.tooltip {
margin-right: 5px;
font-size: 13px;
border-radius: 4px;
box-sizing: border-box;
white-space: nowrap;
padding: 4px;
}
.operation-view {
display: inline-block;
padding: 0px 5px;
margin-left: 5px;
color: #777777;
}
.small-operation-btn {
margin: 0px 3px;
}
}
.el-icon-plus:hover {
color: #1c92e0;
}
.el-icon-edit:hover {
color: #1c92e0;
}
.el-icon-delete:hover {
color: #1c92e0;
}
::v-deep .el-tree {
color: #333333;
}
</style>
3、使用
<el-col :span="7">
<el-card class="box-card">
<div slot="header"
class="clearfix">
<el-button size="mini"
type="primary"
@click="addTree">添加</el-button>
<el-button size="mini"
type="info"
@click="resetQuery"
style="margin-right:10px">刷新</el-button>
<el-checkbox v-model="checked"
@change="getTask">全部展开</el-checkbox>
</div>
<div class="scroll-bar item">
<PubliceTree v-if="refreshTable"
ref="customTree"
:itemShow="itemShow"
:tree-data="treeData"
:tree-expand-all="treeExpandAll"
:tree-node-key="treeNodeKey"
@handleNodeClick='handleNodeClick'
@addItem="addTreeItem"
@deleteItem="deleteTreeItem"
@editItem="editTreeItem">
</PubliceTree>
</div>
</el-card>
</el-col>
<!-- 新增 -->
<AddTask ref="placeDialog"
@addData="addData"
@editData="editData"></AddTask>
<script>
import PubliceTree from '@/views/components/publice/publiceTree';
import AddTask from '@/views/assessment_library/components/addTask';
export default {
components: { PubliceTree, AddTask },
data () {
return {
checked: false,
itemShow: true,
treeExpandAll: false,
refreshTable: true,
treeNodeKey: 'uid',
treeData: [],
};
},
created () { },
mounted () {
this.getTreeselect();
},
methods: {
resetQuery () {
this.getTreeselect();
},
// 查询左侧tree下拉树结构
getTreeselect () {
treeselect().then(response => {
this.treeData = this.handleTree(response.data, 'uid', 'parentUid', 'children');
// 选择顶级节点展示
this.formTableData = [{ uid: 0, name: '顶级', children: this.treeData }];
});
},
// 展开全部
getTask () {
this.refreshTable = false;
this.treeExpandAll = !this.treeExpandAll;
// this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行,类似全局刷新
this.$nextTick(() => {
this.refreshTable = true;
});
},
// 选中每一个子节点---对应右边明细
handleNodeClick (data) {
getDetail({ uid: data.uid }).then(response => {
this.formItem = {
allFlag: response.data.allFlag,
sort: response.data.sort,
name: response.data.name,
stander: response.data.stander,
parentUid: response.data.parentUid,
uid: response.data.uid
};
if (response.data.parentUid === 0) {
this.formItem.parentName = response.data.name;
} else {
this.formItem.parentName = response.data.parentName;
}
});
},
// 弹框------------------------新增表单数据
addData (data) {
// this.$refs.customTree.treeAddItem(data)
this.getTreeselect();
this.clean();
},
// 弹框-------------------------修改表单数据
editData (data) {
this.$refs.customTree.treeEditItem(data);
this.handleNodeClick(data);
},
addTree () {
this.$refs.placeDialog.openDialog(false, '', {}, this.formTableData);
},
// ----------------增加树节点设置默认父级节点
addTreeItem (data) {
this.$refs.placeDialog.openDialog(false, data.uid, data, undefined);
},
// ----------------修改树节点
editTreeItem (data) {
this.$refs.placeDialog.openDialog(true, data.uid, data, undefined);
},
// ---删除树节点
deleteTreeItem (data) {
this.$confirm('确认要删除当前节点 ' + data.name + ' 吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
// 删除树节点
DeleteTreeselect({ uid: data.uid }).then(response => {
this.$message({ type: 'success', message: '删除成功' });
this.clean();
this.$refs.customTree.treeDeleteItem(data);
});
})
.catch(() => { });
},
}
};
</script>
addTask.vue
<template>
<el-dialog :title="title"
:visible.sync="modal_infos"
width="600px"
:close-on-click-modal="false"
:loading="loading"
left
append-to-body>
<el-form ref="formItem"
:model="formItem"
label-width="100px">
<el-form-item label="上级:"
:rules="{ required: true, message: '请输入上级', trigger: 'blur' }"
:prop="treeData === undefined ?'parentName' : 'parentUid'">
<el-input v-show="treeData === undefined"
v-model="formItem.parentName"
:readonly="true"
style="width:95%"
placeholder="请输入" />
<treeselect v-show="treeData !== undefined"
v-model="formItem.parentUid"
:options="treeData"
:searchable="false"
:clearable="false"
:normalizer="normalizer"
placeholder="请选择" />
</el-form-item>
<el-form-item label="名称:"
:rules="{ required: true, message: '请输入名称', trigger: 'blur' }"
prop="name">
<el-input v-model="formItem.name"
maxlength="20"
show-word-limit
style="width:95%"
placeholder="请输入" />
</el-form-item>
<el-form-item label="排序:"
:rules="{ required: true, message: '请输入排序', trigger: 'blur' }"
prop="sort">
<el-input-number size="small"
:min="0"
v-model="formItem.sort"></el-input-number>
</el-form-item>
<el-form-item label="启用:"
:rules="{ required: true, message: '请选择启用', trigger: 'blur' }"
prop="allFlag">
<el-select v-model="formItem.allFlag"
placeholder="请选择"
style="margin-right:10px;">
<el-option value="1"
label="是">是</el-option>
<el-option value="0"
label="否">否</el-option>
</el-select>
</el-form-item>
<el-form-item label="考核标准:"
prop="stander">
<el-input v-model="formItem.stander"
type="textarea"
maxlength="255"
style="width:95%"
placeholder="请输入(255字以内...)" />
</el-form-item>
</el-form>
<div slot="footer"
style="text-align:center">
<el-button :loading='ldstatus'
@click="submitForm"
type="success"
size="small">提交</el-button>
<el-button @click="clean"
size="small">关闭</el-button>
</div>
</el-dialog>
</template>
<script>
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
import { getDetail, AddTreeselect, EditTreeselect } from '@/api/assessment_library/index.js'
export default {
components: { Treeselect },
data () {
return {
modal_infos: false,
loading: false,
title: '',
ldstatus: false,
isEdit: false,
parentId: '',
data: {},
treeData: undefined,
formItem: {
allFlag: '1',
sort: 0,
name: undefined,
parentUid: undefined,
stander: undefined,
parentName: undefined
},
};
},
created () { },
mounted () { },
methods: {
// 转换类型数据结构
normalizer (node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.uid,
label: node.name,
children: node.children
};
},
/**
* @description 打开弹窗
* @param { Boolean } isEdit 是否是修改状态 true 修改 / false 新增
* @param { String } parentId 父级id,新增时默认选中父级时使用
* @param { Object } data 表单数据,编辑时使用
* @param { Object } formTableData tree数据,全局添加时使用
*/
openDialog (isEdit, parentId, data, formTableData) {
this.parentId = parentId
this.data = data
this.isEdit = isEdit
this.title = isEdit ? '编辑' : '新增'
this.initFormData()
this.modal_infos = true
if (isEdit) {
getDetail({ uid: this.parentId }).then(response => {
this.formItem = {
allFlag: response.data.allFlag,
sort: response.data.sort,
name: response.data.name,
stander: response.data.stander,
parentUid: response.data.parentUid,
uid: response.data.uid,
parentName: response.data.parentName
}
})
} else {
if (formTableData !== undefined) {
console.log('ad')
this.treeData = formTableData
this.formItem = {
allFlag: '1',
sort: 0,
name: undefined,
parentUid: undefined,
stander: undefined,
parentName: undefined
}
} else {
this.formItem = {
allFlag: '1',
sort: this.data.sort,
name: '',
stander: '',
parentUid: this.data.uid,
parentName: this.data.name
}
}
}
},
/** 提交按钮 */
submitForm () {
this.$refs.formItem.validate((valid) => {
if (valid) {
const formData = JSON.parse(JSON.stringify(this.formItem))
if (this.isEdit) {
this.ldstatus = true;
EditTreeselect(this.formItem).then(response => {
this.ldstatus = false;
this.msgSuccess('修改成功')
this.$emit('editData', formData)
}).catch(error => {
this.ldstatus = false;
console.log(error);
});
} else {
this.ldstatus = true;
AddTreeselect(this.formItem).then(response => {
this.ldstatus = false;
this.msgSuccess('新增成功')
this.$emit('addData', formData, )
})
.catch(error => {
this.ldstatus = false;
console.log(error);
});
}
this.clean()
}
})
},
// 关闭
clean () {
this.$refs.formItem.resetFields()
this.modal_infos = false
},
// 清楚表单
initFormData () {
this.formItem = {
allFlag: '1',
sort: 0,
name: undefined,
uid: undefined,
parentUid: undefined,
parentName: undefined
}
}
}
};
</script>
<style lang="scss" scoped>
::v-deep label {
font-weight: 400;
}
</style>