| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- <template>
- <view class="container">
- <view v-if="isLoading" class="loading">
- <u-loading mode="circle"></u-loading>
- </view>
- <view v-else class="field-body" @click="handleSelect()">
- <view class="field-value oneline-hide">{{ valueText ? valueText : placeholder }}</view>
- </view>
- <u-select v-model="show" mode="mutil-column-auto" :list="options" :default-value="defaultValue" @confirm="onConfirm"></u-select>
- </view>
- </template>
- <script>
- import Emitter from '@/uni_modules/vk-uview-ui/libs/util/emitter'
- import {isEmpty} from '@/utils/util'
- import RegionModel from '@/common/model/Region'
- // 根据选中的value集获取索引集keys
- // 用于设置默认选中
- const findOptionsKey = (data, searchValue, deep = 1, keys = []) => {
- const index = data.findIndex((item) => item.value === searchValue[deep - 1])
- if (index > -1) {
- keys.push(index)
- if (data[index].children) {
- findOptionsKey(data[index].children, searchValue, ++deep, keys)
- }
- }
- return keys
- }
- export default {
- name: 'SelectRegion',
- mixins: [Emitter],
- emits: ['update:modelValue'],
- props: {
- // 当前选中的值
- modelValue: {
- type: Array,
- default: () => {
- return []
- }
- },
- // 未选中时的提示文字
- placeholder: {
- type: String,
- default: '请选择省/市/区'
- }
- },
- data() {
- return {
- // 正在加载
- isLoading: true,
- // 是否显示
- show: false,
- // 默认选中的值
- defaultValue: [],
- // 选中项内容(文本展示)
- valueText: '',
- // 级联选择器数据
- options: []
- }
- },
- watch: {
- // 监听当前选中的值
- modelValue(val) {
- // 设置默认选中的值
- this.valueText = val.map((item) => item.label).join('/')
- this.setDefaultValue(val)
- // 将当前的值发送到 u-form-item 进行校验
- // this.dispatch('u-form-item', 'on-form-change', val)
- }
- },
- created() {
- // 获取地区数据 (同步)
- this.getTreeDataSync()
- },
- methods: {
- // 打开选择器
- handleSelect() {
- this.show = true
- },
- // // 获取地区数据 (异步)
- // getTreeData() {
- // const app = this
- // app.isLoading = true
- // RegionModel.getTreeData()
- // .then(regions => {
- // // 格式化级联选择器数据
- // app.options = app.getOptions(regions)
- // app.setDefaultValue(app.modelValue)
- // })
- // .finally(() => app.isLoading = false)
- // },
- // 获取地区数据 (同步)
- getTreeDataSync() {
- const app = this
- const regions = RegionModel.getTreeDataSync()
- app.options = app.getOptions(regions)
- app.setDefaultValue(app.modelValue)
- app.isLoading = false
- },
- // 确认选择后的回调
- onConfirm(value) {
- // 记录选中的值
- this.$emit('update:modelValue', value)
- },
- /**
- * 设置默认选中的值
- * 该操作是为了每次打开选择器时聚焦到上次选择
- * @param {Object} value
- */
- setDefaultValue(value) {
- console.log(value, 'value')
- if (value) {
- const options = this.options
- const values = value.map((item) => item.value)
- this.defaultValue = options.length ? findOptionsKey(options, values) : []
- }
- },
- /**
- * 格式化级联选择器数据
- * @param {*} regions 地区数据
- */
- getOptions(regions) {
- const {getOptions, getChildren} = this
- const options = []
- for (const index in regions) {
- const item = regions[index]
- const children = getChildren(item)
- const optionItem = {
- value: item.id,
- label: item.name
- }
- if (children !== false) {
- optionItem.children = getOptions(children)
- }
- options.push(optionItem)
- }
- return options
- },
- // 获取子集地区
- getChildren(item) {
- if (item.city) {
- return item.city
- }
- if (item.region) {
- return item.region
- }
- return false
- },
- // 根据省市区名称获取optionItem
- getOptionItemByNames({provinceName, cityName, countyName}) {
- const app = this
- const data = []
- app.options.forEach((provinceItem) => {
- if (provinceItem.label == provinceName || `${provinceItem.label}市` == provinceName) {
- data.push({label: provinceItem.label, value: provinceItem.value})
- provinceItem.children.forEach((cityItem) => {
- if (cityItem.label == cityName) {
- data.push({label: cityItem.label, value: cityItem.value})
- cityItem.children.forEach((countyItem) => {
- if (countyItem.label == countyName) {
- data.push({label: countyItem.label, value: countyItem.value})
- }
- })
- }
- })
- }
- })
- return data
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .container {
- width: 100%;
- }
- .loading {
- padding-left: 10rpx;
- // text-align: center;
- }
- </style>
|