UniApp 在手机端(Android)打开选择文件和文件写入

复制代码
<!-- 文件选择组件 -->
<template>
	<view>
		<view @click="handleSelectFile"> <!-- 指定一个默认插槽sss -->
			<slot>选择文件</slot>
		</view>
		<view id="fileSelectContainer" :prop="fileProps" :change:prop="fileSelectModule.updateFileProps" r-entry />
	</view>
</template>
<!-- 逻辑层 -->
<script>
	export default {
		name: "FileSelect",
		components: {},
		data() {
			return {
				fileProps: {
					acceptTypes: '.xls,.xlsx',
					selectFileTrigger: false,
					fileStrType: 'Base64' //Base64、String
				}
			}
		},
		onLoad() {},
		methods: {
			handleUniSelectFile() {
				uni.chooseImage({
					count: 6, //默认9
					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
					sourceType: ['album'], //从相册选择
					success: function(res) {
						console.log("uni.chooseImage", res);
						console.log(JSON.stringify(res.tempFilePaths));
					}
				});
			},
			updataSelectFileTrigger(selectFileTrigger) {
				this.fileProps.selectFileTrigger = selectFileTrigger
			},
			handleSelectFile() { //选择文件按钮
				//通过属性改变,配合模块的:change:prop=触发视图层的事件
				this.fileProps.selectFileTrigger = true;
			},
			// 处理文件选择回调
			handleFileSelected(files) {
				this.$emit("fileChange", files)
			},
		}
	}
</script>
<!--视图层:使用 RenderJS模块方式进行APP上非图片和视频选择 -->
<script module="fileSelectModule" lang="renderjs">
	export default {
		data() {
			return {
				fileInputId: "select-file-input",
				fileInput: null,
				fileStrType: null //Base64、String
			};
		},
		mounted() {
			this.createFileInput(); // 动态创建文件输入元素
			console.log('FileSelectModule已挂载');
		},
		methods: {
			createFileInput() { // 创建文件输入元素
				const existingInput = document.getElementById(this.fileInputId);
				if (existingInput) { // 移除已存在的input元素
					existingInput.remove();
				}
				// 创建新的文件输入元素
				this.fileInput = document.createElement('input');
				this.fileInput.id = this.fileInputId;
				this.fileInput.type = 'file';
				this.fileInput.style.display = 'none';

				// 添加文件选择事件监听
				this.fileInput.addEventListener('change',
					(event) => {
						this.handleFileChange(event);
					});
				document.body.appendChild(this.fileInput);
			},

			handleFileChange(event) { // 文件选择文成
				const files = event.target.files;
				if (!files) return;
				let promiseArr = []
				for (let file of files) {
					promiseArr.push(this.fileToBase64OrStr(file))
				}
				Promise.all(promiseArr)
					.then(values => {
						let tempFilePaths = [];
						let tempFiles = []
						for (let fileInfo of values) {
							tempFilePaths.push(fileInfo.path)
							tempFiles.push(fileInfo)
						}
						let result = {
							tempFilePaths,
							tempFiles
						}
						this.$ownerInstance.callMethod('handleFileSelected', result);
					})
					.catch(err => {
						console.log(err);
					})
			},
			triggerFileInput() { // 触发文件输入点击
				if (this.fileInput) {
					this.fileInput.click(); //触发点击事件,进行文件选择
					this.$ownerInstance.callMethod("updataSelectFileTrigger", false) //重置文件选择标识方便下次进行选择
				}
			},
			updateFileProps(newValue, oldValue) { // 更新文件属性
				if (newValue && newValue.selectFileTrigger) { // 监听文件选择触发信号
					this.fileStrType = newValue.fileStrType || "String"
					this.triggerFileInput();
				}
			},
			fileToBase64OrStr(file) { //将文件转场base64
				return new Promise((resolve, reject) => {
					const reader = new FileReader()
					reader.onloadend = () => { //文件读取操作完成时的回调函数
						const base64String = reader.result
						let result = {
							path: base64String,
							size: file.size,
							name: file.name, //这个属性uni.chooseImage中没有
							type: file.type //这个属性uni.chooseImage中没有
						}
						resolve(result)
					}
					reader.onerror = (e) => {
						reject(3)
					}
					//Base64、String
					if ("Base64" === this.fileStrType) {
						reader.readAsDataURL(file) //以URL编码(Base64编码)格式读取文件数据内容
					} else {
						reader.readAsText(file) //以文本格式读取文件数据内容
					}
				})
			}
		}
	};
</script>
<style>
</style>

打开文件选择框截图

相关推荐
777VG2 小时前
PostgreSQL +martin将多张表输出成一个 MVT
前端·数据库·postgresql
mayaairi3 小时前
JS循环语句深度解析:嵌套for、while与do...while
开发语言·前端·javascript
To_OC3 小时前
啃完流式输出:从一个卡顿的 LLM 接口开始,我搞懂了数据流到底怎么 “流”
前端·javascript·llm
阳光是sunny3 小时前
LangGraph实战教程:defer延迟节点——让收尾工作自动排到最后
前端·人工智能·后端
kyriewen3 小时前
我用了三周Claude Code Skills——总结出5条铁律,第3条最反直觉
前端·ai编程·claude
阳光是sunny3 小时前
LangGraph实战教程:控制流详解
前端·人工智能·后端
Rex叶然4 小时前
ScreenMatch适配安卓屏幕脚本,用于老项目
android·screenmatch·安卓屏幕适配
阿pin4 小时前
Android随笔-Activity启动流程深度分析
android·activity启动流程
格尔曼Noah4 小时前
Safari浏览器中如何只允许指定网站下载
前端·safari
zzq77975 小时前
加固包闪退四象限定位:targetSdk 与保护策略实战解析
android·安全·安卓·安全架构