這篇文章主要為大家詳細介紹了require.js+vue+vue-router+vue-resource開發微信上傳圖片元件,具有一定的參考價值,有興趣的夥伴們可以參考一下
由於專案是thinkPHP做後端框架,一直以來都是多頁的後端路由,想用火熱的webpack有點無從下手(原諒我太菜,而且推廣vue只有我一個人…),沒辦法,想把vue用起來,唯有在原來的基礎上改進。使用webpack的巨大好處就是可以使用 .vue 這樣的單文件來寫vue元件,這樣每一個元件就是一個 .vue 文件,哪裡用上這個元件就引入進來,維護起來確實很爽。然而一直以來專案用的都是require.js,那又想以這樣的形式來組織vue元件,還要加上vue-router和vue-resource,怎麼破?這篇文章以開發微信上傳圖片元件為範例小結一下require.js+vue+vue-router+vue-resource的開發流程。
用require.js組織你的元件
我們會有一個components目錄去放我們的各個元件,每個元件有用自己名字命名的資料夾,像是這次的範例album元件,裡面就放著這個元件的html、js、css,具體怎麼用require.js去載入html和css,大家百度一下把相關外掛程式下載下來即可。於是該元件的js中就可以在define裡把相關的依賴都加載進去,最後把元件return出去,別的元件也可以透過define載入這個元件,這也達到了模組化管理元件的目的了。
這裡的話,我總結了一個使用require.js寫vue元件的模板,使用WebStorm把這個模板加上去,每次寫元件的時候打幾個字就把模板生成出來,不要太爽! (componentName是模板的變量,模板生成出來你填上你的組件名字就可以)
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 { } }, // 在编译结束和 $el 第一次插入文档之后调用 ready : function() { }, // 在开始销毁实例时调用。此时实例仍然有功能。 beforeDestroy : function() { }, methods : { }, events : { } }); return $componentName$; });
總體預覽這個例子
為了示範完整的流程,我把這個範例做成一個小單頁叫show-album,就兩個頁面:
1.首頁叫main-page
詳情頁裡的功能有:
接收父元件傳過來的參數進行上傳圖片組件的初始化
點擊每張圖片右上角的叉叉可以刪除圖片
點擊最後那個小相機圖案調用微信”從手機相冊中選圖接口”,用戶可以在自己手機上選圖
選完圖片後,圖片按比例調整尺寸變成如圖所示那樣的縮圖
點擊相應的圖片調用微信“預覽圖片接口”進行圖片預覽
暴露出兩個方法供別的組件調用①上傳圖片方法(上傳到微信伺服器並執行上傳成功後的回調)uploadImage ②獲取所有圖片資訊方法,包括初始化相簿、刪除過的、新增的圖片資訊getAllImgInfo
OK,介紹完畢,現在正式開始!
一.使用vue-router做路由,搭建show-album.js
整個函式叫show-album,所以這個函式的js我們就改名為show-album. js,這個js的結構是這樣:
define(["vue","vueResource","vueRouter","vAlbum"],function (Vue,VueResource,VueRouter,Album) { // 安装资源模块 Vue.use(VueResource); // 安装路由模块 Vue.use(VueRouter); // jquery在执行post请求时,会设置Content-Type为application/x-www-form-urlencoded, // 所以服务器能够正确解析,而使用原生ajax请求时,如果不显示的设置Content-Type,那么默认是text/plain, // 这时服务器就不知道怎么解析数据了,所以才只能通过获取原始数据流的方式来进行解析请求数据。 // 由于vue是使用原生POST,所以要设置一下服务器才能正确解释POST过去的数据 Vue.http.options.emulateJSON = true; //定义mainPage页面 var mainPage = Vue.extend({ template : "#main-page-temp" }) //定义detailPage页面 var detailPage = Vue.extend({ template : "#detail-page-temp", components : { 'album' : Album } }) // 根组件 var showAlbum = Vue.extend({ components : { 'main-page' : mainPage, 'detail-page' : detailPage } }) // 实例化路由 var router = new VueRouter(); // 配置路由 router.map({ '/main-page' : { name : 'mainPage', component: mainPage }, //这里使用路由的动态片段 '/detail-page/:inspection_id/:image_type' : { name : 'detailPage', component : detailPage } }); router.redirect({ // 重定向任意未匹配路径到 /home '*': '/main-page' }); // 启动应用 // 路由器会创建一个实例,并且挂载到选择符匹配的元素上。 router.start(showAlbum, '#show-album'); });
HTML那邊就很簡單了:
<template id="main-page-temp"> <group> <cell v-for="list in lists" title="测试" value="点击" 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" 点击我触发getAllImgInfo方法 </button> </template> <p id="show-ablum"> <!-- 路由外链 --> <router-view></router-view> </p>
現在點擊主頁上的一條記錄,就可以跳到詳情頁,在詳情頁後退,就會回到主頁了。這樣整體結構就完成了。
二.開發微信上傳圖片元件
具體的程式碼就不羅列出來了,我們就按照上面的元件功能清單,說每個功能如何完成
首先,子元件中設定好props
props : { //初始化有无照片 imgSrcs : { type : Array, default : [] }, //是否可编辑 默认true canEdit : { type : Boolean, default : true }, //最大上传数 默认9 maxNum : { type : Number, default : 9 }, //上传后的回调 afterUpload : { type : Function } }
然後在父組件中使用子組件時把參數傳進去即可
<album v-ref:album :img-srcs="initImgSrcs" :canEdit="true" :afterUpload="afterUploadFunction" > </album>
<span class="add-img-icon"> <img src="/cms/tpl/Index/Public/Home/source/image/camera.png" @click="chooseImage" alt="使用require.js+vue開發微信上傳圖片元件方法" > </span>
然后在methods中添加该方法,通过wx.chooseImage请求微信选择图片接口。使用微信js-sdk前需要配置,所以我们在组件的ready时就进行配置即可。
ready : function() { //配置微信JS-SDK this.getSignPackage(); }, methods : { chooseImage : function () { var _this = this; wx.chooseImage({ count: _this.maxNum - _this.albums.length, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 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.选完图片后,图片按比例调整尺寸变成如图所示那样的缩略图
这里要使用到图片预处理,即var img = new Image ();通过实例化一个Image实例去获取原图的尺寸,我们才可以根据这个原图尺寸去计算出相应的等比例缩略图。具体是这样:
var img = new Image(); var $albumSingle = ""; //这里的顺序是先new Image(),然后执行img.src,完了之后图片才算装载完成 //这样最后才会调用onload方法 img.onload = function() { albumsData = { localId : imgSrcs[i], albumSingleStyle : {height : imgWrapWidth + "px"}, //compressImage是压缩图片的方法,将这个图片实例以及图片父元素的宽度传进去来计算。 imgElementStyle : _this.compressImage(img,imgWrapWidth) }; _this.albums.push(albumsData); }; img.src = imgSrcs[i];
特别注意的一个地方:由于每张图片的都有自己的尺寸样式,所以我们要在组件的data选项中添加一个albums的数据作为照片的数据集,里面包含每张照片自己的路径与样式,这样循环渲染每张图片时,才会每张图片对应自己的属性。还有就是,因为相同的图片可以重复上传,所以循环时要加上track-by=”$index”
//每张图片自己的属性 albumsData = { localId : imgSrcs[i], albumSingleStyle : {height : imgWrapWidth + "px"}, //compressImage是压缩图片的方法,将这个图片实例以及图片父元素的宽度传进去来计算。 imgElementStyle : _this.compressImage(img,imgWrapWidth) }; //将每张图片的属性都放到albums数据集里 _this.albums.push(albumsData);
4.点击相应的图片调用微信“预览图片接口”进行图片预览
在图片中绑定点击事件,传入该图片的索引,去触发一个方法:
previewImage : function (index) { var _albums = this.albums; var urls = this.getLocalIds(_albums); wx.previewImage({ current: urls[index], // 当前显示图片的http链接 urls: urls // 需要预览的图片http链接列表 });
5.点击每张图片右上角的叉叉可以删除图片
这个在叉上绑定点击事件,这个事件去处理删除图片。
deleteImage方法,由于要记录下用户删除了哪些初始化的图片,所以要在删除时判断一下这张图片是不是初始化时就有的:
deleteImage : function (index,album) { // 比较要删除的照片是否在初始化照片里 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.当图片等于最大图片数时,最后那个小相机图案消失 v-if=”albums.length
7.暴露出两个方法供别的组件调用①上传图片方法(上传到微信服务器并执行上传成功后的回调)uploadImage ②获取所有图片信息方法,包括初始化相册、删除过的、新增的图片信息getAllImgInfo
怎样暴露方法供别的组件调用,这是个大问题。我也不知道怎样做才是最佳实践,因为做法有多种,比如子组件$dispatch,然后父组件在events里接收一下,但这样好像很麻烦,于是我选择了这样做:
在子组件中使用v-rel:xxx添加该组件索引
然后在父组件里通过this.$refs.xxx.uploadImage()即可调用子组件暴露出来的方法
相关文章:
以上是使用require.js+vue開發微信上傳圖片元件方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!