一次基於Vue.Js的用戶體驗優化

来源:http://www.cnblogs.com/tdws/archive/2017/05/21/6885604.html
-Advertisement-
Play Games

一.寫在前面 半年以前,第一次在項目上實踐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

 

 

寫在最後

 

如果,您認為閱讀這篇博客讓您有些收穫,不妨點擊一下右下加推薦】按鈕。
如果,您希望更容易地發現我的新博客,不妨點擊下方紅色【關註】的。
因為,我的分享熱情也離不開您的肯定支持。

感謝您的閱讀,我將持續輸出分享,我是蝸牛, 保持學習,謹記謙虛。不端不裝,有趣有夢。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • a.安裝mysql database 1.安裝mysql服務端 sudo apt-get install mysql-server (在此過程中要求為mysql的root用戶設置一個密碼) 2.安裝mysql客戶端 sudo apt-get install mysql-client 3.安裝mysq ...
  • 一、在指定目錄創建腳本並賦予755許可權 vim /etc/init.d/tomcat 二、在tomcat的配置文件中添加相應參數 vim /usr/local/tomcat/bin/catalina.sh 三、添加tomcat為系統服務並指定在個各個控制台為開機啟動模式 chkconfig --ad ...
  • 編程語言介紹 語言是人與人之間溝通的介質,簡單的來說,編程語言也是語言,是我們程式員與電腦溝通的介質。常見的編程語言有我們熟知的做網頁開發的php,寫安卓應用的java,應用廣泛的c、c#及c++,以及目前火熱的python、r、go等高級語言,另外還有最接地氣的低級語言彙編語言,但是無論何種語言 ...
  • 在劃分磁碟分區時,遇到錯誤“WARNING: Re-reading the partition table failed with error 22: Invalid argument” 如下所示: [root@DB-Server u02]# fdisk -l Disk /dev/sda: 500.... ...
  • 一:500錯誤 1、500 Internal Server Error 內部服務錯誤:顧名思義500錯誤一般是伺服器遇到意外情況,而無法完成請求。 2、500出錯的可能性: a、編程語言語法錯誤,web腳本錯誤 b、併發高時,因為系統資源限制,而不能打開過多的文件 3、一般解決思路: a、查看ngi ...
  • 安裝: [root@server ~]# yum install -y vsftpd [root@server ~]# rpm -ql vsftpd /etc/logrotate.d/vsftpd /etc/pam.d/vsftpd /etc/rc.d/init.d/vsftpd /etc/vsft ...
  • jdk版本:jdk-8u131-linux-x64.rpm 註:以下操作在root用戶或具有root許可權的用戶下操作 一、將 dk-8u131-linux-x64.rpm拷貝到/home目錄下 二、解壓rpm文件 三、環境變數的配置 註:環境變數的配置稍微麻煩一點,不過也不是特別難。 1.輸入以下命 ...
  • 最近公司需要優化導入的問題,由於之前使用的方式是生成 Insert 語句插入資料庫,數據量小的時候還行,但是隨著發展數據量漸漸大了,之前的方法性能就跟不上了,於是發現了 SqlBulkCopy 這個類。 使用 SqlBulkCopy 類只能向 SQL Server 表寫入數據。但是,數據源不限於 S ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...