學以至用嘛,學了這麼多,在真實項目裏面怎麼應用呢?帶着問題去學習纔是最快的學習方式。仍是之前的那個項目,先後端分離,如今把前端換成vue的,暫時採用腳本化的方式,而後在嘗試工程化的方式。javascript
如今先實現功能節點(樹)、動態tab、數據列表、分頁這幾個主要功能。在前面幾章裏面代碼都已經介紹了,好吧分頁沒說,不過也比較簡單了,加個模板,把數據接上,再加個事件就能夠了。css
先看一下效果:GIF動圖,1.5s一張不要太着急。另外截圖沒截好,不太清晰你們多擔待。(左上角是一個水印。)html
動圖裏面只演示了兩個模塊(頁面),其實不只能夠實現這兩個頁面,全部的基礎列表頁面均可以實現,即便換一個新的項目,也只須要改幾個參數就行(不須要修改代碼),以下圖:前端
實現這些功能,(前端)的代碼(html+vue)不超過300行(只須要一段,不用各類copy)。首先是vue很給力,代碼上面能夠作到很精簡,另外一個就是面向對象的基礎——抽象!vue
雖然功能模塊很是多,可是數據列表的模式是同樣的,區別就是——字段不同,其餘的還不都是同樣的嗎?因此咱們能夠針對全部的數據列表需求作一個抽象,把共同的功能拿出來作成代碼(或者組件),把差別化的需求也拿出來作成json包。這樣代碼就同樣了,不用一次一次的copy。咱們只須要維護好json包就能夠。java
這麼作有幾大優勢:程序員
一、 減小bug的出現機會,由於代碼不多,想出bug都難。並且會通過不少業務模塊、項目的測試,能夠及時發現bug。web
二、 便於修改bug,由於代碼就一處,改了一處就是全部(項目)這類的bug都被修改了。json
三、 減小了不少代碼量,讓程序員有更多的時間休息,,,,哦不對,是更多的時間去思考更復雜的業務邏輯如何實現。後端
四、 便於升級,由於代碼只有一處,想要升級修改這一處就好,其餘全部的列表功能就都跟着一塊兒升級了。
五、 便於入門學習,就這一處代碼,還學不會?
1 <html> 2 <head> 3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 4 <title>樹和列表以及分頁</title> 5 <meta charset="utf-8" /> 6 <script type="text/javascript" src="vue.js"></script> 7 <script type="text/javascript" src="vue-resource.min.js"></script> 8 <link type="text/css" rel="stylesheet" media="screen" href="/Manage/css/mangoGlobal.css"> 9 <link type="text/css" rel="stylesheet" media="screen" href="/Manage/css/mis-style-p.css"> 10 <link type="text/css" rel="stylesheet" media="screen" href="/Manage/css/MisStyle_v2.css"> 11 <link type="text/css" rel="stylesheet" media="screen" href="/Manage/css/debugCss.css"> 12 <link type="text/css" rel="stylesheet" media="screen" href="/Manage/css/css2.css"> 13 <script type="text/javascript"> 14 var dbid = "25,27"; //定義項目標識,區分不一樣的項目 15 var dataBaseId = 25; 16 var projectId = "1,2,3"; 17 </script> 18 </head> 19 <body> 20 <div id="foo"></div> <!—加載動畫--> 21 <div id="div_Show" class="clearfix"> 22 <div id="div_logo"> 23 <span id="showMe"></span> 24 <span id="webTitle">後臺管理 </span> 25 <span id="exit" onclick="delCookie('saleUserID___')"> 退 出 </span> 26 </div> 27 <div style="width:200px;"> 28 <div >導航菜單</div> 29 <div id="divTree"> 30 <div :key="'tree_' + tree.ModuleID" v-for="tree in trees" v-on:click="treeClick(tree.ModuleID,tree.ModuleName)" v-bind:class="'tree' + tree.ModuleLevel">{{tree.ModuleName}}</div> 31 </div> 32 </div> 33 <div id="div_Main" class="inner"> 34 <ul id="ulTab" class="tabs left"> 35 <li v-for="t in tabs" v-bind:class="{'selectTag':t.isShow}"> 36 <a v-on:click="tabClick(t.id)" href="javascript:void(0)"> 37 {{t.title}} {{t.id==='1'?tabNumber:''}} 38 <em class="arrup" v-on:click.stop="closeTab(t.id)">x</em> 39 </a> 40 </li> 41 </ul> 42 <div id="divIframe"> 43 <div v-for="t in tabMains" v-bind:class="{'selectTag':t.isShow}" v-show="t.isShow"> 44 {{ t.message }} 45 <table class="table_default1" style="" v-show="t.message!=='歡迎使用!'"> 46 <tr> 47 <th v-for="key in t.orderBy"> 48 {{t.tableTh[key].title}} 49 </th> 50 </tr> 51 <tr v-for="(tr,i) in t.dataList"> 52 <td v-for="index in t.orderBy" v-bind:align="t.tableTh[index].align"> 53 {{tr[index]}} 54 </td> 55 </tr> 56 </table> 57 <!--分頁控件--> 58 <div id="divQuickPage" v-show="t.message!=='歡迎使用!'"> 59 <div id="quickPage"> 60 <div id="quickPager" class="pagesize1"> 61 <span class="pagetext1" style="cursor: pointer;">共<strong>{{t.pageTurn.recordCount}}</strong>條記錄</span> 62 <span class="pagetext1" style="cursor: pointer;">第<strong>{{t.pageTurn.pageIndex}}</strong>/<strong>{{t.pageTurn.pageCount}}</strong>頁</span> 63 <span class="pagetext1" style="cursor: pointer;">每頁<strong>{{t.pageTurn.pageSize}}</strong>條記錄</span> 64 <span id="navi" style="cursor: pointer;"> 65 <a v-for="(p,index) in t.pageTurn.pageCount" v-on:click="naviClick(t.tabId,index+1)">{{index+1}}</a> 66 </span> 67 <a id="first" class="disabled">首頁</a> 68 <a id="prev" class="disabled">上一頁</a> 69 <a id="next" v-on:click="naviClick(t.tabId,2)">下一頁</a> 70 <a id="last">末頁</a> 71 <input type="text" id="txtGo" size="3" class="cssTxt"> 72 <a id="spanGo">GO</a> 73 </div> 74 </div> 75 </div> 76 </div> 77 </div> 78 </div> 79 </div> 80 81 <div id="div_Copyright"> 82 <span id="divDegub" onclick="DebugShow()">debug</span> <span id="Span1" onclick="DebugCache()">cache</span> 83 <span id="Span2" onclick="DebugShow()">event</span> by 天然框架之UI Vue + Json + ashx 84 </div> 85 </body>
1 //樹的數據包 2 var tree = new Vue({ 3 el: '#divTree', 4 data: { 5 trees: [ 6 { 7 IsHidden: 0, 8 ModuleID: -10, 9 ModuleLevel: 1, 10 ModuleName: "系統管理", 11 ParentID: 0, 12 ParentIDAll: "0", 13 Target: "_self", 14 URL: "#" 15 } 16 ] 17 }, 18 methods: { 19 treeClick: function (id,title) { 20 //隱藏前一個的tab 21 var oldId = tab.currentTabId; //記錄切換前tab的id 22 tab.beforeTabId = oldId; 23 tab.tabs["tab" + oldId].isShow = false; //隱藏切換前的tab 24 tabDiv.tabMains["tab" + oldId].isShow = false; //隱藏切換前的tab容器 25 tab.currentTabId = id; //記錄新的id 26 //建立tab 27 var newTab = { 28 id: id, //標籤識別標示 29 title: title, 30 isShow: true, //是否顯示 31 message: title 32 }; 33 34 //建立tab 的容器 35 var main = { 36 message:title, 37 isShow: true, //是否顯示 38 tabId: id //標籤識別標示 39 }; 40 41 if (typeof (tab.tabs["tab" + id]) === "undefined") 42 tab.tabNumber = tab.tabNumber + 1; 43 44 Vue.set(tab.tabs, "tab" + id, newTab); 45 46 if (typeof (tabDiv.tabMains["tab" + id]) === "undefined") { 47 //沒有加載描述,加載表格的描述信息 48 this.$http.get('/MetaData/GetMeta.ashx?action=grid&mdid=' + id + '&mpvid=' + id + '01&dbid=' + dbid + '&_=1563').then(function (res) { 49 //建立table 50 var table = { 51 message: title, 52 isShow: true, //是否顯示 53 tabId: id, //標籤識別標示 54 orderBy: [], //能夠控制字段的前後順序,想調整列的前後順序,改這個數組就行,能夠作個性化設置 55 tableTh: {}, //表頭的描述信息 56 dataList: [] //數據包,字段名做爲關鍵字,便於列的調整前後順序 57 }; 58 59 for (var key in res.body.data) { 60 var d = res.body.data[key]; 61 62 table.tableTh["" + d.ColumnID] = { 63 title: d.ColName, 64 align: d.ColAlign 65 }; 66 table.orderBy.push("" + d.ColumnID); 67 } 68 Vue.set(tabDiv.tabMains, "tab" + id, table); 69 //獲取數據 70 getDataList(id); 71 72 }, function () { 73 console.log('請求表頭失敗'); 74 }); 75 } else { 76 //獲取數據 77 getDataList(id); 78 } 79 80 //獲取數據 81 function getDataList(id) { 82 tabDiv.$http.get('/Data/GetData.ashx?action=list&mdid=' + id + '&mpvid=' + id + '01&fpvid=' + id + '02&frid=-2&frids=-2&pageno=1&pagerc=0&dbid=' + dbid + '&webappid=1&_=' + Date.now()).then(function (res) { 83 var tableData = tabDiv.tabMains["tab" + id]; 84 85 tableData.dataList = res.body.data; 86 tableData.pageTurn = res.body.pageTurn; 87 tableData.isShow = true; //顯示切換前的tab容器 88 89 Vue.set(tabDiv.tabMains, "tab" + id, tableData); 90 91 }, function () { 92 console.log('請求數據失敗'); 93 }); 94 } 95 } 96 } 97 }); 98 99 //標籤的數據包,只有標籤,沒有標籤下面的容器 100 var tab = new Vue({ 101 el: '#ulTab', 102 data: { 103 tabNumber: 1, //標籤數量,這個是臨時的,便於自動從新綁定 104 currentTabId: 1, //當前激活的tab的id 105 beforeTabId: 1, //上一個被激活的tab的id 106 tabs: { 107 tab1: { //能夠有多個標籤, 108 id: "1", //標籤識別標示 109 title: "個人桌面", 110 isShow: true, //是否顯示 111 message: '桌面' 112 } 113 } 114 }, 115 methods: { 116 tabClick: function (id) { 117 //切換tab 118 var oldId = tab.currentTabId; //記錄切換前tab的id 119 tab.beforeTabId = oldId; 120 tab.tabs["tab" + oldId].isShow = false; //隱藏切換前的tab 121 tabDiv.tabMains["tab" + oldId].isShow = false; //隱藏切換前的tab容器 122 123 tab.currentTabId = id; //記錄切換後的id 124 tab.tabs["tab" + id].isShow = true; //顯示切換後的tab 125 tabDiv.tabMains["tab" + id].isShow = true; //顯示切換前的tab容器 126 }, 127 closeTab: function (id) { 128 if (id === "1") { 129 alert("這是桌面,建議不要關閉哦:)"); 130 return; 131 } 132 133 delete tab.tabs["tab" + id]; //不知道有沒有更好的辦法 134 tab.tabNumber = tab.tabNumber - 1; 135 136 //設置「激活」狀態 137 var oldId = tab.beforeTabId; //上一個激活tab 138 var nowId = tab.currentTabId; //如今激活tab 139 140 if (nowId === id) { 141 //關掉的是激活tab,須要設置上一個tab爲激活狀態 142 tab.currentTabId = oldId; 143 tab.tabs["tab" + oldId].isShow = true; 144 tab.beforeTabId = 1; 145 } 146 else if (oldId === id) { 147 //關閉的是上一個激活tab,修改前一個tab的id 148 tab.beforeTabId = 1; 149 } else { 150 //須要強制修改一下,不然不會刷新 151 tab.currentTabId = nowId; 152 } 153 } 154 } 155 }); 156 157 //tab下面的容器的數據包 158 var tabDiv = new Vue({ 159 el: '#divIframe', 160 data: { 161 tabMains: { 162 tab1: { //能夠有多個標籤, 163 message: '歡迎使用!', 164 isShow: true, //是否顯示 165 tabId: "1", //標籤識別標示 166 orderBy: [], //能夠控制字段的前後順序,想調整列的前後順序,改這個數組就行,能夠作個性化設置 167 tableTh: {}, //表頭的描述信息 168 dataList: [], //數據包,字段名做爲關鍵字,便於列的調整前後順序 169 pageTurn: { 170 //naviCount: 5, //顯示頁碼數量 171 //pageCount: 3, //總頁數 172 //pageIndex: 1, //當前頁數 173 //pageSize: 20, //一頁記錄數 174 //recordCount: 58 //總記錄數 175 } 176 } 177 } 178 }, 179 methods: { 180 naviClick: function(id,pageIndex) { 181 tabDiv.$http.get('/Data/GetData.ashx?action=list&mdid=' + id + '&mpvid=' + id + '01&fpvid=' + id + '02&frid=-2&frids=-2&pageno=' + pageIndex + '&pagerc=0&dbid=' + dbid + '&webappid=1&_=' + Date.now()).then(function (res) { 182 183 var tableData = tabDiv.tabMains["tab" + id]; 184 tableData.dataList = res.body.data; 185 tableData.pageTurn = res.body.pageTurn; 186 187 Vue.set(tabDiv.tabMains, "tab" + id, tableData); 188 189 }, function () { 190 console.log('請求數據失敗'); 191 }); 192 } 193 } 194 }); 195 196 //從後端獲取樹,而後綁定。之前的項目,現成的接口先拿來用了。 197 tree.$http.get('/MetaData/GetMeta.ashx?action=tree&mdid=0&dbid=25&ProjectID=1,2,3&cacheKey=0&webappid=1&_=15640190').then(function (res) { 198 tree.trees = res.body.data; //後端的數據直接賦值,而後就自動綁定上了。 199 }, function () { 200 console.log('請求失敗處理'); 201 });
一、 由於是初學vue,因此代碼還不夠規範,有些地方並非很理想。還有不少須要優化和改進的地方。
二、 關於腳本和工程化。腳本比較簡單直接,引用vue.Js就能夠開魯,便於試驗本身的想法,並且vue的大部分方法也都是支持腳本方式的,還沒學到路由那一塊。如今先用腳本的方式來實現,而後在逐步轉成工程化的方式。或者保持兩種方式共存。這樣更靈活吧,反正代碼也沒多少。
三、 雖然如今代碼很少,可是實現的功能類型也很少,只是簡單的數據列表,還沒加上查詢和按鈕組,還有更復雜的表單控件。這些功能都加上以後,代碼會變得更加的臃腫,也就意味着一步步走向深淵——不可維護、不可擴展。那麼怎麼辦呢?
四、 代碼的可維護性——組件化。作成組件的方式來分割代碼。Emmmm,不知道vue還有沒有更好的方式。總之有好的方法均可以拿來用。
五、 代碼的可擴展性,目前tab裏面只能放數據列表,還沒想到更好的方式放其餘類型的內容,之前用了一個粗暴的方式——iframe,想放啥均可以。如今不想用iframe了。
下一步是研究一下表單的問題了。