最近工作比较紧张,除了日常的小需求之外,还做了一个给商户用的后台。技术栈除了vue之外,还用到了materialize
这个UI库地址,但是这个库有一个缺点,那就是强依赖与jquery。
因为是后台,依赖juqery倒也没什么,因为是在pc端使用对文件大小的要求不是特别高,而且基于juqery的插件特别多,有些地方如果自己去处理可能会存在一些不兼容的问题,用插件会避免很多怪异的问题。
由于这个业务交互不是特别复杂,其中有两点可以分享的:一个就是前端处理二维码及下载,只需要从后端获取到生成二维码的url,就可以生成二维码以及把他下载下来,不需要后台的处理;另一个是应用七牛的SDK去上传图片,其上传也是从前端来完成,不需要后端处理。
前端直接生成二维码及下载
生成二维码这个没什么,就是一个生成二维码的库地址这个库是基于jquery的,github上还有不依赖于jquery的库。这样二维码就生成了。
下载二维码,原理是这样的:把生成的img标签利用canvas的toDataURL()
方法转变为base64格式的,然后把base64的串放到a标签
的href属性中。利用a标签
的download属性,就可以把它下载下来。如果不仅仅需要二维码而是需要在二维码中加入一些文字或者背景图的话,就可以利用canvas把二维码和需要的文字背景图都绘制到canvas中,再获取这个canvas的toDataURL()
,再依据上面的方法去下载下来。
不过这种方法也有不足的地方,比如说批量下载。这种方法如果需要批量下载就必须依靠js,然后去遍历a标签
去主动触发click事件。
下面贴一下代码就好咯~
1 | //生成二维码 |
使用七牛SDK上传图片
七牛的开发文档地址这里。
按照七牛文档和demo就可以很快实现一个上传图片的功能。我来说一下上传的大概过程和我遇到的一个问题。
首先服务端的会先做一些工作,这个我们不太需要关心只要知道我们在上传图片之前,需要先向服务端去发起一次请求去拿到token和key,因为可以看到七牛上传图片时是需要这两个参数的。然后开始上传图片,上传图片后还有一个成功回调事件,在回调事件中可以做一些事情。(告知服务端图片上传成功了,并把这张图片的url告诉服务端,这样才能把图片对应起来)
这里这再插一句,七牛的SDK使用的plupload插件是这样的:他在初始化的时候需要的参数有token,按钮的id
,还有一个可选的参数key(这个参数是可以把文件的url替换成你自定义的)。然后会在方法执行时会去寻找你这个id的button,去初始化它,在这个标签下面再去创建一个input标签,在你点击这个id的button的时候他会去隐式的点击下面的input来唤起浏览器选择文件。
好,大概的过程就是这样的。没有什么问题,但是不管文档和demo都只说了只有一个按钮的情况。如果我有一个列表,上面有很多上传按钮这种情况该怎么办?文档上有类似问题:地址。但是他这里说的情况是固定的几个按钮,并且知道他的token和key,还有按钮标签的id
。
这种是不符合我目前需求的,因为我目前整个列表有几个上传按钮都是不确定的,按钮的id
等等也是不固定的,我要等请求后端接口拿到token和key之后,再去初始化按钮,并且每个按钮和列表每一行的商品要一一对应。所以在完成这个初始化多个上传按钮时碰到了问题。
我们分析一下:如果需要一一对应那么我必须使每一行的button都有自己单独的id、token、和key(因为需要自定义上传图片的url)。
最开始我是这么写的:(大概过程可以看注释)
1 | //请求商品列表 |
请注意我标**的那几行,我本意是把每一个ajax请求到的key,赋到每一个初始化按钮的方法中去,但是如果我们实际这么去写的话,token是对的,但是key总是最后一个请求的key,原因就是初始化中'Key'
这个方法,并不是在方法初始化的时候就去执行了,而是你再点击这个按钮的时候再去获取这个key的值,所以当你点击按钮时这个key的值就是最后一次请求到key的值了。(只有一个key会造成上传了多张图片,但是你只会有一个url的情况发生)
那如何去在一个页面用七牛的SDK去初始化N个上传按钮呢?
我当时试了闭包这种方法,大概是这样:
1 | (function (key) { |
但是并不可以。
找到了一种变通式的解决方法,就是在你每次点击按钮时,去渲染一个新的DOM,再用这个新的DOM去执行初始化的方法:
1 | var rand_num = parseInt(Math.random()*100000000) |
这样同步的来进行,一次只有一个token和key,初始化一个按钮,这样就不会存在上面的问题,但是这样就意味着你点击上传按钮之后,又会出来一个蒙层点击蒙层上的按钮才可以选择图片,这样体验未免有些太差了。
解决
最后经过一下午的尝试,最后也是受到了demo的启发:
1 | 'FileUploaded': function(up, file, info) { |
七牛给的上传说明中有这么一段,方法的第一个参数是up,通过注释我们可以看出这个参数可以获取到Qiniu.uploader
这个方法的一些配置参数的值,比如这一行var domain = up.getOption('domain');
他就获取到了domain这个配置的值(即https://xxxxxxxxx.com/
),可以看到'Key'
这个方法也会接受up
这个参数,所以可不可以在配置中多加一个keyValue的多余配置,来储存key值呢?
经过试验答案是可以的!大概这样:(相同代码就不再重复)
1 | var uploader = Qiniu.uploader({ |
其他地方不变,这样经过试验可以很好地解决初始化多个按钮的问题!