其實這個問題之前已經遇到過了,但是還是在這裏踩坑了。趁此機會整理一下,避免再犯。
問題描述
預期效果:彈出dialog對話框,對話框的內容是由ztree實現的樹菜單。
實際效果:彈出dialog對話框,對話框內容空白,樹菜單顯示失敗。
<template>
<el-dialog title="樹菜單" :visible.sync="dialogVisible">
<div id="tree-menu" class="ztree"></div>
</el-dialog>
</template>
<script>
export default {
data() {
return {
dialogVisible: false
}
},
mounted() {
let setting = {view: {showIcon: false}};
let zNodes = [
{id: "1", name: "nodes1"},
{id: "2", name: "nodes2"}
];
$.fn.zTree.init($("#tree-menu"), setting, zNodes);
}
}
</script>
問題原因
使用elementUI 1.4版本的時候就遇到過這個問題了,當時一直以爲是自己編碼的錯誤,花了很多時間排查。後來控制檯調試的時候發現,沒有打開dialog之前是介個樣子的:
第一次打開dialog之後:
基本就能明白,dialog的內容是懶渲染模式。在el-dialog__body
未渲染之前是無法獲取到其中的DOM元素進行操作的。
在elementui最新版本的文檔中也有提示出來了:
問題解決
- 根據文檔提示“如果需要執行 DOM 操作,或通過 ref 獲取相應組件,請在 open 事件回調中進行”。但其實在第一次打開dialog的open事件回調執行的時候,仍然無法執行DOM操作,因爲這個時候dialog的內容還是未渲染上去。可使用
Vue.$nextTick
將DOM操作延遲到DOM更新之後執行。 - 因爲樹菜單的邏輯較爲複雜,可複用,所以直接提取成組件。在組件mounted的時候去獲取DOM元素來做ztree的初始化操作,可避開dialog懶渲染帶來的DOM元素操作問題。