require.js+vue开发微信上传图片组件
作者:余小弟 发布时间:2024-06-05 15:31:01
由于项目是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
2.详情页叫detail-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>
<div id="show-ablum">
<!-- 路由外链 -->
<router-view></router-view>
</div>
现在点击主页上的一条记录,就可以跳转到详情页,在详情页后退,就会回到主页了。这样总体结构就完成了。
二.开发微信上传图片组件
具体的代码就不罗列出来了,我们就按照上面的组件功能清单,说说每个功能怎样完成
1.接收父组件传过来的参数进行上传图片组件的初始化
首先,子组件中设置好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>
2.点击最后那个小相机图案调用微信”从手机相册中选图接口”,用户可以在自己手机上选图
在小相机图案的html中绑定chooseImage方法@click=”chooseImage”
<span class="add-img-icon">
<img src="../Public/Home/source/image/camera.png" @click="chooseImage">
</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.点击相应的图片调用微信“预览图片接口”进行图片预览<img @click="previewImage($index)">
在图片中绑定点击事件,传入该图片的索引,去触发一个方法:
previewImage : function (index) {
var _albums = this.albums;
var urls = this.getLocalIds(_albums);
wx.previewImage({
current: urls[index], // 当前显示图片的http链接
urls: urls // 需要预览的图片http链接列表
});
5.点击每张图片右上角的叉叉可以删除图片
这个在叉上绑定点击事件,这个事件去处理删除图片。
<i class="close-icon" @click="deleteImage($index,album)" v-if="canEdit"></i>
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 < 9”
7.暴露出两个方法供别的组件调用①上传图片方法(上传到微信服务器并执行上传成功后的回调)uploadImage ②获取所有图片信息方法,包括初始化相册、删除过的、新增的图片信息getAllImgInfo
怎样暴露方法供别的组件调用,这是个大问题。我也不知道怎样做才是最佳实践,因为做法有多种,比如子组件$dispatch,然后父组件在events里接收一下,但这样好像很麻烦,于是我选择了这样做:
在子组件中使用v-rel:xxx添加该组件索引
<album v-ref:album :img-srcs="initImgSrcs" ></album>
然后在父组件里通过this.$refs.xxx.uploadImage()即可调用子组件暴露出来的方法
本文已被整理到了《JavaScript微信开发技巧汇总》,欢迎大家学习阅读。
为大家推荐现在关注度比较高的微信小程序教程一篇:《微信小程序开发教程》小编为大家精心整理的,希望喜欢。
猜你喜欢
- 迭代器(Iterable):能直接作用于for循环的对象,统称可迭代对象。例如:list、tuple、set、str、generator都是
- PyQt5窗口布局控件QStackedWidget介绍QTackedWidget是一个堆栈窗口控件,可以填充一些小控件,但是同一时间只有一个
- Golang 是一门非常适合编写网络爬虫的语言,它有着高效的并发处理能力和丰富的网络编程库。下面是一个简单的 Golang 网络爬虫示例:p
- 一、相同点dump 和 dumps 都实现了序列化load 和 loads 都实现反序列化变量从内存中变成可存储或传输的过程称之为序列化序列
- python中zip函数返回一个以元组为元素的列表,其中第 i 个元组包含每个参数序列的第 i 个元素。返回的列表长度被截断为最短的参数序列
- 这几天一直在看《Pro JavaScript Techniques》,书中有不少优美、健壮代码,让我不得不惊叹老外对语言这东西的研究程度之深
- 上次遇到一个需要打包下载批量图片的问题,找了一下发现这个好方法,记录一下。首先新建一个zipfile打包类:<?phpclass zi
- 在上一篇Python接口自动化测试系列文章:Python接口自动化浅析logging日志原理及模块操作流程,主要介绍日志相关概念及loggi
- 任务:用python时间简单的统计任务-统计男性和女性分别有多少人。用到的物料:xlrd 它的作用-读取excel表数据代码:import
- MenuEverywhere 是Mac OS X上的一款小程序,前一阵刚为其完成了程序图标设计。© 2011 IconMo
- 别人复制你网站的文章时自动加上注释,这个功能你在很多网站应该都有体会过,当我们复制一段内容时,就自动在文章后面加上了网站的一些
- 1. Callbacks您可以将回调方法定义为模型结构的指针,在创建,更新,查询,删除时将被调用,如果任何回调返回错误,gorm将停止未来操
- 业务说明:此示例脚本作用,包含方法和逻辑:图像读取,图片尺寸读取,重置图片大小,图片等比缩放,图片拼接,图片覆盖与堆叠(子母图)图片展示:单
- <?php/** * 网站地图更新控制器 * * &nbs
- 数据库快照是怎样工作的可以使用典型的数据库命令CREATE DATABASE语句来生成一个数据库快照,在声明中有一个源数据库快照的附加说明。
- 程序运行效率程序的运行效率分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。时间复杂度主要
- 本文主要讲述:自定义树形控件<el-tree>需求说明:Element UI 官网提供的树形控件包含基础的、可选择的、自定义节点
- 我正在用 MySQL 客户端的时候,突然想到如果可以给查询结果添加排名该多好啊,然后就找到了一个简单的解决办法。下面是一个示例表
- 选择了MySQL的安装版本后,要做的第二项决策是你是使用源码分发版还是二进制分发版。大多数情况,如果你的平台上已经有了一个二进制分发版,你可
- Jupyter NotebookJupyter项目是从Ipython项目中分出去的,在Ipython3.x之前,他们两个是在一起发布的。在I