Vue真香警告!一个小小的输入框,差点就毁了我的前端大项目!

各位大佬好,如题,可以在这里演示:router-view内存释放问题演示

一个很常规的操作:
router-view切换不同的组件,只要点击了某组件内的input输入框,
这个组件的内存就释放不了

模型做了简化处理,项目采用router-view切换组件,只要点击了页面的输入框,
内存就释放不了,最终chrome浏览器奔溃!!!
然后我就奔溃了!!!

* 用v-if切换组件,没有这个问题,
* 升级到vue3,同样的组件占用的内存较小,但是问题同样存在,


d8210ff2cc2460cbc84741fde8a9b43
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue2.0, router-view模式 MemoryTest</title>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
  <script src="https://unpkg.com/vue-router@3.0.2/dist/vue-router.js"></script>
  <style>
    .item{
      display:inline-block;
      width:5rem;
      padding:5px;
      margin:1px 1px 0 0 ;
      border:1px solid red;
      text-align: center;
    }
  </style>
</head>
<body>
  <div id="app">
    <ul>
      <li><a href="./index.html">Vue2.0, router-view模式 MemoryTest</a></li>
      <li><a href="./no-v-model.html">Vue2.0, router-view模式 MemoryTest--input不绑定v-model</a></li>
      <li><a href="./before-destory.html">Vue2.0, router-view模式 MemoryTest--beforeDestory主动释放变量</a></li>
    </ul>
    <hr />
    其他验证:
    <ul>
      <li><a href="./index-v-if.html">Vue2.0, v-if模式 MemoryTest</a></li>
      <li><a href="./index-vue3.html">Vue3.0, router-view模式 MemoryTest</a></li>
    </ul>
    <pre>
      结论:router-view模式切换组件,点击组件的input输入框,会导致内存无法释放

      验证过程及现象:
      1.先点击 【1.到空白组件】 按钮,记录当前 JS heap size和DOM Nodes数据

      2.点击其他按钮,如【2.到节点组件】,观察memory面板的这两个数值,都会增加,再回到【1.到空白组件】,
      此时手动触发chrome,memory的gc按钮,JS heap size 和DOM Nodes恢复

      3.点击其他按钮,如【3.到节点 + input输入框 组件】,观察memory面板的这两个数值,都会增加,再回到【1.到空白组件】,
      此时手动触发chrome,memory的gc按钮,JS heap size 和DOM Nodes恢复

      4.点击其他按钮,如【3.到节点 + input输入框 组件】,观察memory面板的这两个数值,都会增加,
      注意,如果点击了输入框,即输入框focus了,再回到【1.到空白组件】,
      此时手动触发chrome,memory的gc按钮,JS heap size 和DOM Nodes 就不能恢复了,内存泄漏

      尝试的解决方案:
      1.input输入框不绑定事件,即不写v-model="val"
      2.组件beforeDestory钩子主动清除变量list

      我未解决的问题:
      1.input输入框常规使用就是v-model绑定变量,
      2.一般在beforeDestory需要主动remove事件,或者清除第三方插件生成的变量等,data的变量都需要手动清除吗?
    </pre>
    <p>
      <router-link to="/">0.回到首页</router-link>
      <router-link to="/1">1.到空白组件</router-link>
      <router-link to="/2">2.到节点组件</router-link>
      <router-link to="/3">3.到节点 + input输入框 组件</router-link>
    </p>

    <router-view></router-view>
  </div>
</body>
<script>
const Index1 = {
  template: `<div> 我是空白组件</div>`,
  data(){
    return {
      list:[]
    }
  },
  mounted(){
    for (let i = 0; i < 50000; i++) {
        this.list.push({
          label: "Item " + i,
          value: i
        })
      }
  },
}

const Index2 = {
  template: `<div><span v-for="n in 5000" :key="'Index2_'+n" class="item">{{n}}</span></div>`,
  data(){
    return {
      list:[]
    }
  },
  mounted(){
    for (let i = 0; i < 50000; i++) {
        this.list.push({
          label: "Item " + i,
          value: i
        })
      }
  },
}

const Index3 = {
  data(){
    return {
      val:undefined,
      list:[]
    }
  },
  template: `
  <div>
    <input type="text"  v-model="val"/>
    <hr />
    <span v-for="n in 5000" :key="'Index3_'+n" class="item">{{n}}</span>
  </div>
  `,
  mounted(){
    for (let i = 0; i < 50000; i++) {
        this.list.push({
          label: "Item " + i,
          value: i
        })
      }
  },
}

const routes = [
    { path: '/1', component: Index1 },
    { path: '/2', component: Index2 },
    { path: '/3', component: Index3 },
  ]

const router = new VueRouter({
  routes: routes,
})

window.yyf = new Vue({
  el:'#app',
  router,
  data(){
    return {}
  },
  methods:{}
})
</script>
</html>
```html
1 Like