123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- <template>
- <view :style="{height: height + 'px'}" class="wk-area-picker picker">
- <view class="picker-header">
- <view class="cancel" @click="handleCancel">
- 取消
- </view>
- <view class="picker-header-title" />
- <view class="confirm" @click="handleConfirm">
- 确认
- </view>
- </view>
-
- <picker-view
- v-if="showPicker"
- v-model="valueIndexArr"
- indicator-class="indicator-active"
- class="picker-body"
- @change="bindChange">
- <picker-view-column class="picker-body-column">
- <view v-for="(item,index) in list1" :key="index" class="picker-item">
- {{ item.name }}
- </view>
- </picker-view-column>
- <picker-view-column v-if="precisions >= 2" class="picker-body-column">
- <view v-for="(item,index) in list2" :key="index" class="picker-item">
- {{ item.name }}
- </view>
- </picker-view-column>
- <picker-view-column v-if="precisions >= 3" class="picker-body-column">
- <view v-for="(item,index) in list3" :key="index" class="picker-item">
- {{ item.name }}
- </view>
- </picker-view-column>
- </picker-view>
- </view>
- </template>
- <script>
- import AREA_DATA from './districts.js'
- const EMPTY_TEXT = '请选择'
- export default {
- name: 'WkAreaPicker',
- inject: ['popup'],
- props: {
- value: {
- type: Array,
- default: () => []
- },
- precisions: {
- type: Number,
- default: 3 // 1 省 2 省市 3 省市区
- },
- requiredFull: {
- type: Boolean,
- default: true // 是否允许选择空
- }
- },
- data() {
- return {
- height: 0,
-
- list1: [], // 第一列数据
- list2: [], // 第二列数据
- list3: [], // 第三列数据
-
- valueArr: [],
- valueIndexArr: [0, 0, 0],
-
- showPicker: false
- }
- },
- watch: {
- value: {
- handler() {
- this.setDefaultValueIndex()
- },
- deep: true,
- immediate: true
- }
- },
- mounted() {
- const that = this
- uni.getSystemInfo({
- success: res => {
- that.height = res.windowHeight * 0.4
- }
- })
- },
- methods: {
- getDataList(list, code = null) {
- if (!code) return AREA_DATA
- const findRes = list.find(o => o.code === Number(code)) || {}
- return findRes.children || []
- },
-
- initCom() {
- // 省列表数据
- this.list1 = AREA_DATA
- if (!this.requiredFull) {
- const findRes = this.list1.find(o => o.name === EMPTY_TEXT)
- if (!findRes) {
- this.list1.unshift({ name: EMPTY_TEXT, code: '' })
- }
- }
- this.getCityList()
- this.showPicker = false
- this.$nextTick(() => {
- this.showPicker = true
- })
- },
-
- /**
- * 市列表数据
- */
- getCityList() {
- let num = this.valueIndexArr[0] || 0
- if (num > this.list1.length - 1) {
- num = 0
- }
- this.valueIndexArr[0] = num
- const data = this.list1[num]
- this.list2 = data.children || []
- if (!this.requiredFull) {
- const findRes = this.list2.find(o => o.name === EMPTY_TEXT)
- if (!findRes) {
- this.list2.unshift({ name: EMPTY_TEXT, code: '' })
- }
- }
- this.getAreaList()
- },
-
- /**
- * 区列表数据
- */
- getAreaList() {
- let num = this.valueIndexArr[1] || 0
- if (num > this.list2.length - 1) {
- num = 0
- }
- this.valueIndexArr[1] = num
- const data = this.list2[num]
- this.list3 = data.children || []
- if (!this.requiredFull) {
- const findRes = this.list3.find(o => o.name === EMPTY_TEXT)
- if (!findRes) {
- this.list3.unshift({ name: EMPTY_TEXT, code: '' })
- }
- }
- },
-
- /**
- * 设置默认值
- */
- setDefaultValueIndex() {
- if (this.$isEmpty(this.value)) {
- this.valueIndexArr = [0, 0, 0]
- this.initCom()
- return
- }
- let list = AREA_DATA
- let arr = []
- this.value.forEach((val, index) => {
- if (!this.requiredFull) {
- const findRes = list.find(o => o.name === EMPTY_TEXT)
- if (!findRes) {
- list.unshift({ name: EMPTY_TEXT, code: '' })
- }
- }
- let findIndex = list.findIndex(o => {
- if (typeof val === 'string') return o.name === val
- return o.code == Number(val.code)
- })
- if (findIndex < 0) {
- findIndex = 0
- }
- arr.push(findIndex)
- list = list[findIndex].children || []
- })
- this.valueIndexArr = arr
- this.initCom()
- },
- bindChange({ detail }) {
- detail.value.forEach((item, index) => {
- if (this.valueIndexArr[index] !== item) {
- this.valueIndexArr[index] = item
- this.$nextTick(function() {
- if (index === 0) {
- this.$set(this.valueIndexArr, 1, 0)
- this.$set(this.valueIndexArr, 2, 0)
- this.getCityList()
- } else if (index === 1) {
- this.$set(this.valueIndexArr, 2, 0)
- this.getAreaList()
- }
- })
- }
- })
- },
- handleCancel() {
- this.popup.close()
- },
- handleConfirm() {
- let value = []
- this.valueIndexArr.forEach((v, i) => {
- const item = this[`list${i + 1}`][v]
- value.push({
- code: item.code,
- name: item.name,
- id: i + 1
- })
- })
- value = value
- .slice(0, this.precisions)
- .filter(o => o.name !== EMPTY_TEXT)
-
- this.$emit('input', value)
- this.$emit('select', value, () => {
- this.popup.close()
- })
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .picker {
- width: 100%;
- background-color: white;
- display: flex;
- flex-direction: column;
- overflow: hidden;
-
- .picker-header {
- height: 70rpx;
- font-size: 26rpx;
- border-bottom: 1rpx solid $border-color;
- padding: 0 30rpx;
- @include left;
-
- .picker-header-title {
- flex: 1;
- }
- .cancel {
- color: #666666;
- }
- .confirm {
- color: $theme-color;
- }
- }
-
- .picker-body {
- flex: 1;
- padding: 0 30rpx;
- .picker-body-column {
- .picker-item {
- font-size: 26rpx;
- @include center;
- }
- }
- }
- }
- </style>
|