一.寫在前面 半年以前,第一次在項目上實踐VueJs,由於在那之前,沒有Angular,avalon等框架的實踐經驗,所以在Vue的使用上,沒有給自己總結出更多的經驗和體驗。隨著項目進行和優化改版,無論是新代碼的增加還是舊代碼,在功能的實現和代碼的書寫上,Vue逐漸替代了Jquery,除了有些不容易 ...
一.寫在前面
半年以前,第一次在項目上實踐VueJs,由於在那之前,沒有Angular,avalon等框架的實踐經驗,所以在Vue的使用上,沒有給自己總結出更多的經驗和體驗。隨著項目進行和優化改版,無論是新代碼的增加還是舊代碼,在功能的實現和代碼的書寫上,Vue逐漸替代了Jquery,除了有些不容易替換和沒有找到基於vue更合適的組件。Vue的使用,在我個人的感受中減輕了我操作dom的負擔,我不需要從dom中獲取數據,然後拼裝數據,也不需要向dom中回寫展示數據。更不需要我各種拼接html,即使簡單的html可以忍受,複雜的也將導致無法維護。組件化的開發,更能讓我們js分割,職責清晰,比模塊化開發的復用性更強,最後再通過工具打包。
二.本次優化內容:第一版的體驗
先上第一版體驗的gif圖吧,說實話,當時強行做出來之後,我自己都不愛用,更不想看自己的代碼和修改拼接一堆的html。截圖中所體現的功能,實際上只是將教案的詳細安排和每一個課時對應匹配起來。當課時數量比較多的時候,那麼有多少個課時,用戶可能就需要點擊多少下覆選框。當時,只用了vue computed來計算紅色部分的文字應該如何顯示,所以也能一併監控到教學方案和課時數量的改變情況數據,當教學方案和課時都已經選擇的時候,會生成下方的操作內容,內容則是html拼接的。
三.完全改版
先上改版的頁面效果,由於做成單課時依然需要用戶操作多次,所以增加了上方幾個快速操作的方式。這裡使用純Vue來實現。在這裡如果有一點dom操作,將會擾亂vue的Vmodel數據,所以必須要以數據為驅動,每一個教案的詳細課時,都是一個數組,操作永遠都是push和splice。最後則可以直接將頁面的vmodel提交。
四.上一段簡單的拖動demo吧
這段demo是有很多不足支出的,是我最初參考網上其他人寫法實現所用到的。你可以看到,我把榴蓮拖動到小穎裡面,我把它放在葡萄裡面,結果這個元素apppend到了葡萄div當中。所以在實際情況中,你可能需要做很多判斷,比如如果是葡萄這種div的class,則你將其放到其父元素中之類的。另外這段代碼的操作,沒有完全脫離dom,依然使用了appendChild。所以你的操作可以根據html上做下某些標記,來找到對應的list,並向其中push數據,或者splice數據,這樣一來就是數據驅動了。
這裡是代碼,copy並修改vue路徑直接運行
1 1 <!DOCTYPE html> 2 2 <html> 3 3 <head> 4 4 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> 5 5 <meta charset="utf-8"> 6 6 <title></title> 7 7 <meta name="keywords" content="" /> 8 8 <meta name="description" content="" /> 9 9 10 10 <style> 11 11 .select-item { 12 12 background-color: #5bc0de; 13 13 display: inline-block; 14 14 text-align: center; 15 15 border-radius: 3px; 16 16 margin-right: 10px; 17 17 cursor: pointer; 18 18 padding: 6px 20px; 19 19 color: #fff; 20 20 } 21 21 22 22 .cursored { 23 23 cursor: default; 24 24 } 25 25 26 26 .project-content, .people-content { 27 27 margin: 30px 50px; 28 28 } 29 29 30 30 .people-content { 31 31 margin-top: 30px; 32 32 } 33 33 34 34 .drag-div { 35 35 border: 1px solid#5bc0de; 36 36 padding: 10px; 37 37 margin-bottom: 10px; 38 38 width: 800px; 39 39 cursor: pointer; 40 40 } 41 41 42 42 .select-project-item { 43 43 display: inline-block; 44 44 text-align: center; 45 45 border-radius: 3px; 46 46 } 47 47 48 48 .drag-people-label { 49 49 margin-bottom: 0; 50 50 padding-right: 10px; 51 51 } 52 52 53 53 [v-cloak] { 54 54 display: none; 55 55 } 56 56 </style> 57 57 </head> 58 58 <body> 59 59 60 60 <div class='drag-content' id="dragCon"> 61 61 <div class='project-content'> 62 62 <div class='select-item' draggable='true' @dragstart='drag($event)' v-for="pjdt in projectdatas">{{pjdt.name}}</div> 63 63 </div> 64 64 <div class='people-content'> 65 65 <div class='drag-div' v-for="ppdt in peopledata" @drop='drop($event)' @dragover='allowDrop($event)'> 66 66 <div class='select-project-item'> 67 67 <label class='drag-people-label'>{{ppdt.name}}:</label> 68 68 </div> 69 69 </div> 70 70 </div> 71 71 </div> 72 72 <script src="../../../content/lib/vue/vue.min.js"></script> 73 73 <script type="text/javascript"> 74 74 var dom; 75 75 var ss = new Vue({ 76 76 'el': '#dragCon', 77 77 data: { 78 78 projectdatas: [{ 79 79 id: 1, 80 80 name: '葡萄' 81 81 }, { 82 82 id: 2, 83 83 name: '芒果' 84 84 }, { 85 85 id: 3, 86 86 name: '木瓜' 87 87 }, { 88 88 id: 4, 89 89 name: '榴蓮' 90 90 }], 91 91 92 92 93 93 peopledata: [{ 94 94 id: 1, 95 95 name: '小穎' 96 96 }, { 97 97 id: 2, 98 98 name: 'hover' 99 99 }, { 100 100 id: 3, 101 101 name: '空巢青年三 ' 102 102 }, { 103 103 id: 3, 104 104 name: '一丟丟' 105 105 }] 106 106 107 107 }, 108 108 mounted: function () { 109 109 this.$nextTick(function () { 110 110 111 111 }) 112 112 }, 113 113 watch: { 114 114 projectdatas: { 115 115 handler: function (val, oldval) { 116 116 117 117 }, 118 118 deep: true 119 119 }, 120 120 peopledata: { 121 121 handler: function (val, oldval) { 122 122 123 123 }, 124 124 deep: true 125 125 } 126 126 }, 127 127 128 128 methods: { 129 129 drag: function (event) { 130 130 dom = event.currentTarget 131 131 }, 132 132 drop: function (event) { 133 133 event.preventDefault(); 134 134 event.target.appendChild(dom); 135 135 }, 136 136 allowDrop: function (event) { 137 137 event.preventDefault(); 138 138 } 139 139 } 140 140 141 141 }); 142 142 143 143 144 144 </script> 145 145 </body> 146 146 </html>View Code
寫在最後
如果,您認為閱讀這篇博客讓您有些收穫,不妨點擊一下右下加【推薦】按鈕。
如果,您希望更容易地發現我的新博客,不妨點擊下方紅色【關註】的。
因為,我的分享熱情也離不開您的肯定支持。
感謝您的閱讀,我將持續輸出分享,我是蝸牛, 保持學習,謹記謙虛。不端不裝,有趣有夢。