用Vue中遇到的问题和处理方法(一)
用Vue开发项目有一段时间,在实际项目中遇到一些问题,在里把问题记录下来,并附上解决方案,给遇到同样的问题的码友提供一个解决思路吧:
- 测试部抛出问题一:在Vue1.0路由vue-router中,当点击菜单一个组件加载出来表格列表,输入查询条件查询,当在单击这个菜单后表格的数据没有重置查询条件和查询结果.
原因分析:Vue路由在页面渲染一个组件后加载后,再加载这个组件,组件不会摧毁后在重新生成这个组件,不会重新触发组件的生命周期中的方法.代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <title>learning vue</title> </head> <body> <div id="app-container"> <ul> <li v-for="item in $root.list"> <a v-link="{ path: '/lang/' + item.id }">{{ item.name }}{{para}}{{params}}</a> </li> </ul> <router-view :params="params"></router-view> </div> <script src="js/vue.js"></script> <script src="js/vue-router.js"></script> <script> Vue.config.debug = true; Vue.use(VueRouter); var AppComponent = Vue.extend({ data: function(){ return { params:111, list: [ { id: '10001', name: 'C#', message: 'Hello C#' }, { id: '10002', name: 'Java', message: 'Hello Java.' }, { id: '10003', name: 'C++', message: 'Hello C++' }, { id: '10004', name: 'JavaScript', message: 'Hello JavaScript' } ] }; } }); var LangDetailComponent = Vue.extend({ template: `<div><h1>{{ model.name }}</h1><p>{{ model.message }}</p></div>`, computed: { model: function(){ var list = this.$root.list; var id = this.$route.params.id; for(var i = 0; i < list.length; i++){ if(list[i].id === id){ return list[i]; } } } }, init:function () { alert("init"); }, created:function () { alert("created"); }, beforeCompile:function () { alert("beforeCompile"); }, compiled:function () { alert("compiled"); }, ready:function () { alert("ready"); }, attached:function () { alert("attached") }, detached:function () { alert("detached") }, beforeDestroy:function () { alert("beforeDestroy") }, destroyed:function () { alert("destroyed") } }); var router = new VueRouter(); router.map({ '/lang/:id': { component: LangDetailComponent } }); router.start(AppComponent, '#app-container'); </script> </body> </html>
执行效果:
着三个路由都是同一个组件,但点击其他的时候组件中的所有生命周期的方法都没有调用,去vue-router的api上看没有找到重新加载路由的配置配置项.
在实际开发中这个问题在两个菜单共用一个组件,设置传参来判断加载不同的数据的情况下,会出现另一个ready方法不走导致数据显示不真确.解决思路可以加监听路由地址触发ready事件.
而上面的解决方法是用v-if来重新加载组件,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <title>learning vue</title> </head> <body> <div id="app-container"> <ul> <li v-for="item in $root.list"> <a href="javascript:void(0)" @click="click(item.path)">{{ item.name }}</a> </li> </ul> <router-view v-if="show"></router-view> </div> <script src="js/vue.js"></script> <script src="js/vue-router.js"></script> <script> Vue.config.debug = true; Vue.use(VueRouter); var AppComponent = Vue.extend({ data: function(){ return { show:true, list: [ { id: '10001', name: 'C#', message: 'Hello C#',path:"/lan"}, { id: '10002', name: 'Java', message: 'Hello Java.',path:"/lan1"}, { id: '10003', name: 'C++', message: 'Hello C++' ,path:"/lan2"}, { id: '10004', name: 'JavaScript', message: 'Hello JavaScript',path:"/lan3" } ] }; }, methods:{ click:function (path) { debugger; if(window.location.hash.replace("#!","")==path){ this.show=false; Vue.nextTick(function () { this.show=true; }.bind(this)) }else{ this.$router.go({path:path}); } } } }); var LangDetailComponent = Vue.extend({ template: `<div><h1>C#</h1><p>232323</p></div>`, computed: { model: function(){ var list = this.$root.list; var id = this.$route.params.id; for(var i = 0; i < list.length; i++){ if(list[i].id === id){ return list[i]; } } } }, init:function () { alert("init"); }, created:function () { alert("created"); }, beforeCompile:function () { alert("beforeCompile"); }, compiled:function () { alert("compiled"); }, ready:function () { alert("ready"); }, attached:function () { alert("attached") }, detached:function () { alert("detached") }, beforeDestroy:function () { alert("beforeDestroy") }, destroyed:function () { alert("destroyed") } }); var LangDetailComponent1 = Vue.extend({ template: `<div><h1>Java</h1><p>Hello Java.</p></div>`, computed: { model: function(){ var list = this.$root.list; var id = this.$route.params.id; for(var i = 0; i < list.length; i++){ if(list[i].id === id){ return list[i]; } } } }, init:function () { alert("init"); }, created:function () { alert("created"); }, beforeCompile:function () { alert("beforeCompile"); }, compiled:function () { alert("compiled"); }, ready:function () { alert("ready"); }, attached:function () { alert("attached") }, detached:function () { alert("detached") }, beforeDestroy:function () { alert("beforeDestroy") }, destroyed:function () { alert("destroyed") } }); var LangDetailComponent2 = Vue.extend({ template: `<div><h1>C++</h1><p>Hello C++</p></div>`, computed: { model: function(){ var list = this.$root.list; var id = this.$route.params.id; for(var i = 0; i < list.length; i++){ if(list[i].id === id){ return list[i]; } } } }, init:function () { alert("init"); }, created:function () { alert("created"); }, beforeCompile:function () { alert("beforeCompile"); }, compiled:function () { alert("compiled"); }, ready:function () { alert("ready"); }, attached:function () { alert("attached") }, detached:function () { alert("detached") }, beforeDestroy:function () { alert("beforeDestroy") }, destroyed:function () { alert("destroyed") } }); var LangDetailComponent3 = Vue.extend({ template: `<div><h1>JavaScript</h1><p>Hello JavaScript</p></div>`, computed: { model: function(){ var list = this.$root.list; var id = this.$route.params.id; for(var i = 0; i < list.length; i++){ if(list[i].id === id){ return list[i]; } } } }, init:function () { alert("init"); }, created:function () { alert("created"); }, beforeCompile:function () { alert("beforeCompile"); }, compiled:function () { alert("compiled"); }, ready:function () { alert("ready"); }, attached:function () { alert("attached") }, detached:function () { alert("detached") }, beforeDestroy:function () { alert("beforeDestroy") }, destroyed:function () { alert("destroyed") } }); var router = new VueRouter(); router.map({ '/lan': { component: LangDetailComponent }, '/lan1': { component: LangDetailComponent1 }, '/lan2': { component: LangDetailComponent2 }, '/lan3': { component: LangDetailComponent3 } }); router.start(AppComponent, '#app-container'); </script> </body> </html>
效果是:
这样在点相同的菜单,组件就重新加载,后面想优化每个菜单都加click,菜单很多话对页面是性能消耗,下篇想用vue能不能用事件委托绑定单击事件.暂时先写到这里.
这里在多说一句,Vue的路由是hash路由,所以要回去路由地址可以用 window.location.hash.replace("#!","")来获取.不知道hash路由的可以百度下,这里就不多说了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?