Cannot mount an app within an app
Version
3.2.31
Reproduction link
Steps to reproduce
Click the 'unmount app' button
The error message will show in the Developer Tools Console
TypeError: Cannot read properties of null (reading 'nextSibling')
What is expected?
No error on app.unmount()
when the fragment dom content is not exist
What is actually happening?
There is an error on app.unmount()
when the fragment dom content is not exist
Combine usages of x6 and AntdVue
- Create a component Foo.vue which the root element is a Popover component. The AntdVue Popover component is a fragment implemented inside
- registerVueComponent with Foo, named this x6 node 'foo-node'
- Render some custom node of 'foo-node'
- Call removeCells of x6 to remove these nodes
- Show error and the x6 content area is not responsive, because x6 does not handle exception of unmount error
Maybe this error will occur in some other scenarios when app.unmount()
- Some browser extensions maybe clear the content of the fragment dom container
- In micro frontend, the sub app is a fragment, root app clear sub app dom content by mistake
Demo with x6 library:
Reproduction link
https://stackblitz.com/edit/vitejs-vite-nghwu9?file=README.md
Steps to reproduce
- click the button
What is expected?
Remove all the two custom nodes
What is actually happening?
Only remove one node
You cannot mount an app within an app, use a component instead or make sure you manually add an element that isn't handled by Vue
@posva Thanks for your reply. I know it is the best practice not to mount an app within an app. Maybe the sfc reproduction link is obfuscated.
In this https://stackblitz.com/edit/vitejs-vite-nghwu9 demo, the editable svg area is an element not controlled by vue. x6 library can be using create an svg node using vue component with foreignObject
. I think the x6 node is not a part of the main vue application, they are controlled by the custom x6 instance which isn't handled by vue.
The key point is when the child nodes of the fragment container doesn't exist, unmounting the fragment instance will cause the error.
Some complex apps may be consisting with multi app instance, fake code below,
<head>
<!-- some code -->
</head>
<body>
<div id="subapp1"></div>
<div id="subapp2"></div>
<script>
const subApp1 = createApp({/* fragment component*/});
const subApp2 = createApp({});
subApp1.mount('#subapp1');
subApp2.mount('#subapp2');
document.getElementById('subapp1').innerHTML = '';
subApp1.unmount();
</script>
</body>
Vue will throw the error on calling unmount
when subapp1 children do not exist. It's an edge case when unmount fragment.
But it would be confused when the application is complicated. Especially using some third-party libraries that use createApp
internal (antd vue, vant), it's more difficult to figure out why this error occurred.
You are not supposed to manually manipulate the HTML that is handled by Vue either. You just need to move the html clear after the unmount like this