|
|
- <template>
- <view class="input-image-container">
- <view class="upload-area" v-if="showUploadBtn">
- <view class="upload-btn" @click="chooseImage">
- <view v-if="showPlaceholder" class="placeholder-area" :style="{ height: placeholderHeight }">
- <!-- 占位区域 -->
- </view>
- <view class="upload-icon">
- <image style="width:110rpx;height:110rpx" src="/static/re/ico.png" />
- </view>
- <view v-if="hasImage" class="image-preview" :style="{ height: imageHeight }">
- <image
- :style="{ height: imageDisplayHeight }"
- :src="imageUrl"
- mode="scaleToFill"
- class="preview-image"
- />
- </view>
- </view>
- </view>
-
- <!-- 显示已上传的图片 -->
- <view v-if="showImageOnly" class="image-display" :style="{ height: 'auto' }">
- <image
- :style="{ height: 'auto' }"
- :src="displayImageUrl"
- mode="widthFix"
- class="display-image"
- />
- </view>
-
- <!-- 多图上传模式 -->
- <view v-if="multiple" class="multiple-upload">
- <uv-upload
- :fileList="fileList"
- :multiple="true"
- :maxCount="maxCount"
- :width="uploadWidth"
- :height="uploadHeight"
- @afterRead="afterRead"
- @delete="deleteImage"
- >
- <image
- src="/static/re/ico.png"
- mode="aspectFill"
- :style="{ width: uploadWidth, height: uploadHeight }"
- />
- </uv-upload>
- </view>
- </view>
- </template>
-
- <script>
- export default {
- name: 'InputImage',
- props: {
- // 是否显示上传按钮
- showUploadBtn: {
- type: Boolean,
- default: true
- },
- // 是否显示占位区域
- showPlaceholder: {
- type: Boolean,
- default: false
- },
- // 占位区域高度
- placeholderHeight: {
- type: String,
- default: '200rpx'
- },
- // 是否有图片
- hasImage: {
- type: Boolean,
- default: false
- },
- // 图片URL
- imageUrl: {
- type: String,
- default: ''
- },
- // 图片高度
- imageHeight: {
- type: String,
- default: '300rpx'
- },
- // 图片显示高度
- imageDisplayHeight: {
- type: String,
- default: '300rpx'
- },
- // 只显示图片模式
- showImageOnly: {
- type: Boolean,
- default: false
- },
- // 显示的图片URL
- displayImageUrl: {
- type: String,
- default: ''
- },
- // 是否多图上传
- multiple: {
- type: Boolean,
- default: false
- },
- // 最大上传数量
- maxCount: {
- type: Number,
- default: 3
- },
- // 上传区域宽度
- uploadWidth: {
- type: String,
- default: '180rpx'
- },
- // 上传区域高度
- uploadHeight: {
- type: String,
- default: '180rpx'
- },
- // 文件列表
- fileList: {
- type: Array,
- default: () => []
- }
- },
- data() {
- return {
- internalFileList: []
- }
- },
- mounted() {
- this.internalFileList = [...this.fileList];
- },
- watch: {
- fileList: {
- handler(newVal) {
- this.internalFileList = [...newVal];
- },
- deep: true
- }
- },
- methods: {
- // 选择图片
- chooseImage() {
- uni.chooseImage({
- count: 1,
- sizeType: ['compressed'],
- sourceType: ['album', 'camera'],
- success: (res) => {
- const tempFilePath = res.tempFilePaths[0];
- this.$emit('imageSelected', tempFilePath);
-
- // 模拟上传到OSS
- this.uploadToOss(tempFilePath);
- },
- fail: (err) => {
- console.error('选择图片失败:', err);
- uni.showToast({
- title: '选择图片失败',
- icon: 'none'
- });
- }
- });
- },
-
- // 模拟上传到OSS
- uploadToOss(filePath) {
- uni.showLoading({
- title: '上传中...'
- });
-
- // 模拟上传过程
- setTimeout(() => {
- uni.hideLoading();
-
- // 模拟生成OSS URL
- const mockOssUrl = `https://relief.oss-cn-hangzhou.aliyuncs.com/mock_${Date.now()}.jpg`;
-
- this.$emit('uploadSuccess', {
- localPath: filePath,
- ossUrl: mockOssUrl
- });
-
- uni.showToast({
- title: '上传成功',
- icon: 'success'
- });
- }, 1000); // 模拟1秒上传时间
- },
-
- // 多图上传后处理
- afterRead(e) {
- const files = Array.isArray(e.file) ? e.file : [e.file];
-
- files.forEach(file => {
- this.uploadToOssMultiple(file.url);
- });
- },
-
- // 模拟多图上传到OSS
- uploadToOssMultiple(filePath) {
- // 模拟上传过程
- setTimeout(() => {
- // 模拟生成OSS URL
- const mockOssUrl = `https://relief.oss-cn-hangzhou.aliyuncs.com/mock_${Date.now()}.jpg`;
-
- this.internalFileList.push({
- url: mockOssUrl
- });
-
- this.$emit('update:fileList', this.internalFileList);
- this.$emit('multipleUploadSuccess', this.internalFileList);
- }, 500); // 模拟0.5秒上传时间
- },
-
- // 删除图片
- deleteImage(e) {
- this.internalFileList.splice(e.index, 1);
- this.$emit('update:fileList', this.internalFileList);
- this.$emit('imageDeleted', e.index);
- }
- }
- }
- </script>
-
- <style scoped lang="scss">
- .input-image-container {
- position: relative;
- }
-
- .upload-area {
- position: relative;
- }
-
- .upload-btn {
- position: relative;
- border: 2rpx dashed #ddd;
- border-radius: 10rpx;
- padding: 20rpx;
- text-align: center;
- background-color: #fafafa;
- transition: all 0.3s;
-
- &:active {
- background-color: #f0f0f0;
- }
- }
-
- .placeholder-area {
- width: 100%;
- background-color: #f5f5f5;
- border-radius: 8rpx;
- margin-bottom: 20rpx;
- }
-
- .upload-icon {
- margin-bottom: 20rpx;
- }
-
- .image-preview {
- width: 100%;
- border-radius: 8rpx;
- overflow: hidden;
-
- .preview-image {
- width: 100%;
- border-radius: 8rpx;
- }
- }
-
- .image-display {
- width: 100%;
- border-radius: 8rpx;
- overflow: hidden;
-
- .display-image {
- width: 100%;
- border-radius: 8rpx;
- }
- }
-
- .multiple-upload {
- padding: 20rpx;
- background-color: #fff;
- border-radius: 10rpx;
- }
- </style>
|