7-4更新 => 已將本次項目上傳至 githulb/lonhon 歡迎大家下載,以后做的新東西也都會更新在上面。
之前發了一篇關於自己看待前端組件化的文章,但是由於學習和實踐的業務邏輯差異,所以自己練習的一些demo邏輯比較簡單,打算用vue重構現在公司做的項目,所以在一些小的功能頁面上使用vue來做的,現在寫的這個是項目中用戶反饋功能而來的,收獲還是挺多的。
收獲:dom操作=>數據操作 router的使用 組件的使用,具體總結放在尾部。
- 功能:1.上傳圖片
- 2.顯示縮略圖
- 3.可以刪除
先上成品圖(主要抽取圖片這塊),自己在家主要做的功能,樣式就不計較了。
先上文件目錄
由於測試demo,結構基本和VUE初始化生成的目錄一致,這里把Hello文件作為了這次組件開發的文件,App文件是主文件。這里自己理解的vue文件:是組件,也是頁面。所以在定義的時候得根據實際情況來做路由還是組件。
因為產品給的圖上面要求有5個按鈕,意味着只能選5個文件,這里如果用原來的思維來做的話,就是放5個input進去,但是現在用vue來做了,肯定得用v-for,不然太low了。先看看html部分
使用ul列表作為input的容器,然后在li中使用v-for循環mmm對象,生成5個初始框。
img就是預覽時候需要用到的了,使用v-if根據item.data是否為空來渲染,而src就是item.data
input就是上傳的了,在它的change事件中實現我們的主要功能, ps:實際業務使用中應該還要指定name,並且item.name應該是相同的,這樣提交給后台的時候才能更好讀取。
span用於刪除item.data,
現在看看data部分:
其中的mmm數組初始有5個子對象(因為需要5個固定的選擇框),name為自己定義,data用於存放圖片上傳后的base64,還有一個flag用於判斷是否上傳成功的。現在看看效果
OK,已經得到了5個選擇器,樣式方面主要思路是將input設置為行內塊級元素然后寬高100% 完全透明,比較簡單,現在來實現預覽效果,
預覽效果主要使用的是H5新功能 fileReader 實現,
思路:在input指定change事件觸發pushImg方法,接受兩個參數,一個是event,一個index
在v-for循環渲染li的時候,使用的是v-for="(item,index) in mmm" ,其中item就是mmm數組的元素,index就是元素的下標,這里具體可以看官方的文檔
現在來看pushImg方法:
在pushImg內部let了4個變量
mm指向data中的mmm,因為需要在reader.onload中用到,如果直接this.mmm會由於閉包取到reader.onloadg的this
flag用於標記上傳成功,因為要做一個上傳成功的提示
flie指向input
reader就是我們預覽圖片需要用到的了,這是一個H5的新接口,具體的使用手冊點擊 這里
在reader.onload中,我們將讀取到的result也就是圖片的base64碼放入mmm[i].data
還設置了個定時器改變flag的值,實現成功提示的效果
ps:reader.onload是一個異步操作,所以result要么在它內部傳出去,要么用回調或者promise傳出去。
現在上傳一個圖片看看效果
已經ok,現在來做最后一步——刪除圖片
span中已經指定了click事件為delImg,來看看代碼:
主要做的就是清空所點擊的選擇器的文件了
現在來一遍完整的流程:
小功告成,接下來說說使用vue-router把這個頁面路由到其它頁面中,要使用首先要安裝這個模塊,在項目目錄下使用cnpm install vue-router就行
還是先說下大致步驟:
1.制作頁面(這點上面已經做好了,就是我們的Hello文件)
2.配置路由
3.在頁面中展示
直接來第2步,如果了解實體路由器的應該知道路由器中都有一個路由表,這里我建立了一個route.js,就類似於路由器中的路由表。
在route.js中,引入Vue、vue-router、和需要路由的組件Hello,圖中的
import Hello from '@/components/Hello' 這里@相當於我配置的一個src目錄的縮寫而已,如果不會不用管,按照正常路徑寫就行。
下圖中的path就是一個路徑,在后面要用到,name相當於一個別名,component就是對應組件了。
按照上圖,我們就創建了一個路由表,建立好之后我們需要在主入口把路由表掛載上去。這里項目的主入口main.js,
進入main.js,這里就引入上面配置好的路由表route.js,和程序的主模塊App,可以看到我們的Vue實例是掛載到App中的。
接下來在App.vue中展示了,由於是靜態路由,所以主要配置template模塊,繼續上配置圖

圖中圈出來的第一部分,就類似於我們的a標簽,只不過vue-router使用router-link標簽封裝了,值得一提的是,router-link標簽只是起到一個包裹的作用,並沒有實際的html意義,里面可以放各種內容。
第二部分就是我們要展示的舞台了,<router-view></router-view> 就是我們的路由的模塊需要映射的地方,現在來測試一下是否成功。
注意我們的地址欄的變化,從localhost:8080變成了localhost:8080/#/hhh,也就是說這次路由跳轉成功。
現在來做組件引入到頁面中
將Hello作為組件放在App中,其實只要其它頁面引用了該組件,就可以使用,並不局限於App。
我們先在App.vue文件中的script部分將Hello引入,並注冊該組件
接下來在template部分將組件放進去,我們來把他放在頂部。
現在來看看效果,如圖頁面中已經渲染出了該模塊

現在我們來看看router和作為模塊引入的結合效果。

現在能看到組件部分和路由進去的部分都能夠正常運行,至此我們的功能就算全部完成了。
總結: 數據驅動的魔力實在太大,就拿圖片上傳來說,我們在實際操作中其實只是對data中的mmm進行了賦值操作,然后將值綁定在dom節點上,通過雙向綁定就實現了對DOM的操作,特別是現在的網站項目中,大部分都是處理數據,比如電商之類的網站。其實在用VUE做這個上傳功能之前我已經用傳統的jQuery寫出了這個插件,從手段上來說,jQuery做的就是操縱DOM節點,設置各個DOM節點的ID,然后js再通過ID取到對應的節點,給DOM綁上事件或者取出DOM的值,需要寫大量的html代碼和js代碼;在VUE中,使用一個v-for就可以渲染出多個想要的內容。從復用性來說,我們這次做的這個上傳圖片功能就已經是一個組件了,我們不僅僅可以在App.vue中使用它。像這次的Hello,我們不僅可以使用路由把它作為一個新的頁面,也可以使用component把他作為組件,也就是說,只要業務需要,我們可以選擇合理的方式復用我們已經寫好的東西。
特別需要注意的就是,使用angular或者vue這種數據驅動視圖的框架,我們需要將原來的操縱DOM的思維轉變為操縱數據。這點可能需要我們的抽象能力,將需要操作的對象封裝成結構合理的數據。