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>

打开文件选择框截图

相关推荐
前端之虎陈随易4 小时前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·vue.js·人工智能·typescript·node.js
一路向北he4 小时前
字节钢铁军团--“提供情境,而非控制”
java·开发语言·前端
kyriewen4 小时前
豆包和千问同时关了智能体,我用它们搭的 3 个自动化全废了——迁移方案整理
前端·javascript·ai编程
前端一小卒5 小时前
我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行
前端·agent
GitLqr5 小时前
Flutter 3.44 插件内置 Kotlin (KGP) 双向兼容适配指南
android·flutter·dart
大圣编程6 小时前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang6 小时前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
之歆7 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜8 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
负责的蛋挞9 小时前
异步HttpModule的实现方式
java·服务器·前端