1.安装依赖:
npm install vue-jsmind
2.在main.js中引入:
import jm from 'vue-jsmind'
Vue.use(jm)
if (window.jsMind) {
Vue.prototype.jsMind = window.jsMind
}
3.拖拽完成时间需要引入文件jsmindDrag.js,下载地址:
https://download.csdn.net/download/qq_40364610/85218557
4.数据格式:
{
"data": [
{
"children": [
{
"children": [
{
"id": "8",
"topic": "专家信息"
}
],
"id": "3",
"topic": "教师信息"
},
{
"children": [],
"id": "4",
"topic": "人才称号"
},
{
"children": [
{
"id": "9",
"topic": "教学团队"
}
],
"id": "5",
"topic": "创新团队"
}
],
"id": "1",
"topic": "师资队伍"
},
{
"children": [
{
"children": [],
"id": "6",
"topic": "国家级科研教学平台"
},
{
"children": [],
"id": "7",
"topic": "学科平台"
}
],
"id": "2",
"topic": "支撑平台"
}
]
}
5.完整代码:
<template>
<div class="app-container">
<div class="header">
<div style="float: right;margin: 10px 20px 0px 0px;display:inline-block;">
<el-button type="primary" class="noimpor-btn" @click="addNode"><i class="el-icon-plus"></i> 添加节点</el-button>
<el-button type="primary" class="noimpor-btn" @click="editNode"><i class="el-icon-edit"></i> 编辑节点</el-button>
<el-button type="primary" class="noimpor-btn" @click="onRemoveNode"><i class="el-icon-minus"></i> 删除节点
</el-button>
<el-divider direction="vertical"></el-divider>
<!-- <el-button type="primary" class="common-btn" @click='saveMind'><i class="el-icon-s-claim"></i> 保存</el-button>-->
<el-button type="primary" class="danger-btn" @click='deleteMind' :disabled="formData.id === ''?true:false"><i
class="el-icon-delete"></i> 删除
</el-button>
</div>
</div>
<js-mind :values="mind" :options="options" ref="jsMind" :height="mindHeight"></js-mind>
<el-dialog title="编辑节点" :visible.sync="dialogVisible" width="30%" :close-on-click-modal="false">
<el-form ref="nodeForm" :model="nodeOption" :rules="rules" label-width="80px">
<el-form-item label="目录名称" prop="targetName">
<el-input v-model="nodeOption.targetName" style="width: 60%"></el-input>
</el-form-item>
<el-form-item label="目录顺序" prop="order">
<el-input style="width: 200px" type="number" v-model="nodeOption.order"></el-input>
</el-form-item>
<el-form-item label="表关联" prop="connect" style="text-align: left">
<el-select
clearable
v-model="nodeOption.connect"
:disabled="tableDisabled"
filterable
remote
reserve-keyword
:popper-append-to-body="true"
:remote-method="remoteMethod"
:default-first-option="true"
placeholder="请选择"
v-el-select-loadmore="loadMore">
<el-option
v-for="item in tableOptions"
:key="item.tableId"
:label="item.tableDesc"
:value="item.tableId">
</el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" class="common-btn" @click="sureEditNode('nodeForm')">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import '@/utils/directive'
import {treeIndex, addIndex, tableList, deleteIndex, queryIndex, updateIndex,moveIndex} from "@/api/config/targetConfig"
require("./component/jsmindDrag")
export default {
name: 'targetConfig',
inject: ['reload'],
data() {
return {
currentSpaceId:"",
tableDisabled: false,
tablePage: 0,
tableOptions: [],
optionTotal: 0,
dialogVisible: false,
nodeOption: {
order: '',
connect: '',
targetName: ""
},
defaultTableList: [],
rules: {
targetName: [
{required: true, message: '请输入目录名称', trigger: 'blur'},
],
order: [
{required: true, message: '顺序不能为空', trigger: 'blur'},
],
},
theme_value: '',
mindHeight: 'calc(100vh - 127px)',
themOptions: ['primary', 'warning', 'danger', 'success', 'info', 'greensea', 'nephrite', 'belizehole', 'wisteria', 'asphalt', 'orange', 'pumpkin', 'pomegranate', 'clouds', 'asbestos'],
mind: {
meta: {
name: 'jsMind remote',
author: '[email protected]',
version: '0.2'
},
format: 'node_tree',
data: {
id: "0",
topic: "根目录",
children: []
}
},
options: {
container: 'jsmind_container', // [必选] 容器的ID
shortcut: { //禁用快捷键
enable: false
},
editable: false, // [可选] 是否启用编辑
theme: 'info' // [可选] 主题
},
formData: {
id: '',
mindCode: '',
mindName: '',
mindType: '',
mindData: '',
mindOptions: ''
},
mindOptions: {
theme: ''
},
treeData: [],
defaultProps: {
children: 'children',
label: 'name'
},
color: 'rgba(255, 69, 0, 0.68)',
predefineColors: [
'#ff4500',
'#ff8c00',
'#ffd700',
'#90ee90',
'#00ced1',
'#1e90ff',
'#c71585',
'rgba(255, 69, 0, 0.68)',
'rgb(255, 120, 0)',
'hsv(51, 100, 98)',
'hsva(120, 40, 94, 0.5)',
'hsl(181, 100%, 37%)',
'hsla(209, 100%, 56%, 0.73)',
'#c7158577'
]
}
},
computed: {
spaceId() {
return this.$store.state.user.spaceId
}
},
watch:{
spaceId(newVal){
this.reload()
}
},
mounted() {
this.currentSpaceId = this.$store.state.user.spaceId? this.$store.state.user.spaceId:localStorage.getItem("spaceId")
this.jm = this.$refs.jsMind.jm
this.jm.enable_edit()
this.jm.enable_event_handle('dblclick')
this.getMind()
let that = this
Object.defineProperties(jsMind.dragObj, { //拖拽完成事件
target_direct: {
configurable: true,
set: function (newValue) {
let target_direct = newValue;
that.moveHandle(target_direct)
}
},
});
Object.defineProperties(jsMind.dragObj, { //点击事件
edit_value: {
configurable: true,
set: function (newValue) {
// let edit_value = newValue;
that.$nextTick(()=>{
that.dblclickEditHandle(newValue)
})
}
}
})
},
methods: {
dblclickEditHandle(newValue) {
let param = {
indexId: newValue.id,
indexName: newValue.topic,
sortIndex: ""
};
// console.log(param,"途经此处")
updateIndex(param).then(res => {
this.getMind()
})
},
loadMore() {
if (this.tableOptions.length < this.optionTotal) {
this.tablePage++
this.getTableConnect()
}
},
remoteMethod(query) {
this.tablePage = 0
this.nodeOption.tableDesc = query.trimStart()
this.tableOptions = []
this.getTableConnect()
},
getTableConnect() {
let param = {
page: this.tablePage,
size: 10,
tableDesc: this.nodeOption.tableDesc,
spaceId: this.currentSpaceId,
}
let selectedId = this.get_selected_nodeid()
const nodeObj = this.jm.get_node(selectedId)
if (nodeObj.children != null && nodeObj.children.length > 0) {
param = { ...param, sourceType: '20' }
}
tableList(param).then(res => {
this.optionTotal = res.totalElements
if (this.tablePage === 0 && !this.nodeOption.tableDesc) {
this.tableOptions = [ ...this.defaultTableList ]
}
let newContent = res.content.filter(item => { return item.tableId != this.nodeOption.connect })
if (this.nodeOption.tableDesc) {
if (this.tablePage === 0) {
this.tableOptions = []
}
newContent = res.content
}
// const newContent = res.content.filter(item => { return item.tableId != this.nodeOption.connect })
this.tableOptions = [ ...this.tableOptions, ...newContent ]
})
},
async getMind(mindCode) {
let param = {
spaceId: this.currentSpaceId
}
treeIndex(param).then(res => {
this.mind.data = res
// if (this.formData.mindOptions&&this.formData.mindOptions !== '') {
// this.theme_value = JSON.parse(this.formData.mindOptions).theme
// this.set_theme()
// }
this.jm.show(this.mind)
}).catch(err => {
})
},
moveHandle(target_direct) {
// console.log("移动名称:" + jsMind.dragObj.src_node.topic, "id为" + jsMind.dragObj.src_node.id);
// console.log("父级名称:" + jsMind.dragObj.target_node.topic, "id为" + jsMind.dragObj.target_node.id);
// console.log("移动方向:" + target_direct);
let param= {
indexId:jsMind.dragObj.src_node.id,//移动的资源目录id
superId:jsMind.dragObj.target_node.id,//移动后的父资源目录id
}
moveIndex(param).then(res=>{})
},
// 新增节点
addNode() {
let selectedNode = this.jm.get_selected_node() // as parent of new node
if (!selectedNode) {
this.$message({
type: 'warning',
message: '请先选择一个节点!'
})
return
}
let nodeid = this.jsMind.util.uuid.newid()
let topic = '新增节点'
this.jm.add_node(selectedNode, nodeid, topic)
let params = {
indexName: topic,//指标名称
levelNum: "",//层级
superId: selectedNode.id,//指标id
spaceId: this.currentSpaceId
};
addIndex(params).then(res => {
this.getMind()
})
},
// 重置
resetForm() {
this.nodeOption = {
targetName: '',
order: null,
connect: null
}
setTimeout(() => {
if (this.$refs.nodeForm) {
this.$refs.nodeForm.clearValidate()
}
}, 300)
this.tablePage = 0
},
// 编辑节点
editNode() {
let selectedId = this.get_selected_nodeid()
if (!selectedId) {
this.$message({
type: 'warning',
message: '请先选择一个节点!'
})
return
}
this.resetForm()
let nodeObj = this.jm.get_node(selectedId)
queryIndex({indexId: nodeObj.id}).then(res => {
this.nodeOption = {
targetName: res.indexName,
order: res.sortIndex,
connect: res.tableId,
tableDesc: ''
}
this.dialogVisible = true
if (res.tableId) {
this.defaultTableList = [{ tableId: res.tableId, tableDesc: res.tableDesc }]
this.tableOptions = [{ tableId: res.tableId, tableDesc: res.tableDesc }]
} else {
this.defaultTableList = []
this.tableOptions = []
}
this.getTableConnect()
/*if (nodeObj.children.length > 0) {
this.tableDisabled = true
} else {
this.tableDisabled = false
}*/
})
},
sureEditNode(formName) {
let selectedId = this.get_selected_nodeid()
this.$refs[formName].validate((valid) => {
if (valid) {
let param = {
indexId: selectedId,
tableId: this.nodeOption.connect,
indexName: this.nodeOption.targetName,
sortIndex: this.nodeOption.order
}
updateIndex(param).then(res => {
this.dialogVisible = false
this.getMind()
this.jm.update_node(selectedId, this.nodeOption.content)
this.jm.set_node_font_style(selectedId, this.nodeOption.fontSize, this.nodeOption.fontWeight, this.nodeOption.fontStyle)
this.jm.set_node_color(selectedId, this.nodeOption.bgColor, this.nodeOption.fontColor)
this.nodeOption = {
content: '',
bgColor: '',
fontColor: '',
fontSize: '',
fontWeight: '',
fontStyle: ''
}
this.$refs.nodeForm.resetFields()
})
}
})
},
// 删除节点
onRemoveNode() {
let selectedId = this.get_selected_nodeid()
if (!selectedId) {
this.$message({
type: 'warning',
message: '请先选择一个节点!'
})
return
}
// let selectedNode = this.jm.get_selected_node()
this.$confirm('确定删除此指标吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.jm.remove_node(selectedId)
let param = {
indexId: selectedId
}
deleteIndex(param).then(res => {
this.getMind()
this.$message({
type: "success",
message: "已删除"
})
})
}).catch(err => {})
},
// 选择主题颜色
set_theme() {
this.jm.set_theme(this.theme_value)
},
// 获取选中标签的 ID
get_selected_nodeid() {
let selectedNode = this.jm.get_selected_node()
if (selectedNode) {
return selectedNode.id
} else {
return null
}
},
saveMind() {
return;
if (this.formData.mindCode === '') {
this.$message({type: 'warning', message: '导图编码不能为空!'})
return
}
if (this.formData.mindName === '') {
this.$message({type: 'warning', message: '导图名称不能为空!'})
return
}
this.mindOptions.theme = this.theme_value
this.formData.mindOptions = JSON.stringify(this.mindOptions)
this.formData.mindData = JSON.stringify(this.jm.get_data())
let url = process.env.VUE_APP_BASE_CRUD_PATH + `/api/jsmind/save`
this.$axios.post(url, JSON.stringify(this.formData), {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
}).then(res => {
if (res.resultCode === 500) {
this.$message({
type: 'error',
message: '导图编码已存在!'
})
}
if (res.resultCode === 200) {
this.$message({
type: 'success',
message: '保存成功!'
})
}
}).catch(err => {
console.log(err)
})
},
deleteMind() {
this.$confirm('您确定要删除该导图吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {}).catch(() => {})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.app-container {
padding: 0;
.header {
height: 60px;
background-color: #eee;
border-bottom: solid 1px #aaa;
z-index: 100;
}
}
</style>