require.js+vue開(kāi)發(fā)微信上傳圖片組件
由于項(xiàng)目是thinkPHP做后端框架,一直以來(lái)都是多頁(yè)面的后端路由,想使用火熱的webpack有點(diǎn)無(wú)從下手(原諒我太菜,而且推廣vue只有我一個(gè)人……),沒(méi)辦法,想把vue用起來(lái),唯有在原來(lái)的基礎(chǔ)上改進(jìn)。使用webpack的巨大好處就是可以使用 .vue 這樣的單文件來(lái)寫(xiě)vue組件,這樣每一個(gè)組件就是一個(gè) .vue 文件,哪里用上這個(gè)組件就引入進(jìn)來(lái),維護(hù)起來(lái)確實(shí)很爽。然而一直以來(lái)項(xiàng)目用的都是require.js,那又想以這樣的形式來(lái)組織vue組件,還要加上vue-router和vue-resource,怎么破?這篇文章以開(kāi)發(fā)微信上傳圖片組件為例子小結(jié)一下require.js+vue+vue-router+vue-resource的開(kāi)發(fā)流程。
用require.js組織你的組件
我們會(huì)有一個(gè)components目錄去放我們的各個(gè)組件,每個(gè)組件有用自己名字命名的文件夾,比如這次的例子album組件,里面就放著這個(gè)組件的html、js、css,具體怎樣用require.js去加載html和css,大家百度一下把相關(guān)插件下載下來(lái)即可。于是該組件的js中就可以在define里把相關(guān)的依賴(lài)都加載進(jìn)去,最后把組件return出去,別的組件也可以通過(guò)define加載這個(gè)組件,這也達(dá)到了模塊化管理組件的目的了。
這里的話(huà),我總結(jié)了一個(gè)使用require.js寫(xiě)vue組件的模板,使用WebStorm把這個(gè)模板加上去,每次寫(xiě)組件的時(shí)候打幾個(gè)字就把模板生成出來(lái),不要太爽啊?。╟omponentName是模板的變量,模板生成出來(lái)你填上你的組件名字就可以)
define(["vue","text!../js/lib/components/$componentName$/index.html","css!../js/lib/components/$componentName$/index.css"],function (Vue,Template) { // 這里是模塊的代碼 var $componentName$ = Vue.extend({ template : Template, props : [], data : function() { return { } }, // 在編譯結(jié)束和 $el 第一次插入文檔之后調(diào)用 ready : function() { }, // 在開(kāi)始銷(xiāo)毀實(shí)例時(shí)調(diào)用。此時(shí)實(shí)例仍然有功能。 beforeDestroy : function() { }, methods : { }, events : { } }); return $componentName$; });
總體預(yù)覽這個(gè)例子
為了演示完整的流程,我把這個(gè)例子做成一個(gè)小單頁(yè)叫show-album,就兩個(gè)頁(yè)面:
1.主頁(yè)叫main-page
2.詳情頁(yè)叫detail-page
詳情頁(yè)里的功能有:
接收父組件傳過(guò)來(lái)的參數(shù)進(jìn)行上傳圖片組件的初始化
點(diǎn)擊每張圖片右上角的叉叉可以刪除圖片
點(diǎn)擊最后那個(gè)小相機(jī)圖案調(diào)用微信”從手機(jī)相冊(cè)中選圖接口”,用戶(hù)可以在自己手機(jī)上選圖
選完圖片后,圖片按比例調(diào)整尺寸變成如圖所示那樣的縮略圖
點(diǎn)擊相應(yīng)的圖片調(diào)用微信“預(yù)覽圖片接口”進(jìn)行圖片預(yù)覽
當(dāng)圖片等于最大圖片數(shù)時(shí),最后那個(gè)小相機(jī)圖案消失
暴露出兩個(gè)方法供別的組件調(diào)用①上傳圖片方法(上傳到微信服務(wù)器并執(zhí)行上傳成功后的回調(diào))uploadImage ②獲取所有圖片信息方法,包括初始化相冊(cè)、刪除過(guò)的、新增的圖片信息getAllImgInfo
OK,介紹完畢,現(xiàn)在正式開(kāi)始!
一.使用vue-router做路由,搭建show-album.js
整個(gè)功能叫show-album,所以這個(gè)功能的js我們就改名為show-album.js,這個(gè)js的結(jié)構(gòu)是這樣:
define(["vue","vueResource","vueRouter","vAlbum"],function (Vue,VueResource,VueRouter,Album) { // 安裝資源模塊 Vue.use(VueResource); // 安裝路由模塊 Vue.use(VueRouter); // jquery在執(zhí)行post請(qǐng)求時(shí),會(huì)設(shè)置Content-Type為application/x-www-form-urlencoded, // 所以服務(wù)器能夠正確解析,而使用原生ajax請(qǐng)求時(shí),如果不顯示的設(shè)置Content-Type,那么默認(rèn)是text/plain, // 這時(shí)服務(wù)器就不知道怎么解析數(shù)據(jù)了,所以才只能通過(guò)獲取原始數(shù)據(jù)流的方式來(lái)進(jìn)行解析請(qǐng)求數(shù)據(jù)。 // 由于vue是使用原生POST,所以要設(shè)置一下服務(wù)器才能正確解釋POST過(guò)去的數(shù)據(jù) Vue.http.options.emulateJSON = true; //定義mainPage頁(yè)面 var mainPage = Vue.extend({ template : "#main-page-temp" }) //定義detailPage頁(yè)面 var detailPage = Vue.extend({ template : "#detail-page-temp", components : { 'album' : Album } }) // 根組件 var showAlbum = Vue.extend({ components : { 'main-page' : mainPage, 'detail-page' : detailPage } }) // 實(shí)例化路由 var router = new VueRouter(); // 配置路由 router.map({ '/main-page' : { name : 'mainPage', component: mainPage }, //這里使用路由的動(dòng)態(tài)片段 '/detail-page/:inspection_id/:image_type' : { name : 'detailPage', component : detailPage } }); router.redirect({ // 重定向任意未匹配路徑到 /home '*': '/main-page' }); // 啟動(dòng)應(yīng)用 // 路由器會(huì)創(chuàng)建一個(gè)實(shí)例,并且掛載到選擇符匹配的元素上。 router.start(showAlbum, '#show-album'); });
HTML那邊就很簡(jiǎn)單了:
<template id="main-page-temp"> <group> <cell v-for="list in lists" title="測(cè)試" value="點(diǎn)擊" is-link v-link="{'name':'detailPage',params: { 'inspection_id': list.inspection_id,'image_type' : list.image_type }}"> </cell> </group> </template> <template id="detail-page-temp"> <album v-ref:album :img-srcs="initImgSrcs" ></album> <button style="width: 100%;margin-top: 20px" 點(diǎn)擊我觸發(fā)getAllImgInfo方法 </button> </template> <div id="show-ablum"> <!-- 路由外鏈 --> <router-view></router-view> </div>
現(xiàn)在點(diǎn)擊主頁(yè)上的一條記錄,就可以跳轉(zhuǎn)到詳情頁(yè),在詳情頁(yè)后退,就會(huì)回到主頁(yè)了。這樣總體結(jié)構(gòu)就完成了。
二.開(kāi)發(fā)微信上傳圖片組件
具體的代碼就不羅列出來(lái)了,我們就按照上面的組件功能清單,說(shuō)說(shuō)每個(gè)功能怎樣完成
1.接收父組件傳過(guò)來(lái)的參數(shù)進(jìn)行上傳圖片組件的初始化
首先,子組件中設(shè)置好props
props : { //初始化有無(wú)照片 imgSrcs : { type : Array, default : [] }, //是否可編輯 默認(rèn)true canEdit : { type : Boolean, default : true }, //最大上傳數(shù) 默認(rèn)9 maxNum : { type : Number, default : 9 }, //上傳后的回調(diào) afterUpload : { type : Function } }
然后在父組件中使用子組件時(shí)把參數(shù)傳進(jìn)去即可
<album v-ref:album :img-srcs="initImgSrcs" :canEdit="true" :afterUpload="afterUploadFunction" > </album>
2.點(diǎn)擊最后那個(gè)小相機(jī)圖案調(diào)用微信”從手機(jī)相冊(cè)中選圖接口”,用戶(hù)可以在自己手機(jī)上選圖
在小相機(jī)圖案的html中綁定chooseImage方法@click=”chooseImage”
<span class="add-img-icon"> <img src="../Public/Home/source/image/camera.png" @click="chooseImage"> </span>
然后在methods中添加該方法,通過(guò)wx.chooseImage請(qǐng)求微信選擇圖片接口。使用微信js-sdk前需要配置,所以我們?cè)诮M件的ready時(shí)就進(jìn)行配置即可。
ready : function() { //配置微信JS-SDK this.getSignPackage(); }, methods : { chooseImage : function () { var _this = this; wx.chooseImage({ count: _this.maxNum - _this.albums.length, // 默認(rèn)9 sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認(rèn)二者都有 sourceType: ['album', 'camera'], // 可以指定來(lái)源是相冊(cè)還是相機(jī),默認(rèn)二者都有 success: function (res) { var _localIds = res.localIds; //記錄新增照片信息 for (var i = 0,len = _localIds.length;i < len;i ++) { _this.newImagesCache.push(_localIds[i]); } //按比例生成縮略圖 _this.renderImage(_localIds); } }); } }
3.選完圖片后,圖片按比例調(diào)整尺寸變成如圖所示那樣的縮略圖
這里要使用到圖片預(yù)處理,即var img = new Image ();通過(guò)實(shí)例化一個(gè)Image實(shí)例去獲取原圖的尺寸,我們才可以根據(jù)這個(gè)原圖尺寸去計(jì)算出相應(yīng)的等比例縮略圖。具體是這樣:
var img = new Image(); var $albumSingle = ""; //這里的順序是先new Image(),然后執(zhí)行img.src,完了之后圖片才算裝載完成 //這樣最后才會(huì)調(diào)用onload方法 img.onload = function() { albumsData = { localId : imgSrcs[i], albumSingleStyle : {height : imgWrapWidth + "px"}, //compressImage是壓縮圖片的方法,將這個(gè)圖片實(shí)例以及圖片父元素的寬度傳進(jìn)去來(lái)計(jì)算。 imgElementStyle : _this.compressImage(img,imgWrapWidth) }; _this.albums.push(albumsData); }; img.src = imgSrcs[i];
特別注意的一個(gè)地方:由于每張圖片的都有自己的尺寸樣式,所以我們要在組件的data選項(xiàng)中添加一個(gè)albums的數(shù)據(jù)作為照片的數(shù)據(jù)集,里面包含每張照片自己的路徑與樣式,這樣循環(huán)渲染每張圖片時(shí),才會(huì)每張圖片對(duì)應(yīng)自己的屬性。還有就是,因?yàn)橄嗤膱D片可以重復(fù)上傳,所以循環(huán)時(shí)要加上track-by=”$index”
//每張圖片自己的屬性 albumsData = { localId : imgSrcs[i], albumSingleStyle : {height : imgWrapWidth + "px"}, //compressImage是壓縮圖片的方法,將這個(gè)圖片實(shí)例以及圖片父元素的寬度傳進(jìn)去來(lái)計(jì)算。 imgElementStyle : _this.compressImage(img,imgWrapWidth) }; //將每張圖片的屬性都放到albums數(shù)據(jù)集里 _this.albums.push(albumsData);
4.點(diǎn)擊相應(yīng)的圖片調(diào)用微信“預(yù)覽圖片接口”進(jìn)行圖片預(yù)覽<img @click="previewImage($index)">
在圖片中綁定點(diǎn)擊事件,傳入該圖片的索引,去觸發(fā)一個(gè)方法:
previewImage : function (index) { var _albums = this.albums; var urls = this.getLocalIds(_albums); wx.previewImage({ current: urls[index], // 當(dāng)前顯示圖片的http鏈接 urls: urls // 需要預(yù)覽的圖片http鏈接列表 });
5.點(diǎn)擊每張圖片右上角的叉叉可以刪除圖片
這個(gè)在叉上綁定點(diǎn)擊事件,這個(gè)事件去處理刪除圖片。
<i class="close-icon" @click="deleteImage($index,album)" v-if="canEdit"></i>
deleteImage方法,由于要記錄下用戶(hù)刪除了哪些初始化的圖片,所以要在刪除時(shí)判斷一下這張圖片是不是初始化時(shí)就有的:
deleteImage : function (index,album) { // 比較要?jiǎng)h除的照片是否在初始化照片里 for (var i = 0,len = this.oldImagesCache.length;i < len;i ++) { if (album.localId === _oldImagesCache[i]) { this.deleteImagesList.push(_oldImagesCache[index]); } } this.canEdit && this.albums.$remove(album); }
6.當(dāng)圖片等于最大圖片數(shù)時(shí),最后那個(gè)小相機(jī)圖案消失 v-if=”albums.length < 9”
7.暴露出兩個(gè)方法供別的組件調(diào)用①上傳圖片方法(上傳到微信服務(wù)器并執(zhí)行上傳成功后的回調(diào))uploadImage ②獲取所有圖片信息方法,包括初始化相冊(cè)、刪除過(guò)的、新增的圖片信息getAllImgInfo
怎樣暴露方法供別的組件調(diào)用,這是個(gè)大問(wèn)題。我也不知道怎樣做才是最佳實(shí)踐,因?yàn)樽龇ㄓ卸喾N,比如子組件$dispatch,然后父組件在events里接收一下,但這樣好像很麻煩,于是我選擇了這樣做:
在子組件中使用v-rel:xxx添加該組件索引
<album v-ref:album :img-srcs="initImgSrcs" ></album>
然后在父組件里通過(guò)this.$refs.xxx.uploadImage()即可調(diào)用子組件暴露出來(lái)的方法
本文已被整理到了《JavaScript微信開(kāi)發(fā)技巧匯總》,歡迎大家學(xué)習(xí)閱讀。
為大家推薦現(xiàn)在關(guān)注度比較高的微信小程序教程一篇:《微信小程序開(kāi)發(fā)教程》小編為大家精心整理的,希望喜歡。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- vue+element實(shí)現(xiàn)圖片上傳及裁剪功能
- vue.js 實(shí)現(xiàn)圖片本地預(yù)覽 裁剪 壓縮 上傳功能
- cropper js基于vue的圖片裁剪上傳功能的實(shí)現(xiàn)代碼
- vue實(shí)現(xiàn)移動(dòng)端圖片裁剪上傳功能
- Vue + Node.js + MongoDB圖片上傳組件實(shí)現(xiàn)圖片預(yù)覽和刪除功能詳解
- vue中使用elementUI組件手動(dòng)上傳圖片功能
- vue+elementUi圖片上傳組件使用詳解
- 基于vue-upload-component封裝一個(gè)圖片上傳組件的示例
- vue上傳圖片組件編寫(xiě)代碼
- vuejs開(kāi)發(fā)組件分享之H5圖片上傳、壓縮及拍照旋轉(zhuǎn)的問(wèn)題處理
- vue 圖片裁剪上傳組件的實(shí)現(xiàn)
相關(guān)文章
vue中el-table多層級(jí)嵌套的具體實(shí)現(xiàn)
本文主要介紹了vue中el-table多層級(jí)嵌套的具體實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10Vue filter 過(guò)濾當(dāng)前時(shí)間 實(shí)現(xiàn)實(shí)時(shí)更新效果
這篇文章主要介紹了Vue filter 過(guò)濾當(dāng)前時(shí)間 實(shí)現(xiàn)實(shí)時(shí)更新效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12解決vue axios跨域 Request Method: OPTIONS問(wèn)題(預(yù)檢請(qǐng)求)
這篇文章主要介紹了解決vue axios跨域 Request Method: OPTIONS問(wèn)題(預(yù)檢請(qǐng)求),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08Vue數(shù)據(jù)代理的原理和實(shí)現(xiàn)
數(shù)據(jù)代理是什么?通過(guò)一個(gè)對(duì)象代理,對(duì)另一個(gè)對(duì)象中屬性的操作,簡(jiǎn)單就是說(shuō):可以通過(guò)?對(duì)象b?對(duì)?對(duì)象a?中的屬性進(jìn)行操作,這里我學(xué)到的數(shù)據(jù)代理是用Object.defineProperty這個(gè)方法進(jìn)行操作2022-11-11vue中input type=file上傳后@change事件無(wú)效的解決方案
這篇文章主要介紹了vue中input type=file上傳后@change事件無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05瀏覽器事件循環(huán)與vue nextTicket的實(shí)現(xiàn)
這篇文章主要介紹了瀏覽器事件循環(huán)(結(jié)合vue nextTicket)的實(shí)現(xiàn)方法,需要的朋友可以參考下2019-04-04關(guān)于Vue.js 2.0的Vuex 2.0 你需要更新的知識(shí)庫(kù)
關(guān)于Vue.js 2.0 的 Vuex 2.0你需要更新的知識(shí)庫(kù),感興趣的小伙伴們可以參考一下2016-11-11Vue Element-UI中el-table實(shí)現(xiàn)單選的示例代碼
在element-ui中是為我們準(zhǔn)備好了可直接使用的單選與多選屬性的,本文主要介紹了Vue Element-UI中el-table實(shí)現(xiàn)單選的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12