用Vue中遇到的問題和處理方法
阿新 • • 發佈:2019-01-10
用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"<