需求:左侧树针对某一节点进行加锁、解锁处理,处理后的数据需要重新加载树接口,并展开到上一次展开的节点; 可作为有类似场景的代码参考
html
<el-tree
ref="tree"
:key="treeKey"
highlight-current
lazy
node-key="node_id"
:props="props"
:load="loadNode"
:default-expanded-keys="showList"
:expand-on-click-node="false"
@node-click="clicktree"
@node-expand="afterNodeExpand"
>
<span slot-scope="{ data }" class="custom-tree-node">
<span
class="el-tree-node__label"
:class="{ fnode: data.node_type === 'root' }"
>
<em
v-if="data.node_type === 'root'"
:title="data.name"
class="iconEpc icon-cangku mc"
/>
<em v-else-if="data.node_type === 'dt_CraftRank_01'" class="iconEpc icon-gongsi1 mc" />
<em v-else-if="data.node_type === 'dt_CraftRank_02'" class="iconEpc icon-chanpinxian mc" />
<em v-else-if="data.node_type === 'dt_CraftRank_03'" class="iconEpc icon-gongyi mc" />
<em v-else-if="data.node_type === 'dt_CraftRank_04'" class="iconEpc icon-chejianguanli mc" />
<em v-else-if="data.node_type === 'dt_CraftRank_05'" class="iconEpc icon-piliangshengchan mc" />
<em v-else-if="data.node_type === 'dt_CraftRank_06' && data.itemType === 'resource'" class="iconEpc icon-beijing mc" />
<em v-else-if="data.node_type === 'dt_CraftRank_06'" class="iconEpc icon-server mc" />
<em v-else-if="data.node_type === 'dt_CraftRank_08'" class="iconEpc icon-beijing mc" />
{{ getNodeLabel(data) }}
<span v-if="data.node_type === 'dt_CraftRank_08'" class="tree-btn-group">
<em v-if="data.lock == 1" class="el-icon-lock" style="color: #00b4e1;cursor: pointer;width:30px" @click.stop="handleClicklock(data)" />
<em v-else-if="data.lock == 2" class="el-icon-lock" style="color: red;width:30px" @click.stop="handleClickUnlock(data)" />
</span>
</span>
</span>
</el-tree>
javascript
props: {
label: 'title',
isLeaf: 'leaf'
},
factoryId: '',
mfgCenterCode: '',
showList:[]
treeKey: 0
javascript
methods: {
// 请求树的接口 写自己的逻辑即可
loadNode(node, resolve) {
const craftType = (this.$route.meta && this.$route.meta.craftType) || 'ZZ'
if (node.level === 0) {
querytree({ craftType, modelCode: this.selectedModel, jphVersion: this.currentJphVersionType, versionNo: this.currentVersion ? this.currentVersion.versionNo : '' }).then(res => {
if (res.data.rows.length > 0) {
this.showList.push(res.data.rows[0].node_id)
if (res.data.rows[0].isParent === 'true' || res.data.rows[0].isParent === true) {
res.data.rows[0].leaf = false
} else {
res.data.rows[0].leaf = true
}
const n = node
n.data = res.data.rows[0]
this.rootNode = n
resolve(res.data.rows)
this.$nextTick(() => {
if (this.autoExpandFinished) return
})
} else {
resolve([])
}
}).catch(e => {
console.error('加载树节点失败:', e)
resolve([])
})
return
}
if (node.level > 0) {
querytree({
'nodeId': node.data.node_id,
craftType,
modelCode: this.selectedModel,
jphVersion: this.currentJphVersionType,
versionNo: this.currentVersion ? this.currentVersion.versionNo : ''
}).then(res => {
if (res.data.rows.length > 0) {
res.data.rows.forEach(i => {
if (i.isParent === 'true' || i.isParent === true) {
this.$set(i, 'leaf', false)
} else {
this.$set(i, 'leaf', true)
}
})
}
return resolve(res.data.rows)
}).catch(e => {
console.error('加载树节点失败:', e)
resolve([])
})
}
},
// 加锁
handleClicklock(data) {
this.handleLockToggle(data, 'lock', '加锁')
},
// 解锁
handleClickUnlock(data) {
this.handleLockToggle(data, 'unlock', '解锁')
},
// 加锁/解锁
handleLockToggle(data, action, actionName) {
this.$confirm(`确定对此数据${actionName}吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const api = action === 'lock' ? lockZZPrBOP : unlockZZPrBOP
api({ recordIds: data.id }).then((res) => {
if (res.data.result == '1') {
this.$message.success(`${actionName}成功!`)
// 保存当前路径(用于刷新后定位)
const savedPath = this.getCurrentPath()
this._restorePath = [...savedPath]
this.showList = [...savedPath]
// 刷新树
this.$nextTick(() => {
this.treeKey++
})
this.$nextTick(() => {
setTimeout(() => {
this.locateToNode(savedPath)
}, 600)
})
}
})
}).catch(() => {})
},
// 定位到目标节点(带重试)
locateToNode(path, retries = 5) {
if (!path || path.length === 0) return
const tree = this.$refs.tree
if (!tree) return
const targetId = path[path.length - 1]
const targetNode = tree.getNode(targetId)
if (targetNode && targetNode.data) {
// 找到了,设置高亮并触发点击
tree.setCurrentKey(targetId, true)
this.clicktree(targetNode.data, targetNode, null)
this._restorePath = null
} else if (retries > 0) {
// 节点还未加载,延迟重试
setTimeout(() => {
this.locateToNode(path, retries - 1)
}, 400)
} else {
console.log('定位失败,目标节点未加载:', targetId)
}
},
getCurrentPath() {
const savedPath = []
let current = this.clicknode
while (current && current.data && current.data.node_id) {
// 排除 root 节点
if (current.data.node_type !== 'root') {
savedPath.push(current.data.node_id)
}
// 遇到 root 直接跳出,避免死循环
if (current.data.node_type === 'root') {
break
}
current = current.parent
}
savedPath.reverse()
console.log('保存的路径:', savedPath)
return savedPath
}
}