165 lines
4.8 KiB
Vue
165 lines
4.8 KiB
Vue
<template>
|
|
<div class="fullPage">
|
|
<div class="bg">
|
|
<div>
|
|
<!-- 顶部 -->
|
|
<MobileHeader title="Country&Region">
|
|
<!-- <template v-slot:extraFunction>
|
|
<div style="display: flex; justify-content: center; align-items: center; width: 10%">
|
|
<img src="../assets/icon/selected.png" alt="" style="width: 100%" @click="confirm" />
|
|
</div>
|
|
</template> -->
|
|
</MobileHeader>
|
|
</div>
|
|
|
|
<!-- 内容 -->
|
|
<div style="padding: 10px">
|
|
<div style="font-weight: 510; color: rgba(0, 0, 0, 0.4)">Select your country</div>
|
|
|
|
<div v-for="(countries, gIndex) in groupedCountries" :key="gIndex">
|
|
<div style="font-weight: 400; color: rgba(0, 0, 0, 0.4)">{{ countries.letter }}</div>
|
|
<div
|
|
style="
|
|
margin: 10px 0;
|
|
border-radius: 12px;
|
|
box-shadow: 0 0 4px 0 #00000050;
|
|
padding: 10px;
|
|
background-color: white;
|
|
"
|
|
>
|
|
<div
|
|
v-for="(country, cIndex) in countries.countries"
|
|
:key="cIndex"
|
|
style="
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin: 10px 0;
|
|
"
|
|
@click="selectC(gIndex, cIndex, country)"
|
|
>
|
|
<div style="display: flex; align-items: center">
|
|
<img
|
|
:src="country.country.nationalFlag"
|
|
alt=""
|
|
style="height: 16px; margin-right: 10px"
|
|
/>
|
|
{{ country.countryName }}
|
|
</div>
|
|
<div
|
|
style="
|
|
width: 16px;
|
|
height: 16px;
|
|
border: 1px solid rgba(0, 0, 0, 0.4);
|
|
border-radius: 50%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
"
|
|
>
|
|
<div
|
|
style="
|
|
width: 10px;
|
|
height: 10px;
|
|
border-radius: 50%;
|
|
background-color: rgba(187, 146, 255, 1);
|
|
"
|
|
v-if="groupIndex == gIndex && countryIndex == cIndex"
|
|
></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, ref } from 'vue'
|
|
import MobileHeader from '../components/MobileHeader.vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { useCountryStore } from '@/stores/country'
|
|
import { storeToRefs } from 'pinia'
|
|
|
|
const router = useRouter()
|
|
const countryStore = useCountryStore()
|
|
// const { list: countryList, selectedCountry } = storeToRefs(countryStore) //国家信息store双向绑定
|
|
const countryList = ref(countryStore.list)
|
|
const selectedCountry = ref(countryStore.selectedCountry)
|
|
|
|
const groupIndex = ref(-1) //选中的首字母区域
|
|
const countryIndex = ref(-1) //选中区域的第几个
|
|
|
|
// 选择国家
|
|
const selectC = (gIndex, cIndex, country) => {
|
|
groupIndex.value = gIndex
|
|
countryIndex.value = cIndex
|
|
selectedCountry.value = country
|
|
confirm()
|
|
}
|
|
|
|
// 初始化首字母分组
|
|
const groupedCountries = computed(() => {
|
|
const groups = {}
|
|
countryList.value.forEach((item) => {
|
|
let firstLetter = item.countryName.charAt(0)?.toUpperCase() || '#' //获取首字母转大写
|
|
const normalizedLetter = /[A-Z]/.test(firstLetter) ? firstLetter : '#' //处理特殊字符
|
|
|
|
if (!groups.hasOwnProperty(normalizedLetter)) {
|
|
groups[normalizedLetter] = []
|
|
}
|
|
groups[normalizedLetter].push(item)
|
|
})
|
|
|
|
let resCountryList = Object.keys(groups)
|
|
.sort()
|
|
.map((letter) => ({
|
|
letter,
|
|
countries: groups[letter].sort((a, b) => a.countryName.localeCompare(b.countryName)),
|
|
}))
|
|
|
|
let firstLetter = selectedCountry.value.countryName.charAt(0)?.toUpperCase() || '#' //当前选中的国家的首字母
|
|
resCountryList.forEach((resitem, gIndex) => {
|
|
if (resitem.letter == firstLetter) {
|
|
resitem.countries.forEach((citem, cIndex) => {
|
|
if (citem.countryName == selectedCountry.value.countryName) {
|
|
groupIndex.value = gIndex
|
|
countryIndex.value = cIndex
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
return resCountryList
|
|
})
|
|
|
|
// 右上角确认按钮
|
|
const confirm = () => {
|
|
console.log('点击确认按钮')
|
|
countryStore.setCountry(selectedCountry.value)
|
|
router.go(-1)
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
* {
|
|
color: black;
|
|
font-family: 'SF Pro';
|
|
}
|
|
|
|
.fullPage {
|
|
background-color: #ffffff;
|
|
min-height: 100vh;
|
|
position: relative;
|
|
}
|
|
|
|
.bg {
|
|
width: 100vw;
|
|
min-height: 100vh;
|
|
background-image: url(../assets/images/secondBg.png);
|
|
background-size: 100% auto;
|
|
background-repeat: no-repeat;
|
|
}
|
|
</style>
|