Subscribe on changes!

Implicit dynamic nodes are treated as static tags

avatar
Jul 19th 2022

Vue version

v3.2.37

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-nasrdq?file=vite.config.ts

Steps to reproduce

Define a <router view> in the app component, define a login page level component with a route of /, define a register page level component with a route of /reg, define a <div id="map" >< /div> dom element in the register component, and dynamically create a div with a width and height of 100px to this element in the onmounted life cycle.

regist.vue

<script setup lang="ts">
import { onMounted } from 'vue';

onMounted(() => {
  const div = document.createElement('div');
  div.style.cssText = `
    width: 100px;
    height: 100px;
    background: red;
  `;
  (document.querySelector('#map') as HTMLInputElement).appendChild(div);
});
</script>

<template>
  <div class="regist">
    register
    <div id="map"></div>
  </div>
</template>

<style scoped>
.regist {
  width: 400px;
  height: 400px;
  background: #999;
}
</style>

login.vue

<script setup lang="ts"></script>

<template>
  <div class="login">Login</div>
</template>

<style scoped>
.login {
  width: 400px;
  height: 400px;
  background: #666;
}
</style>

router.ts

import { createRouter, createWebHashHistory } from 'vue-router';

const routes = [
  {
    path: '/',
    name: 'AppLogin',
    component: () => import('../components/AppLogin.vue'),
  },
  {
    path: '/reg',
    name: 'AppRegist',
    component: () => import('../components/AppRegist.vue'),
  },
];

const router = createRouter({
  history: createWebHashHistory(),
  routes,
});

export default router;

app.vue

<script setup lang="ts">
import { useRouter } from 'vue-router';

const router = useRouter();
</script>

<template>
  <h1>App</h1>
  <div>
    <button @click="router.push('/')">Login</button>
    <button @click="router.push('/reg')">Reg</button>
  </div>
  <hr />
  <router-view></router-view>
</template>

<style scoped></style>

Production environment demonstration:

179216119-85c7d8ac-6788-420e-8dce-1ba424477c1c

What is expected?

Finally, the packaged production environment code is consistent with the running results of the development environment.

What is actually happening?

  • Switch routes repeatedly in the test environment, and the div element dynamically created in the register component always remains 100px
  • After packaging, the route is switched repeatedly in the generation environment, and the div elements dynamically created in the register component will always accumulate

System Info

System:
    OS: Windows 10 10.0.19044
    CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
    Memory: 2.04 GB / 7.90 GB
  Binaries:
    Node: 16.13.1 - E:\Nodejs\node.EXE
    Yarn: 1.22.17 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 8.12.1 - E:\Nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (103.0.1264.49)
    Internet Explorer: 11.0.19041.1566
  npmPackages:
    vue: ^3.2.37 => 3.2.37

Any additional comments?

It is suspected that the problem is caused by static tags. It is unclear whether the optimization of static tag promotion will only occur in the packaging phase or not? At present, we can only explicitly bind a variable key value to the implicit dynamic node to solve the cache problem after packaging.