| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| --> |
| <!-- Created by Tw93 on 17/12/27. --> |
| <!--A City --> |
| |
| <template> |
| <div class="wxc-city" ref="city" :style="cityExtendStyle"> |
| <wxc-searchbar ref="wxc-searchbar" |
| v-bind="mergeInputConfig" |
| @wxcSearchbarInputOnInput="onInput" |
| @wxcSearchbarInputReturned="onSubmit" |
| @wxcSearchbarCancelClicked="onCancel"></wxc-searchbar> |
| |
| <wxc-tab ref="wxc-tab" |
| v-if="showTab" |
| @wxcTabSwitch="onTabSwitch"></wxc-tab> |
| |
| <wxc-indexlist :normal-list="normalList" |
| :hot-list-config="hotListConfig" |
| :nav-style="{ top: '24px'}" |
| :height="listHeight" |
| :show-index="showIndex" |
| :only-show-list="!showNavHeader || onlyShowList" |
| :city-location-config="currentCityLocationConfig" |
| @wxcIndexlistItemClicked="onItemClick"></wxc-indexlist> |
| |
| <wxc-result type="noGoods" |
| :wrap-style="{top:'84px'}" |
| :show="true" |
| :customSet="result" |
| v-if="showError"></wxc-result> |
| </div> |
| </template> |
| |
| <script> |
| import defaultSourceData from './default-data'; |
| import * as Util from './util'; |
| import Utils from '../utils'; |
| import wxcTab from './tab.vue'; |
| import WxcSearchbar from '../wxc-searchbar' |
| import WxcResult from '../wxc-result'; |
| import WxcIndexlist from '../wxc-indexlist'; |
| |
| export default { |
| components: { wxcTab, WxcSearchbar, WxcResult, WxcIndexlist }, |
| props: { |
| animationType: { |
| type: String, |
| default: 'push' |
| }, |
| inputConfig: { |
| type: Object, |
| default: () => ({}) |
| }, |
| sourceData: { |
| type: Object, |
| default: () => defaultSourceData |
| }, |
| cityStyleType: { |
| type: String, |
| default: 'list' |
| }, |
| currentLocation: String, |
| cityHeight: { |
| type: Number, |
| default: 0 |
| }, |
| showTab: { |
| type: Boolean, |
| default: false |
| }, |
| showIndex: { |
| type: Boolean, |
| default: true |
| }, |
| showNavHeader: { |
| type: Boolean, |
| default: true |
| } |
| }, |
| data: () => ({ |
| tId: null, |
| saveDefaultSourceData: {}, |
| cityData: {}, |
| onlyShowList: false, |
| result: { |
| noGoods: { |
| pic: 'https://img.alicdn.com/tfs/TB1SpPHkf2H8KJjy0FcXXaDlFXa-200-200.png', |
| button: '', |
| content: '搜索无结果' |
| } |
| } |
| }), |
| created () { |
| this.cityData = this.sourceData |
| this.saveDefaultSourceData = this.sourceData |
| }, |
| computed: { |
| cityExtendStyle () { |
| return Utils.uiStyle.pageTransitionAnimationStyle(this.animationType) |
| }, |
| currentCityLocationConfig () { |
| if (this.currentLocation) { |
| return { |
| type: this.cityStyleType, |
| title: '定位', |
| list: [ |
| { name: this.currentLocation, isLocation: true } |
| ] |
| } |
| } else { |
| return {}; |
| } |
| }, |
| normalList () { |
| return Util.getCities(this.cityData.cities) |
| }, |
| hotListConfig () { |
| return { |
| type: this.cityStyleType, |
| title: '热门', |
| list: Util.getCities((this.cityData.hotCity)) |
| } |
| }, |
| showError () { |
| const { normalList, hotListConfig } = this; |
| return (normalList && normalList.length < 1) && (hotListConfig && hotListConfig.list && hotListConfig.list.length < 1) |
| }, |
| listHeight () { |
| // 兼容去头逻辑 |
| let pageHeight = Utils.env.getPageHeight(); |
| |
| const { cityHeight } = this; |
| if (cityHeight && !isNaN(cityHeight) && cityHeight > 0) { |
| pageHeight = cityHeight; |
| } |
| // searchInput 84 |
| const tabHeight = this.showTab ? 90 : 0; |
| return pageHeight - 84 - tabHeight; |
| }, |
| mergeInputConfig () { |
| return { |
| autofocus: false, |
| alwaysShowCancel: true, |
| placeholder: '中文/拼音/首字母', |
| ...this.inputConfig |
| } |
| } |
| }, |
| methods: { |
| onTabSwitch (e) { |
| this.$emit('wxcTabSwitch', e); |
| }, |
| switchTab (i = 0) { |
| setTimeout(() => { |
| this.$refs['wxc-tab'].switchTab(i) |
| }, 100); |
| }, |
| onItemClick (e) { |
| this.$refs['wxc-searchbar'].autoBlur(); |
| this.show(false); |
| this.$emit('wxcCityItemSelected', { item: e.item }); |
| }, |
| onInput (e) { |
| clearTimeout(this.tId); |
| const { cities } = this.cityData; |
| const { value } = e; |
| if (value !== '' && cities && cities.length > 0) { |
| const queryData = Util.query(cities, String(value).trim()); |
| this.cityData = { |
| cities: queryData, |
| hotCity: [] |
| }; |
| this.onlyShowList = true; |
| } else { |
| this.cityData = this.saveDefaultSourceData; |
| this.onlyShowList = false; |
| } |
| this.tId = setTimeout(() => { |
| this.$emit('wxcCityOnInput', { |
| value: e.value |
| }); |
| }, 300); |
| }, |
| onCancel () { |
| this.autoBlur(); |
| this.show(false); |
| this.$emit('wxcCityCanceled', {}); |
| }, |
| onSubmit (e) { |
| this.autoBlur(); |
| this.$emit('wxcCityOnKeyUpEnter', { value: e.value }); |
| }, |
| autoBlur () { |
| const inputRef = this.$refs['wxc-searchbar']; |
| inputRef && inputRef.autoBlur(); |
| }, |
| show (status = true, callback = null) { |
| const ref = this.$refs.city |
| if (this.animationType === 'push') { |
| Utils.animation.pageTransitionAnimation(ref, `translateX(${status ? -750 : 750}px)`, status, callback) |
| } else if (this.animationType === 'model') { |
| Utils.animation.pageTransitionAnimation(ref, `translateY(${status ? -Utils.env.getScreenHeight() : Utils.env.getScreenHeight()}px)`, status, callback) |
| } |
| } |
| } |
| }; |
| </script> |
| |
| <style scoped> |
| .wxc-city { |
| position: fixed; |
| width: 750px; |
| background-color: #F2F3F4; |
| } |
| </style> |