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 (
+
+ );
+ };
},
});