57 lines
3.5 KiB
Vue
57 lines
3.5 KiB
Vue
<template>
|
|
<view v-if="visible" class="mask" @tap="close">
|
|
<view class="sheet" @tap.stop>
|
|
<view class="sheet-header">
|
|
<text class="sheet-title">选择目的地</text>
|
|
<text class="sheet-close" @tap="close">关闭</text>
|
|
</view>
|
|
<view class="city-path">{{ pathLabel || '请选择目的地' }}</view>
|
|
<picker-view class="wheel" :value="pickerValue" @change="onChange">
|
|
<picker-view-column>
|
|
<view v-for="item in continents" :key="item.name" class="wheel-item"><text>{{ item.name }}</text></view>
|
|
</picker-view-column>
|
|
<picker-view-column>
|
|
<view v-for="item in countries" :key="item.name" class="wheel-item"><text>{{ item.name }}</text></view>
|
|
</picker-view-column>
|
|
<picker-view-column>
|
|
<view v-for="item in cities" :key="item" class="wheel-item"><text>{{ item }}</text></view>
|
|
</picker-view-column>
|
|
</picker-view>
|
|
<view class="footer">
|
|
<button class="btn ghost" @tap="close">取消</button>
|
|
<button class="btn primary" @tap="confirm">确定</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
const CITY_DATA = [
|
|
{ name: '亚洲', countries: [{ name: '中国', cities: ['北京', '上海', '广州', '深圳', '杭州', '成都'] }, { name: '日本', cities: ['东京', '大阪', '京都'] }, { name: '韩国', cities: ['首尔', '釜山'] }, { name: '新加坡', cities: ['新加坡'] }] },
|
|
{ name: '欧洲', countries: [{ name: '英国', cities: ['伦敦', '曼彻斯特'] }, { name: '法国', cities: ['巴黎', '里昂'] }, { name: '德国', cities: ['柏林', '慕尼黑'] }] },
|
|
{ name: '北美洲', countries: [{ name: '美国', cities: ['纽约', '洛杉矶', '旧金山'] }, { name: '加拿大', cities: ['多伦多', '温哥华'] }] },
|
|
{ name: '大洋洲', countries: [{ name: '澳大利亚', cities: ['悉尼', '墨尔本'] }, { name: '新西兰', cities: ['奥克兰', '惠灵顿'] }] }
|
|
]
|
|
export default {
|
|
props: { visible: Boolean, value: String },
|
|
emits: ['update:visible', 'change'],
|
|
data() { return { pickerValue: [0, 0, 0], cityData: CITY_DATA } },
|
|
computed: {
|
|
continents() { return this.cityData },
|
|
countries() { return this.continents[this.pickerValue[0]]?.countries || [] },
|
|
cities() { return this.countries[this.pickerValue[1]]?.cities || [] },
|
|
pathLabel() { const a = this.continents[this.pickerValue[0]]?.name || ''; const b = this.countries[this.pickerValue[1]]?.name || ''; const c = this.cities[this.pickerValue[2]] || ''; return [a,b,c].filter(Boolean).join(' / ') }
|
|
},
|
|
watch: { visible(v) { if (v) this.initValue() } },
|
|
methods: {
|
|
initValue() { this.pickerValue = [0,0,0] },
|
|
onChange(e) { this.pickerValue = (e.detail.value || []).map(v => Number(v)) },
|
|
confirm() { this.$emit('change', this.pathLabel); this.close() },
|
|
close() { this.$emit('update:visible', false) }
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.mask{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:1000;display:flex;align-items:flex-end}.sheet{width:100%;background:#fff;border-radius:24rpx 24rpx 0 0;padding:20rpx;box-sizing:border-box}.sheet-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16rpx}.sheet-title{font-size:30rpx;font-weight:800}.sheet-close{font-size:26rpx;color:#1677ff}.city-path{padding:12rpx 16rpx;margin-bottom:12rpx;border-radius:16rpx;background:#f8fafc;color:#334155;font-size:24rpx}.wheel{height:520rpx}.wheel-item{display:flex;align-items:center;justify-content:center;height:88rpx}.footer{display:flex;gap:12rpx;margin-top:16rpx}.btn{flex:1;border-radius:16rpx}.btn.ghost{background:#f3f4f6;color:#334155}.btn.primary{background:#1677ff;color:#fff}
|
|
</style> |