uniapp多格式文件选择(APP,H5)【补充】

uniapp多格式文件选择(APP,H5)【补充】

背景

之前写过一篇【uniapp多格式文件选择(APP,H5)】文章使用renderjs来实现H5端和APP端选择文件,当时文章中只涉及了如何选择文件,今天的文章作为补充来实现怎么将选择好的文件进行上传。

实现思路

上次我们能获取到blob格式的文件流,在H5端这个blob流可以直接通过uni.uploadFile相关的API进行上传,这种方案本来就是使用html端的dom实现,所以并无问题。但是在APP端的blob流上传则会报错。这里我们的思路是再renderjs视图层通过FileReader将文件转成base64,然后把选择的文件base64数据发送到逻辑层,逻辑层将base64转成一个path,这样就可以正式上传。

代码实现

思路上面已经有了,这里就直接上代码:

<template>
	<view class="content">
		<button @click="fileChoose">文件选择</button>
		<view :fileData="fileData" :change:fileData="renderJS.receiveFileData"/>
		<view style="word-break:break-all;">文件路径:{{filePath}}</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				fileData: '',
				filePath: '',
				fileName: ''
			}
		},
		onLoad() {
			
		},
		methods: {
			fileChoose(){
				this.fileData = 'test'
				setTimeout(()=> {
					this.fileData = ''
				},1000)
			},
			async receiveRenderFile(result){
			  // #ifdef APP-PLUS
			  const fileUrl = await this.base64toPath(result.filePath, result.name);
			  this.fileName = fileUrl.relativePath
			  this.filePath = fileUrl.localAbsolutePath
			  // #endif
			  // #ifdef H5
			  this.fileName = result.name
			  this.filePath = result.filePath
			  // #endif
			  console.log('选择文件的路径:'+this.filePath)
			},
			//将base64转成路径
			async base64toPath(base64, attachName) {
				console.log('base64开始转化成文件')
				let _that = this;
				return new Promise(function(resolve, reject) {
					const filePath = `_doc/yourFilePath/${attachName}`;
					plus.io.resolveLocalFileSystemURL('_doc', function(entry) {
						entry.getDirectory("yourFilePath", {
							create: true,
							exclusive: false,
						}, function(entry) {
							entry.getFile(attachName, {
								create: true,
								exclusive: false,
							}, function(entry) {
								entry.createWriter(function(writer) {
									writer.onwrite = function(res) {
										console.log('base64转化文件完成')
										const obj = {
											relativePath: filePath,
											localAbsolutePath: plus.io
												.convertLocalFileSystemURL(
													filePath)
										}
										resolve(obj);
									}
									writer.onerror = reject;
									writer.seek(0);
									writer.writeAsBinary(_that
										.getSymbolAfterString(base64,
											','));
								}, reject)
							}, reject)
						}, reject)
					}, reject)
				})
			},
			// 取某个符号后面的字符
			getSymbolAfterString(val, symbolStr) {
				if (val == undefined || val == null || val == "") {
					return "";
				}
				val = val.toString();
				const index = val.indexOf(symbolStr);
				if (index != -1) {
					val = val.substring(index + 1, val.length);
					return val;
				} else {
					return val
				}
			}
		}
	}
</script>
<script module="renderJS" lang="renderjs">
	export default {
		data() {
			return {}
		},
		mounted() {
			console.log('mounted')
		},
		methods: {
			receiveFileData(newValue, oldValue, ownerVm, vm){
				if(!newValue){
					return
				}
				this.createFileInputDom(ownerVm)
			},
			createFileInputDom(ownerVm){
				let fileInput = document.createElement('input')
				fileInput.setAttribute('type','file')
				fileInput.setAttribute('accept','*')
				fileInput.click()
				fileInput.addEventListener('change', e => {
					let file = e.target.files[0]
					// #ifdef APP-PLUS
					console.log('开始读取文件')
					let reader = new FileReader();
					//读取图像文件 result 为 DataURL, DataURL 可直接 赋值给 img.src
					reader.readAsDataURL(file);
					reader.onload = function(event) {
						const base64Str = event.target.result; // 文件的base64
						console.log('文件读取完成')
						//如果文件较大,这里调用到逻辑层可能时间较长
						ownerVm.callMethod('receiveRenderFile', {
							name: file.name,
							filePath: base64Str
						})
					}
					// #endif
					// #ifdef H5
					const filePath = URL.createObjectURL(file)
					ownerVm.callMethod('receiveRenderFile',{
						name: file.name,
						filePath: filePath
					})
					// #endif
				})
			}
		}
	}
</script>
<style>
</style>

运行结果

我们这里选择手机一个txt文件

在这里插入图片描述

查看打印日志
在这里插入图片描述
界面上选择结果
在这里插入图片描述

到这里拿到文件路径之后就可以上传了。

注意事项

这种方式因为要进行逻辑层和视图层通讯,在APP侧如果选择大文件可能会造成内存溢出或者等待时间过长的问题,请自行取舍。

尾巴

今天的文章就到这里了,希望能给大家帮助,如果喜欢我的文章,欢迎给我点赞,评论,关注,谢谢大家!

