From c54025ce839be2daf2eaecfff56492b45958d0c2 Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Tue, 25 Aug 2020 19:50:59 +0800 Subject: [PATCH] refactor(Area): refactor with composition api --- src/area/index.js | 329 ++++++++++++++++++++++------------------------ 1 file changed, 159 insertions(+), 170 deletions(-) diff --git a/src/area/index.js b/src/area/index.js index bcd28468d..a6bb4c978 100644 --- a/src/area/index.js +++ b/src/area/index.js @@ -1,15 +1,20 @@ -import { createNamespace } from '../utils'; +import { ref, watch, computed, reactive, nextTick, onMounted } from 'vue'; +import { createNamespace, pick } from '../utils'; import { pickerProps } from '../picker/shared'; import Picker from '../picker'; const [createComponent, bem] = createNamespace('area'); -const PLACEHOLDER_CODE = '000000'; +const EMPTY_CODE = '000000'; function isOverseaCode(code) { return code[0] === '9'; } +function clone(obj) { + return JSON.parse(JSON.stringify(obj)); +} + export default createComponent({ props: { ...pickerProps, @@ -34,79 +39,60 @@ export default createComponent({ emits: ['change', 'confirm'], - data() { - return { - code: this.value, - columns: [{ values: [] }, { values: [] }, { values: [] }], - }; - }, + setup(props, { emit, slots }) { + const pickerRef = ref(null); - computed: { - province() { - return this.areaList.province_list || {}; - }, + const state = reactive({ + code: ref(props.value), + columns: reactive([{ values: [] }, { values: [] }, { values: [] }]), + }); - city() { - return this.areaList.city_list || {}; - }, - - county() { - return this.areaList.county_list || {}; - }, - - displayColumns() { - return this.columns.slice(0, +this.columnsNum); - }, - - placeholderMap() { + const areaList = computed(() => { + const { areaList } = props; return { - province: this.columnsPlaceholder[0] || '', - city: this.columnsPlaceholder[1] || '', - county: this.columnsPlaceholder[2] || '', + province: areaList.province_list || {}, + city: areaList.city_list || {}, + county: areaList.county_list || {}, }; - }, + }); - pickerSlots() { - return ['title', 'columns-top', 'columns-bottom'].reduce((slots, key) => { - slots[key] = this.$slots[key]; - return slots; - }, {}); - }, - }, + const placeholderMap = computed(() => { + const { columnsPlaceholder } = props; + return { + province: columnsPlaceholder[0] || '', + city: columnsPlaceholder[1] || '', + county: columnsPlaceholder[2] || '', + }; + }); - watch: { - value(val) { - this.code = val; - this.setValues(); - }, + const getDefaultCode = () => { + if (props.columnsPlaceholder.length) { + return EMPTY_CODE; + } - areaList: { - deep: true, - handler() { - this.setValues(); - }, - }, + const { county, city } = areaList.value; - columnsNum() { - this.$nextTick(() => { - this.setValues(); - }); - }, - }, + const countyCodes = Object.keys(county); + if (countyCodes[0]) { + return countyCodes[0]; + } - mounted() { - this.setValues(); - }, + const cityCodes = Object.keys(city); + if (cityCodes[0]) { + return cityCodes[0]; + } + + return ''; + }; - methods: { // get list by code - getList(type, code) { + const getList = (type, code) => { let result = []; if (type !== 'province' && !code) { return result; } - const list = this[type]; + const list = areaList.value[type]; result = Object.keys(list).map((listCode) => ({ code: listCode, name: list[listCode], @@ -114,38 +100,37 @@ export default createComponent({ if (code) { // oversea code - if (this.isOverseaCode(code) && type === 'city') { + if (type === 'city' && props.isOverseaCode(code)) { code = '9'; } - result = result.filter((item) => item.code.indexOf(code) === 0); } - if (this.placeholderMap[type] && result.length) { + if (placeholderMap.value[type] && result.length) { // set columns placeholder let codeFill = ''; if (type === 'city') { - codeFill = PLACEHOLDER_CODE.slice(2, 4); + codeFill = EMPTY_CODE.slice(2, 4); } else if (type === 'county') { - codeFill = PLACEHOLDER_CODE.slice(4, 6); + codeFill = EMPTY_CODE.slice(4, 6); } result.unshift({ - code: `${code}${codeFill}`, - name: this.placeholderMap[type], + code: code + codeFill, + name: placeholderMap.value[type], }); } return result; - }, + }; // get index by code - getIndex(type, code) { + const getIndex = (type, code) => { let compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6; - const list = this.getList(type, code.slice(0, compareNum - 2)); + const list = getList(type, code.slice(0, compareNum - 2)); // oversea code - if (this.isOverseaCode(code) && type === 'province') { + if (props.isOverseaCode(code) && type === 'province') { compareNum = 1; } @@ -158,68 +143,17 @@ export default createComponent({ } return 0; - }, - - // parse output columns data - parseOutputValues(values) { - return values.map((value, index) => { - // save undefined value - if (!value) return value; - - value = JSON.parse(JSON.stringify(value)); - - if (!value.code || value.name === this.columnsPlaceholder[index]) { - value.code = ''; - value.name = ''; - } - - return value; - }); - }, - - onChange(values, index) { - const { picker } = this.$refs; - this.code = values[index].code; - this.setValues(); - - const parsedValues = this.parseOutputValues(picker.getValues()); - this.$emit('change', parsedValues, index); - }, - - onConfirm(values, index) { - values = this.parseOutputValues(values); - this.setValues(); - this.$emit('confirm', values, index); - }, - - getDefaultCode() { - if (this.columnsPlaceholder.length) { - return PLACEHOLDER_CODE; - } - - const countyCodes = Object.keys(this.county); - if (countyCodes[0]) { - return countyCodes[0]; - } - - const cityCodes = Object.keys(this.city); - if (cityCodes[0]) { - return cityCodes[0]; - } - - return ''; - }, - - setValues() { - let { code } = this; + }; + const setValues = () => { + let { code } = state; if (!code) { - code = this.getDefaultCode(); + code = getDefaultCode(); } - const { picker } = this.$refs; - const province = this.getList('province'); - const city = this.getList('city', code.slice(0, 2)); + const picker = pickerRef.value; + const province = getList('province'); + const city = getList('city', code.slice(0, 2)); if (!picker) { return; @@ -231,30 +165,45 @@ export default createComponent({ if ( city.length && code.slice(2, 4) === '00' && - !this.isOverseaCode(code) + !props.isOverseaCode(code) ) { [{ code }] = city; } - picker.setColumnValues(2, this.getList('county', code.slice(0, 4))); + picker.setColumnValues(2, getList('county', code.slice(0, 4))); picker.setIndexes([ - this.getIndex('province', code), - this.getIndex('city', code), - this.getIndex('county', code), + getIndex('province', code), + getIndex('city', code), + getIndex('county', code), ]); - }, + }; - getValues() { - const { picker } = this.$refs; - let getValues = picker - ? picker.getValues().filter((value) => !!value) - : []; - getValues = this.parseOutputValues(getValues); - return getValues; - }, + // parse output columns data + const parseValues = (values) => { + return values.map((value, index) => { + if (value) { + value = clone(value); - getArea() { - const values = this.getValues(); + if (!value.code || value.name === props.columnsPlaceholder[index]) { + value.code = ''; + value.name = ''; + } + } + + return value; + }); + }; + + const getValues = () => { + if (pickerRef.value) { + const values = pickerRef.value.getValues().filter((value) => !!value); + return parseValues(values); + } + return []; + }; + + const getArea = () => { + const values = getValues(); const area = { code: '', country: '', @@ -274,7 +223,7 @@ export default createComponent({ ? validValues[validValues.length - 1].code : ''; - if (this.isOverseaCode(area.code)) { + if (props.isOverseaCode(area.code)) { area.country = names[1] || ''; area.province = names[2] || ''; } else { @@ -284,33 +233,73 @@ export default createComponent({ } return area; - }, + }; - // @exposed-api - reset(code) { - this.code = code || ''; - this.setValues(); - }, - }, + const reset = (newCode = '') => { + state.code = newCode; + setValues(); + }; - render() { - return ( - + const onChange = (values, index) => { + state.code = values[index].code; + setValues(); + + const parsedValues = parseValues(pickerRef.value.getValues()); + emit('change', parsedValues, index); + }; + + const onConfirm = (values, index) => { + values = parseValues(values); + setValues(); + emit('confirm', values, index); + }; + + onMounted(setValues); + + watch( + () => props.value, + (value) => { + state.code = value; + setValues(); + } ); + + watch(() => props.areaList, setValues, { deep: true }); + + watch( + () => props.columnsNum, + () => { + nextTick(setValues); + } + ); + + return (vm) => { + // @exposed-api + vm.reset = reset; + vm.getArea = getArea; + + const columns = state.columns.slice(0, +props.columnsNum); + + return ( + + ); + }; }, });