area.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. <template>
  2. <view>
  3. <view class="area">
  4. <view class="img" :style="{ backgroundPosition: items.position }"></view>
  5. <view class="area_text">{{ codeNum ? items.code : items?.country }}</view>
  6. </view>
  7. <Picker
  8. :data="arealist"
  9. ref="popupRef"
  10. v-model="internalCode"
  11. labelKey="country"
  12. valueKey="code"
  13. @confirm="confirm"
  14. >
  15. <template #pickerItem="{ item }">
  16. <view class="picker_item"> {{ item.country }} {{ item.code }} </view>
  17. </template>
  18. </Picker>
  19. </view>
  20. </template>
  21. <script setup>
  22. import Picker from "./picker";
  23. import { useSystemStore } from "@/store";
  24. import { ref, computed, watch } from "vue";
  25. const props = defineProps({
  26. modelValue: {
  27. type: [String, Number],
  28. default: null,
  29. },
  30. codeNum: Boolean,
  31. });
  32. const useSystem = useSystemStore();
  33. const popupRef = ref(null);
  34. const arealist = computed(() => useSystem.getCountryCodes);
  35. const internalCode = ref(props.modelValue);
  36. watch(
  37. () => props.modelValue,
  38. (newVal) => {
  39. internalCode.value = newVal;
  40. },
  41. { immediate: true }
  42. );
  43. watch(
  44. () => internalCode.value,
  45. (newVal) => {
  46. emit("update:modelValue", newVal);
  47. }
  48. );
  49. const emit = defineEmits(["update:modelValue", "confirm"]);
  50. const confirm = (data) => {
  51. emit("confirm", data);
  52. emit("update:modelValue", data.code);
  53. internalCode.value = data.code;
  54. };
  55. const open = () => {
  56. popupRef.value && popupRef.value.open();
  57. };
  58. const items = computed(() => {
  59. let areas = JSON.parse(JSON.stringify(arealist.value));
  60. if (!areas || !areas.length) {
  61. return {};
  62. }
  63. const list = areas.find((item) => item.code == props.modelValue);
  64. if (!props.modelValue) {
  65. const defaultItem = areas[0] || {};
  66. internalCode.value = defaultItem.code;
  67. emit("confirm", defaultItem);
  68. return defaultItem;
  69. }
  70. emit("confirm", list);
  71. return list || {};
  72. });
  73. defineExpose({
  74. open,
  75. });
  76. </script>
  77. <style lang="less" scoped>
  78. .area {
  79. display: flex;
  80. align-items: center;
  81. .img {
  82. background: url(@/static/login/country_img.png) no-repeat 0 0;
  83. -webkit-background-size: 24px 3876px;
  84. background-size: 24px 3876px;
  85. width: 24px;
  86. height: 16px;
  87. overflow: hidden;
  88. }
  89. .area_text {
  90. margin-left: 10rpx;
  91. color: var(--black);
  92. font-size: 28rpx;
  93. line-height: 16px;
  94. }
  95. }
  96. </style>