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>

打开文件选择框截图

相关推荐
程序员黑豆6 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC7 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea7 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
浮生望7 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少8 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波0078 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis9 小时前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝10 小时前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps
计算机魔术师10 小时前
新兴多智能体系统的模式与问题
前端
用户0595401744611 小时前
AI Agent 上下文污染踩坑实录:用 pytest + Redis 揪出 3 类记忆串号 bug,排查 6 小时
前端·css