各位大佬好,如题,可以在这里演示:router-view内存释放问题演示
一个很常规的操作:
router-view切换不同的组件,只要点击了某组件内的input输入框,
这个组件的内存就释放不了。
模型做了简化处理,项目采用router-view切换组件,只要点击了页面的输入框,
内存就释放不了,最终chrome浏览器奔溃!!!
然后我就奔溃了!!!
* 用v-if切换组件,没有这个问题,
* 升级到vue3,同样的组件占用的内存较小,但是问题同样存在,

代码如下:
<!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