Taro简介
Taro是一个开放式跨端跨框架解决方案,支持使用React/Vue/Nerv等框架来开发 微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ / 飞书 / 快手 小程序/ H5 / RN等应用。
项目是Taro + vue3 + ts, 这两天在玩Taro,就遇到一个问题,想实现H5跟小程序都能调用本地图片,但他们调用的方法都不一样!
H5上传本地图片
<input type="file" accept="image/*" style="display: none;" @change="handleFileChange" id="fileInput" />
小程序上传图片
<template>
<view class="photograph flex align-center justify-center" @tap="photographClick" v-if="!isWeb">
<view class="photograph-icon">
<image src="../../assets/icon/camera.png" mode=""></image>
</view>
拍照识图
</view>
</template>
<script lang="ts" setup>
import Taro from '@tarojs/taro'
const photographClick = () => {
Taro.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePaths = res.tempFilePaths
console.log('选择的图片路径:', tempFilePaths)
// 在这里处理选择的图片
}
})
}
</script>
咱们要H5跟小程序都可以使用,就得先判断用户访问的是web端还是小程序,调用Taro.getEnv()
方法!
<script lang="ts" setup>
import { ref, onMounted, nextTick } from 'vue'
import Taro from '@tarojs/taro'
const env = ref('')
const isWeb = ref(false)
onMounted(() => {
env.value = Taro.getEnv()
isWeb.value = env.value === Taro.ENV_TYPE.WEB // 判断用户进来是web端的话,切换显示上传视图
})
</script>
如果你跟我一样,不想显示input type="file"
的原生样式,就可以加个样式style="display: none;"
<template>
<view class="flex flex-wrap">
<view class="photograph flex align-center justify-center" @tap="photographClick" v-if="!isWeb">
<view class="photograph-icon">
<image src="../../assets/icon/camera.png" mode=""></image>
</view>
拍照识图
</view>
<view class="photograph flex align-center justify-center" @click="triggerFileInput" v-else>
<view class="photograph-icon">
<image src="../../assets/icon/camera.png" mode=""></image>
</view>
拍照识图
<input type="file" accept="image/*" style="display: none;" @change="handleFileChange" id="fileInput" />
</view>
</view>
</template>
这时候开始我们就要点击外层triggerFileInput
方法,触发模拟点击handleFileChange
方法,这里面也是一堆坑的时候!
<script lang="ts" setup>
// 使用了很多种方法去获取input type="file"元素,用ref去绑定实例,inputElement.click()还是会没有反应,用DOM元素,绑定click事件就可以,但记得加一个判断,判断用户只能每次点击一次,不然我发现inputElement.click()会一直重复执行,也是奇怪
const triggerFileInput = () => {
if (inputClicked.value) return // 如果已经点击过,直接返回
inputClicked.value = true // 标记已经点击过
nextTick(() => {
let inputElement = document.querySelector('input[type="file"]') // 只适用当前页面只有一个input type="file"元素
if (inputElement) {
inputElement.click()
inputClicked.value = false
} else {
console.error("找不到 <input type='file'>");
}
});
};
// handleFileChange方法,上传单张图片,查ChatGPT的时候,发现老让我用event.target.files,结果根本打印不出值!
const handleFileChange = (event) => {
const files = event.target.firstChild.files[0]
console.log('files', files);
if (files) {
if (!files.type.startsWith("image/")) {
alert("只能上传图片文件!");
return;
}
} else {
console.log('files无值', files);
}
}
</script>
图片需要预览的话,可以转成base64
方法,后续有问题在修改!