DOM acquisition exception analysis in dialog Error: Initialize failed: invalid dom

Analysis on the situation of placing DOM in dialog to obtain exception

When putting the dom into the dialog, an abnormal error will often appear, indicating that the dom is invalid, just because
1. The dialog must be opened before the dom can be mounted.
2. After the dialog is opened, when the open listening event is used for dom operations, it often appears that the dom is invalid because the dom has not been mounted.
Use this.$next(()=>{
xxx;
})
Or setTimeout can also be implemented.

Example: vue implements ECharts drawing in the pop-up window

<el-dialog id="dialogboard" fullscreen title="Static Kanban" :lock-scroll="false" :visible.sync="StaticBoard" @open="handleDialogOpen">
       
        <div style="margin:auto;width:1450px;height:400px;position: relative;top: 100px;" >
          <div slot="header" style="height:30px; font-size:larger;color: #ffffff; background-color: #1b1d9d;" ><i class="el-icon-caret-right"></ i>Real-time production rate</div>
          <div style="height:380px; background-color: #ffffff; padding: 15px;border-style: solid;border-color: rgb(23, 137, 250);border-width: 2px;">
            <div id="produceRadio" style="width:1400px;height: 350px;display: inline-block; "></div>
          </div>
        </div>
    </el-dialog>
data(){<!-- -->
return{<!-- -->
//Pop-up window control to display static billboard
      StaticBoard:false,
}
},
mounted(){<!-- -->
//The use of nextTick here is only for demonstration. If not used, an error will be reported.
    this.$nextTick(()=>{<!-- -->
        this.setBarChart2()
      })
  },
methods: {<!-- -->
showStaticBoard(){<!-- -->
      this.StaticBoard=true
    },
    setBarChart2(){<!-- -->
      var myChart = this.$echarts.init(document.getElementById("produceRadio"))
      var option2={<!-- -->
        title: {<!-- -->
          text: 'Real-time graph of production rate',
        },
        toolbox: {<!-- -->
          feature: {<!-- -->
            dataView: {<!-- --> show: true, readOnly: false },
            magicType: {<!-- --> show: true, type: ['line', 'bar'] },
            restore: {<!-- --> show: true },
            saveAsImage: {<!-- --> show: true }
          }
        },
        legend: {<!-- -->
          data: ['Production rate (PCS/H)', 'Theoretical rate', 'Current output']
        },
        xAxis: [
          {<!-- -->
            type: 'category',
            data: ['Filling', 'Weighing', 'Blister', 'Packaging 1', 'Packaging 2', 'Packaging 3'],
            axisPointer: {<!-- -->
              type: 'cross',
              crossStyle: {<!-- -->
                color: '#999'
              }
            }
          }
        ],
        yAxis: [
          {<!-- -->
            type: 'value',
            //name: 'Precipitation',
            min: 0,
            max: 70000,
            interval: 10000,
            axisLabel: {<!-- -->
              formatter: '{value}'
            }
          },
        ],
        series: [
          {<!-- -->
            name: 'Production rate (PCS/H)',
            type: 'bar',
            yAxisIndex: 0,
            tooltip: {<!-- -->
              valueFormatter: function (value) {<!-- -->
                return value ;
              }
            },
            data: [
              30000,25000,30000,20000,22000,18000
            ]
          },
          {<!-- -->
            name: 'Theoretical speed',
            type: 'line',
            yAxisIndex: 0,
            tooltip: {<!-- -->
              valueFormatter: function (value) {<!-- -->
                return value ;
              }
            },
            data: [
              25000,25000,30000,20000,22000,18000
            ]
          },
          {<!-- -->
            name: 'Current output',
            type: 'line',
            yAxisIndex: 0,
            tooltip: {<!-- -->
              valueFormatter: function (value) {<!-- -->
                return value ;
              }
            },
            data: [60000,40000,30000,20000,18000,15000]
          }
        ]
      }
      myChart.setOption(option2)
      console.log(option2)
    },
    handleDialogOpen(){<!-- -->
      //Called after DOM is fully mounted
      console.log("this dialog is opened")
    },
}

1. In the above example, put the drawing function in mounted to achieve the effect:

Browser error:
Error in nextTick: “Error: Initialize failed: invalid dom.”
Error: Initialize failed: invalid dom.

Reason: Mounted can only handle the situation where the DOM is placed directly on the interface. If you want to put the DOM used by the echart component into the dialog, you can listen to the open event set by the dialog. When the dialog is opened, it will hang in the dialog settings. dom, after mounting, use document.getElementById (set id) or refs (set ref) to get the component.

2. Close the dialog and open it again, as shown below:

Browser error:
Error in mounted hook: “Error: Initialize failed: invalid dom.”
Initialize failed: invalid dom.
And this dialog is opened executed twice

Reason: Mounted can only handle the situation where the DOM is in the interface. It cannot detect the DOM in the dialog and needs to be set manually in the open event.

3. Let’s demonstrate below, using the drawing function directly in the open event in the dialog:

handleDialogOpen(){<!-- -->
      this.setBarChart2()
      console.log("this dialog is opened")
    },

Rendering:

Browser error message:
Error in v-on handler: “Error: Initialize failed: invalid dom.”
Initialize failed: invalid dom.

Reason: When the dialog is opened, the DOM is accessed before it is mounted, and an exception occurs. Use nextTick or setTimeout.

4. Close the pop-up window and open it again, as shown below:

Reason: After closing the dialog last time, the components in the dialog have been mounted and are not destroyed when closing the pop-up window, so you can get the dom when you open it again.

The normal code is as follows:

5. Other codes are above. Except for calling the drawing function setBarChart2, other codes are fine.

handleDialogOpen(){<!-- -->
      //Called after DOM is fully mounted
      this.$nextTick(()=>{<!-- -->
        this.setBarChart2()
      })
      
      console.log("this dialog is opened")
    },

Rendering: