likes
comments
collection
share

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

作者站长头像
站长
· 阅读数 85

背景

无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市场上各种上传插件都有。但是支持多种格式或者不限格式的上传组件却寥寥无几。于是我在插件市场上找了个‘yt-upload‘全文件上传插件,分享下它的使用方式。

  • 说明:为啥不用uniapp提供的uni-file-picker扩展组件呢,因为我开发的是app,而它有多种格式文件上传只支持小程序和H5限制。

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

介绍

关于为啥用yt-upload这个插件呢,因为我在插件市场上找到了两个一样的插件,看了下更新时间,这个比较新。

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市 上面这个更完善,但是他的示例代码还复制少了,所以不要用他的示例代码。但是插件装了也能用,估计插件他就是改了个名字,可能更新了里面的一些bug。 uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

开始使用

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

  • 2. 安装完成,项目中多了个模块文件,这样我们就能全局使用该组件了。

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

  • 3. 将组件放到要使用的页面中,包含上传按钮,上传记录文件名显示,点击文件名可预览文件,上传记录删除操作:
<view class="tn-flex">
	<view class="tn-flex-1">
		<view class="tn-shadow-blur">
			<yt-upload ref="uploadFile" childId="upload1" width="150rpx" :option="option" :size="30" :count="3"
				:formats="formats" :debug="false" :instantly="true" @uploadEnd="onuploadEnd" @progress="upProgress"
				@change="upChange">
				<view class="tn-bg-orangered tn-color-white tn-text-center">
					选择附件</view>
			</yt-upload>
		</view>
		<view class="tn-shadow-blur" v-for="(item,index) in files.values()" :key="index">
			<!-- <image style="width: 100rpx;height: 100rpx;" :src="item.path" mode="widthFix">
									</image> -->
			<text class="tn-color-blue" @click="look(item.name)">{{item.name}}</text>
			<text @click="clear(item.name)" v-if="item.type=='success'"
				style="margin-left: 10rpx;padding: 0 10rpx;border: 1rpx solid #ff0000;color: #ff0000;">删除</text>
		</view>
	</view>
</view>

我的页面效果如下,因为我用了图鸟的UI,你们可以自己改下样式:

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

组件有三个重要的属性,option是定义文件上传接口的相关参数,count是上传文件数量限制,formats是文件上传格式,不写默认全文件格式,写了的话就是逗号隔开,,例如png,jpg,pdf等。下面其他的参数大家可以看下

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

  • 4. data中的配置,files是上传回显记录集合,option则是上传配置,formats是限制允许上传的格式。
option: {
	// 上传服务器地址,需要替换为你的接口地址
	url: config.baseUrl + '/options/uploadFile', // 该地址非真实路径,需替换为你项目自己的接口地址
	// 上传附件的key,后端处理获取文件的字段
	name: 'file'
},
formats: '', //限制允许上传的格式,空串=不限制,默认为空,多个格式以逗号隔开,例如png,jpg,pdf
// 文件回显列表
files: new Map(),

    1. 上传时用到的回调函数,
			 * 某文件上传结束回调(成功失败都回调)
			 * @param {Object} item 当前上传完成的文件
			 */
			onuploadEnd(item) {
				console.log(`${item.name}已上传结束,上传状态=${item.type}`);

				// 更新当前窗口状态变化的文件
				this.files.set(item.name, item);

				//上传完成后取服务端数据
				if (item['responseText']) {
					console.log('演示服务器返回的字符串JSON转Object对象', item.responseText);
					this.files.get(item.name).responseText = JSON.parse(item.responseText);
					//赋值给表单字段
					// console.log(this.files.get(item.name).responseText.data.url);
					const res_data = this.files.get(item.name).responseText.data
					let data = {
						name: item.name,
						value: res_data.url,
						type:res_data.type
					}
					this.formData.files = this.formData.files.concat([data])
					console.log('before delete', this.formData.files);
				}
				// 强制更新视图
				this.$forceUpdate();

				// ---可删除--演示判断是否所有文件均已上传成功
				let isAll = [...this.files.values()].find(item => item.type !== 'success');
				if (!isAll) {
					console.log('已全部上传完毕');
				} else {
					console.log(isAll.name + '待上传');
				}

			},
			upProgress(e) {
				console.log('upProgress', e, e.type);
			},
			upChange(files) {
				console.log('当前选择的文件列表:', JSON.stringify([...files.values()]));
				// 更新选择的文件 
				this.files = files;
				// 强制更新视图
				this.$forceUpdate();
			},
			/**
			 * 移除某个文件
			 * @param {Object} name 带后缀名的文件名称
			 */
			clear(name) {
				// name=指定文件名,不传name默认移除所有文件
				this.$refs['uploadFile'].clear(name);
				//移除表单里的文件
				this.formData.files = this.formData.files.filter(function(item) {
					return item.name !== name
				});
				console.log('after delete', this.formData.files);
			},
    1. 服务端处理上传的接口,我用的是PHP开发的:
 try {
            $tmp_name = $_FILES['file']['tmp_name'];
            $file_name = $_FILES['file']['name'];
            // var_dump($_FILES);
            //初始化变量
            $date = date('Ymdhis');
            //文件目录
            $file_dir = root_path() . 'public/files/' . date('Ymd') . '/';
            if (!is_dir($file_dir)) {
                mkdir($file_dir);
            }
            //上传文件路径
            $domain = Env::get('app.domain');
            //如果当前图片不为空
            if (!empty($file_name)) {
                $uptype = explode(".", $file_name);
                //图片名称
                $newname = $date . rand(10000, 99999) . "." . $uptype[count($uptype) - 1];
                $uplad_name = $newname;
                //如果上传的文件没有在服务器上存在
                if (!file_exists($file_dir . $uplad_name)) {
                    //把图片文件从临时文件夹中转移到我们指定上传的目录中
                    $file = $file_dir . $uplad_name;
                    move_uploaded_file($tmp_name, $file);
                    chmod($file, 0644);
                    $img_url = $domain . '/files/' . date('Ymd') . '/' . $newname;
                    if(in_array($uptype[count($uptype) - 1],['jpg','jpeg','png','gif','JPG','JPEG','PNG','GIF'])){
                        $type = 'image';
                    }else{
                        $type = 'file';
                    }
                    $data = [
                        'type'=> $type,
                        'url'=>$img_url
                    ];
                    return CatchResponse::success($data, "上传成功");
                }
            } else {
                return CatchResponse::fail('请选择文件上传');
            }
        } catch (\Exception $e) {
            return CatchResponse::fail($e->getMessage());
        }

返回值包含了两个参数,文件类型是图片还是文件文档,便于前端预览时使用,如果是图片,则用image标签回显,如果是文件,则用uni.openDocument打开文档,上传成功界面:

uniapp实现多格式文件上传无论是开发APP、H5、亦或是小程序,我们经常用到图片上传,uniapp官方的组件,插件市

点击文件名预览文件代码如下,参数是文件名,根据这个文件名我们可以获取到files集合中的服务端返回值(因为预览图片、问价要用文件网络地址),这样就能看到上传文件内容了。

look(name) {
	let data = this.formData.files.filter(function (item) {
		return item.name === name
	});
	console.log(data);
	if (data[0].type == 'image') {
		this.showImage = true
		this.imageUrl = data[0].value
		// console.log(this.imageUrl);
		return
	}
	uni.downloadFile({
		url: data[0].value, //只能是网络地址
		success: function (res) {
			var filePath = res.tempFilePath;
			uni.openDocument({
				filePath: filePath,
				showMenu: true,
				success(e) {
					console.log('success', e);
				},
				fail(e) {
					console.log('fail', e);
				}
			});
		}
	})
},

总结

这样的文件上传打破了一些组件的局限性,让我们能够自由地选择适合自己的上传格式,对于我们的开发是很有帮助的。记录一下,下次不用翻以前的代码也会写了呢。

转载自:https://juejin.cn/post/7362821013243166720
评论
请登录