2
This commit is contained in:
@@ -15,11 +15,11 @@
|
||||
@change="onMoving(index, $event)"
|
||||
@touchend="onMoveEnd(index)"
|
||||
>
|
||||
<image :src="img.url" mode="aspectFill" class="thumb" @click="preview(index)" />
|
||||
<view class="remove" @click.stop="remove(index)">×</view>
|
||||
<image :src="img.url" mode="aspectFill" class="thumb" @click="preview(index)" />
|
||||
<image class="remove" src="/static/icons/icons8-close-48.png" mode="aspectFit" @click.stop="remove(index)" />
|
||||
</movable-view>
|
||||
|
||||
<view v-if="innerList.length < max" class="adder" @click="choose">
|
||||
<view v-if="innerList.length < max" class="adder" :style="adderStyle" @click="choose">
|
||||
<text>+</text>
|
||||
</view>
|
||||
</movable-area>
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
<script>
|
||||
import { upload } from '../common/http.js'
|
||||
import { API_BASE_URL } from '../common/config.js'
|
||||
|
||||
const ITEM_SIZE = 210 // rpx
|
||||
const GAP = 18 // rpx
|
||||
@@ -57,6 +58,14 @@ export default {
|
||||
areaHeight() {
|
||||
const rows = Math.ceil((this.innerList.length + 1) / COLS) || 1
|
||||
return rows * ITEM_SIZE + (rows - 1) * GAP
|
||||
},
|
||||
adderStyle() {
|
||||
const index = this.innerList.length
|
||||
const row = Math.floor(index / COLS)
|
||||
const col = index % COLS
|
||||
const x = px(col * (ITEM_SIZE + GAP))
|
||||
const y = px(row * (ITEM_SIZE + GAP))
|
||||
return { left: x + 'rpx', top: y + 'rpx' }
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -65,7 +74,7 @@ export default {
|
||||
handler(list) {
|
||||
const mapped = (list || []).map((u, i) => ({
|
||||
uid: String(i) + '_' + (u.id || u.url || Math.random().toString(36).slice(2)),
|
||||
url: typeof u === 'string' ? u : (u.url || ''),
|
||||
url: this.ensureAbsoluteUrl(typeof u === 'string' ? u : (u.url || '')),
|
||||
x: this.posOf(i).x,
|
||||
y: this.posOf(i).y
|
||||
}))
|
||||
@@ -74,6 +83,12 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
ensureAbsoluteUrl(u) {
|
||||
if (!u) return ''
|
||||
const s = String(u)
|
||||
if (s.startsWith('http://') || s.startsWith('https://')) return s
|
||||
return API_BASE_URL + (s.startsWith('/') ? s : '/' + s)
|
||||
},
|
||||
posOf(index) {
|
||||
const row = Math.floor(index / COLS)
|
||||
const col = index % COLS
|
||||
@@ -105,7 +120,7 @@ export default {
|
||||
async doUpload(filePath) {
|
||||
try {
|
||||
const resp = await upload(this.uploadPath, filePath, this.formData, this.uploadFieldName)
|
||||
const url = resp?.url || resp?.data?.url || resp?.path || ''
|
||||
const url = this.ensureAbsoluteUrl(resp?.url || resp?.data?.url || resp?.path || '')
|
||||
if (!url) throw new Error('上传响应无 url')
|
||||
this.innerList.push({ uid: Math.random().toString(36).slice(2), url, ...this.posOf(this.innerList.length) })
|
||||
this.reflow()
|
||||
@@ -155,7 +170,7 @@ export default {
|
||||
.area { width: 100%; position: relative; }
|
||||
.cell { position: absolute; border-radius: 12rpx; overflow: hidden; box-shadow: 0 0 1rpx rgba(0,0,0,0.08); }
|
||||
.thumb { width: 100%; height: 100%; }
|
||||
.remove { position: absolute; right: 6rpx; top: 6rpx; background: rgba(0,0,0,0.45); color: #fff; width: 40rpx; height: 40rpx; text-align: center; line-height: 40rpx; border-radius: 20rpx; font-size: 28rpx; }
|
||||
.remove { position: absolute; right: 6rpx; top: 6rpx; width: 42rpx; height: 42rpx; }
|
||||
.adder { width: 210rpx; height: 210rpx; border: 2rpx dashed #ccc; border-radius: 12rpx; display: flex; align-items: center; justify-content: center; color: #999; position: absolute; left: 0; top: 0; }
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user