<think>好的,我现在需要帮助用户解决在UniApp小程序中实现跳转到APP的功能的问题。首先,我需要仔细分析用户的查询内容。用户提供的引用资料都是关于在UniApp中从APP跳转到小程序,或者小程序之间跳转,但没有直接提到如何从小程序跳转到APP。因此,我需要根据现有的知识来回答这个问题,同时参考已有的引用内容,确保回答的准确性。 首先,我需要了解微信小程序的开放能力。根据微信的官方文档,小程序本身有严格的权限限制,特别是跳转到APP的功能。微信小程序平台出于用户体验和安全考虑,通常不允许直接从小程序跳转到原生APP。不过,可能存在一些特定的API或方法,比如使用URL Scheme或者Universal Links来实现这种跳转。 接下来,我需要检查UniApp的官方文档是否有相关的API支持。UniApp作为一个跨平台框架,可能会封装一些平台特定的功能。例如,在APP端可以使用`uni.navigateToMiniProgram`跳转到小程序,但反过来可能没有直接的API。这时候可能需要依赖微信小程序本身的API,或者结合其他方法。 然后,用户提供的引用[1]到[4]都是关于从APP跳转小程序或小程序间跳转,这提示在UniApp中实现这些跳转需要特定的API和参数配置。例如,使用`uni.navigateToMiniProgram`需要提供目标小程序的appid、路径、额外数据等。但跳转到APP可能需要不同的方法。 根据我的知识,微信小程序中要实现跳转到APP,通常需要用户主动触发,例如点击按钮打开APP。这可以通过使用`<button>`组件的`open-type`属性设置为`launchApp`来实现。同时,APP端需要配置相应的URL Scheme,并且需要在微信开放平台关联相同的应用,以确保跳转的有效性。 在UniApp中,可能需要编写条件编译的代码,针对微信小程序平台使用特定的开放标签。例如,在微信小程序中,可以使用`<button open-type="launchApp" app-parameter="参数">打开APP</button>`,但这需要APP和小程序在同一个微信开放平台账号下关联,并且APP已经通过了审核。 此外,还需要考虑不同平台的兼容性。例如,在H5端可能无法直接跳转到APP,但可以通过URL Scheme在移动浏览器中打开APP。在UniApp中可能需要使用`uni.navigateTo`或`uni.redirectTo`等方法,结合平台判断来实现多端适配。 总结可能的实现步骤: 1. 在微信开放平台关联小程序和APP,确保它们属于同一账号。 2. 在APP端配置URL Scheme,例如`myapp://path?param=value`。 3. 在小程序中使用`<button open-type="launchApp">`并设置相应的`app-parameter`。 4. 处理用户未安装APP的情况,可能需要提供下载链接或提示。 同时,需要注意微信小程序的最新政策,因为权限和API可能会变化。需要查阅最新的微信官方文档和UniApp文档,确认相关API的可用性。 在回答用户时,需要明确说明实现的步骤、需要的配置、可能遇到的限制(如用户未安装APP时的处理),以及不同平台的兼容性问题。同时,可以引用UniApp和微信的官方文档作为参考,确保信息的准确性。</think>### UniApp小程序跳转至APP的实现方法 在UniApp中实现**微信小程序跳转至APP**的功能需结合微信开放平台的特定接口,但由于平台限制,需注意以下核心要点: --- #### **1. 基础实现条件** - **微信开放平台关联**:确保目标APP与小程序已在同一微信开放平台账号下完成关联[^1]。 - **URL Scheme配置**:在APP的配置文件中声明自定义协议(如`myapp://`),用于通过链接唤起APP--- #### **2. 代码实现步骤** ##### **微信小程序端** 使用微信原生`<button>`组件的`launchApp`开放能力: ```html <button open-type="launchApp" app-parameter="key=value" @error="handleError"> 点击打开APP </button> ``` - **参数说明**: - `app-parameter`:传递给APP的自定义参数。 - `@error`:监听跳转失败事件(如未安装APP)。 ##### **UniApp中适配** 通过条件编译区分微信小程序平台: ```html <template> <view> <!-- #ifdef MP-WEIXIN --> <button open-type="launchApp" app-parameter="from=miniprogram" @error="onLaunchAppError"> 打开APP </button> <!-- #endif --> </view> </template> <script> export default { methods: { onLaunchAppError(e) { uni.showToast({ title: '未安装APP,请下载', icon: 'none' }); } } } </script> ``` ##### **APP端配置** - **Android**:在`AndroidManifest.xml`中声明`intent-filter`: ```xml <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="myapp" /> </intent-filter> ``` - **iOS**:在`Info.plist`中注册URL Scheme: ```xml <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> </dict> </array> ``` --- #### **3. 补充说明** - **未安装APP的兜底处理**:可通过`@error`事件引导用户跳转下载页: ```javascript onLaunchAppError() { uni.navigateTo({ url: '/pages/download-app' // 跳转至下载引导页 }); } ``` - **跨平台兼容性**:此方案仅适用于微信小程序,其他平台(如支付宝小程序)需使用对应API。 --- #### **限制与注意事项** 1. **用户主动触发**:跳转动作必须由用户点击按钮触发,无法通过代码自动执行。 2. **审核要求**:微信要求跳转功能需符合其平台规范,避免滥用[^1]。 3. **参数传递限制**:`app-parameter`仅支持字符串类型,复杂数据需序列化。 ---
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值