|
@@ -0,0 +1,789 @@
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+ class="selector-content region-selector-content"
|
|
|
+ key="s-content"
|
|
|
+ >
|
|
|
+ <div class="selected-list" v-if="showSelectedList">
|
|
|
+ <el-tag
|
|
|
+ type="plain"
|
|
|
+ :closable="!singleChoice"
|
|
|
+ v-for="tag in selectedTagList"
|
|
|
+ :key="tag"
|
|
|
+ @close="tagClose(tag)"
|
|
|
+ >{{ tag }}</el-tag
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ <div class="select-list" ref="selectList">
|
|
|
+ <div
|
|
|
+ class="index-item"
|
|
|
+ :data-index="key"
|
|
|
+ :ref="'index-item-' + key"
|
|
|
+ v-for="(item, key) in provinceListMap"
|
|
|
+ :key="key"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="j-button-item"
|
|
|
+ v-for="(province, ii) in item"
|
|
|
+ :class="{
|
|
|
+ bgc: onlyProvince,
|
|
|
+ expand: province.expanded && province.canExpanded,
|
|
|
+ active: provinceButtonActive(province),
|
|
|
+ country: province.name === '全国',
|
|
|
+ hidden: !moreStatus && key === 'other',
|
|
|
+ [province.selectedState]: !showSelectedList
|
|
|
+ }"
|
|
|
+ :key="ii * 2"
|
|
|
+ @click="changeExpandStateForLine($event, province)"
|
|
|
+ >
|
|
|
+ {{ province.name }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="city-list" ref="cityList" v-show="expandedCitiesShow">
|
|
|
+ <div class="city-list-content">
|
|
|
+ <div
|
|
|
+ v-if="!onlyCity"
|
|
|
+ class="city-item province"
|
|
|
+ :class="{
|
|
|
+ active: expandedProvince.selectedState === 'checked'
|
|
|
+ }"
|
|
|
+ @click="clickProvinceInCityListForLine(expandedProvince)"
|
|
|
+ >
|
|
|
+ {{ expandedProvince.name }}
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="city-item city"
|
|
|
+ :class="{
|
|
|
+ active: city.selected
|
|
|
+ }"
|
|
|
+ v-for="(city, iii) in expandedProvince.children"
|
|
|
+ :key="iii"
|
|
|
+ @click="changeCityStateForLine(expandedProvince, city)"
|
|
|
+ >
|
|
|
+ {{ city.city }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="city-list-footer">
|
|
|
+ <button class="confirm" @click="confirmCitySelected">确定</button>
|
|
|
+ <button class="cancel" @click="cancelCitySelected">取消</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div slot="expand" class="is-expand" @click="toggleMoreStatus">
|
|
|
+ <span>{{ moreStatus ? '收起' : '展开' }}</span>
|
|
|
+ <i class="el-icon-arrow-down" :class="{'is-reverse': moreStatus}"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { Tag } from 'element-ui'
|
|
|
+import chinaMapJSON from '@/assets/js/china_area.js'
|
|
|
+import { hotAndAllProvinceList } from '@/assets/js/selector.js'
|
|
|
+import { getRandomString } from '@/utils/'
|
|
|
+export default {
|
|
|
+ name: 'RegionLineSelector',
|
|
|
+ props: {
|
|
|
+ onlyProvince: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ // 是否仅能选择城市
|
|
|
+ onlyCity: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ // 是否单选
|
|
|
+ singleChoice: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ beforeTabClick: Function,
|
|
|
+ // 是否显示选择结果
|
|
|
+ showSelectedList: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ // 刚进入页面需要被选中的城市数据
|
|
|
+ value: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ [Tag.name]: Tag,
|
|
|
+ },
|
|
|
+ model: {
|
|
|
+ prop: 'value',
|
|
|
+ event: 'change'
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ // 省份与字母IndexBar对照表
|
|
|
+ provinceListMapExp: hotAndAllProvinceList,
|
|
|
+ provinceListMap: {},
|
|
|
+ // indexBar数据
|
|
|
+ indexList: [],
|
|
|
+ provinceExp: {
|
|
|
+ name: '',
|
|
|
+ // 展开状态
|
|
|
+ expanded: false,
|
|
|
+ // 是否可以展开
|
|
|
+ canExpanded: false,
|
|
|
+ // 选中状态: half(半选)、checked(全选)、''(未选中)、checkeddisabled(全选不能点击)、nonedisabled(未选不能点击)
|
|
|
+ selectedState: '',
|
|
|
+ children: [],
|
|
|
+ id: ''
|
|
|
+ },
|
|
|
+ // line状态下,当前被展开省的省份列表
|
|
|
+ expandedProvince: {
|
|
|
+ children: []
|
|
|
+ },
|
|
|
+ selectedCity: {},
|
|
|
+ selectedTagList: [],
|
|
|
+ moreStatus: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ expandedCitiesShow() {
|
|
|
+ if (!this.expandedProvince) return false
|
|
|
+ return this.expandedProvince.children.length
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ value(newVal, oldVal) {
|
|
|
+ this.setState(newVal)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.initIndexBarAndAreaMap()
|
|
|
+ this.setState(this.value)
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ toggleMoreStatus() {
|
|
|
+ this.moreStatus = !this.moreStatus
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ this.provinceListMap[key].forEach((item) => {
|
|
|
+ item.expanded = false
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.expandedProvince = {
|
|
|
+ children: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getAllItem() {
|
|
|
+ var p = {}
|
|
|
+ if (this.provinceListMap['hot']) {
|
|
|
+ p = this.provinceListMap['hot'][0]
|
|
|
+ }
|
|
|
+ return p
|
|
|
+ },
|
|
|
+ // 整理城市数据列表(并初始化indexBar数据)
|
|
|
+ initIndexBarAndAreaMap(provinceMap = {}) {
|
|
|
+ // 整理数据得到indexListMap(),同时获得indexList
|
|
|
+ const provinceListMap = {}
|
|
|
+ const indexList = []
|
|
|
+ const pMap =
|
|
|
+ Object.keys(provinceMap).length === 0
|
|
|
+ ? this.provinceListMapExp
|
|
|
+ : provinceMap
|
|
|
+ if (Object.keys(provinceMap).length !== 0) {
|
|
|
+ this.provinceListMapExp = provinceMap
|
|
|
+ }
|
|
|
+ for (const key in pMap) {
|
|
|
+ const areaArr = []
|
|
|
+ indexList.push(key)
|
|
|
+ pMap[key].forEach((pName) => {
|
|
|
+ const provinceExp = JSON.parse(JSON.stringify(this.provinceExp))
|
|
|
+
|
|
|
+ provinceExp.name = pName
|
|
|
+ provinceExp.id = `ap-${getRandomString(8).toLowerCase()}`
|
|
|
+
|
|
|
+ if (pName !== '全国') {
|
|
|
+ let cities = []
|
|
|
+ if (!this.onlyProvince) {
|
|
|
+ cities = this.getCitiesFromJSONMap(pName)
|
|
|
+ }
|
|
|
+ // 筛选掉直辖市和特别行政区(台湾省也不不需要展开)
|
|
|
+ if (cities.ProRemark === '省份' || cities.ProRemark === '自治区') {
|
|
|
+ if (cities.ProID === 32) {
|
|
|
+ provinceExp.children = []
|
|
|
+ provinceExp.canExpanded = false
|
|
|
+ } else {
|
|
|
+ cities.city.forEach((c) => {
|
|
|
+ // 将市区重组成一个新的对象
|
|
|
+ return provinceExp.children.push({
|
|
|
+ city: c.name,
|
|
|
+ selected: false,
|
|
|
+ canSelected: true,
|
|
|
+ id: `ac-${getRandomString(8).toLowerCase()}`
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ provinceExp.children = []
|
|
|
+ provinceExp.canExpanded = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ provinceExp.canExpanded = provinceExp.children.length !== 0
|
|
|
+ areaArr.push(provinceExp)
|
|
|
+ })
|
|
|
+
|
|
|
+ provinceListMap[key] = areaArr
|
|
|
+ }
|
|
|
+
|
|
|
+ this.provinceListMap = provinceListMap
|
|
|
+ this.indexList = indexList
|
|
|
+
|
|
|
+ // 给provinceListMap赋值
|
|
|
+ for (const k in provinceListMap) {
|
|
|
+ this.$set(this.provinceListMap, k, provinceListMap[k])
|
|
|
+ }
|
|
|
+ this.getAllItem().selectedState = 'checked'
|
|
|
+ },
|
|
|
+ // 循环chinaMapJSON,找到对应省下面对应的市
|
|
|
+ getCitiesFromJSONMap(provinceName) {
|
|
|
+ return chinaMapJSON.find((item) => item.name.indexOf(provinceName) !== -1)
|
|
|
+ },
|
|
|
+ // 控制城市盒子展开和收起(card)
|
|
|
+ changeExpandState(e, province) {
|
|
|
+ if (!province.canExpanded) return
|
|
|
+ province.expanded = !province.expanded
|
|
|
+ },
|
|
|
+ // 控制城市盒子展开和收起(line)
|
|
|
+ changeExpandStateForLine(e, province) {
|
|
|
+ const beforeTabClick = this.beforeTabClick
|
|
|
+ if (beforeTabClick) {
|
|
|
+ const pass = beforeTabClick(e, province)
|
|
|
+ if (!pass) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (province.name === this.expandedProvince.name) return
|
|
|
+ // 循环,将其他全部置为false
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ this.provinceListMap[key].forEach((item) => {
|
|
|
+ item.expanded = false
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.expandedProvince = {
|
|
|
+ children: []
|
|
|
+ }
|
|
|
+ province.expanded = true
|
|
|
+ // 省份数据与原数据分离(点击确定覆盖原数据,点击取消则不保存数据)
|
|
|
+ this.expandedProvince = JSON.parse(JSON.stringify(province))
|
|
|
+ // 如果直接点击直辖市
|
|
|
+ if (province.children.length === 0) {
|
|
|
+ if (province.name === '全国') {
|
|
|
+ this.setState()
|
|
|
+ } else {
|
|
|
+ if (this.singleChoice) {
|
|
|
+ this.setState()
|
|
|
+ }
|
|
|
+ this.getAllItem().selectedState = ''
|
|
|
+ if (this.showSelectedList) {
|
|
|
+ this.provinceListMap['hot'][0].selectedState = ''
|
|
|
+ this.expandedProvince.selectedState = 'checked'
|
|
|
+ } else {
|
|
|
+ var checked = this.expandedProvince.selectedState
|
|
|
+ if (checked === 'checked') {
|
|
|
+ this.expandedProvince.selectedState = ''
|
|
|
+ } else {
|
|
|
+ this.expandedProvince.selectedState = 'checked'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.confirmCitySelected()
|
|
|
+ } else {
|
|
|
+ var hasCitySelected = this.expandedProvince.children.some(function (v) {
|
|
|
+ return v.selected
|
|
|
+ })
|
|
|
+ if (!hasCitySelected) {
|
|
|
+ this.expandedProvince.selectedState = 'checked'
|
|
|
+ }
|
|
|
+ this.moveTheCityContainer(e)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ moveTheCityContainer(e) {
|
|
|
+ const selectList = this.$refs.selectList
|
|
|
+ const cityList = this.$refs.cityList
|
|
|
+ const { lineFirstDom, clickLine } = this.getDomInfo(e.target)
|
|
|
+
|
|
|
+ if (clickLine >= lineFirstDom.length) {
|
|
|
+ selectList.appendChild(cityList) // 往列表末尾插入元素
|
|
|
+ } else if (clickLine <= 1) {
|
|
|
+ selectList.insertBefore(cityList, lineFirstDom[1])
|
|
|
+ } else {
|
|
|
+ selectList.insertBefore(cityList, lineFirstDom[clickLine])
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getDomInfo(dom) {
|
|
|
+ const indexDOMList = [] // 所有索引项dom数组(索引项下有每个省份的按钮)
|
|
|
+ const indexTopList = [] // 每个元素距离顶部高度数组
|
|
|
+ const tolerance = [] // 行间距差值
|
|
|
+ const lineFirstDom = [
|
|
|
+ // 每行的第一个dom
|
|
|
+ ...this.$refs[`index-item-${this.indexList[0]}`]
|
|
|
+ ]
|
|
|
+ this.indexList.forEach((item) => {
|
|
|
+ const ref = this.$refs[`index-item-${item}`]
|
|
|
+ if (ref && ref[0]) {
|
|
|
+ indexDOMList.push(ref[0])
|
|
|
+ indexTopList.push(parseInt(ref[0].getBoundingClientRect().top))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ for (let i = 0; i < indexTopList.length; i++) {
|
|
|
+ if (indexTopList[i + 1] > indexTopList[i]) {
|
|
|
+ tolerance.push(indexTopList[i + 1] - indexTopList[i])
|
|
|
+ lineFirstDom.push(indexDOMList[i + 1])
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 求平均值,谁的值大于平均值,就在哪一行
|
|
|
+ let insetedLine = 0
|
|
|
+ const avg =
|
|
|
+ tolerance.length > 0
|
|
|
+ ? tolerance.reduce((prev, item) => prev + item) / tolerance.length
|
|
|
+ : 0
|
|
|
+ for (let j = 0; j < tolerance.length; j++) {
|
|
|
+ if (tolerance[j] > avg) {
|
|
|
+ insetedLine = j + 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // clickDOMIndex: 点击dom在indexDOMList的索引
|
|
|
+ const clickDOMIndex = indexDOMList.findIndex(
|
|
|
+ (item) => item === dom.parentNode
|
|
|
+ ) // dom是点击的按钮
|
|
|
+ const indexTopSet = Array.from(new Set(indexTopList))
|
|
|
+ const clickLine =
|
|
|
+ indexTopSet.findIndex((item) => item === indexTopList[clickDOMIndex]) +
|
|
|
+ 1
|
|
|
+
|
|
|
+ return {
|
|
|
+ lineFirstDom, // 每行的第一个dom
|
|
|
+ indexTopList, // 每个元素距离顶部高度数组
|
|
|
+ indexTopSet, // indexTopList去重后的数组(里面是每一行距离顶部的高度)
|
|
|
+ tolerance, // 行间距差值
|
|
|
+ clickLine, // 通过传入的dom计算出的当前点击的哪一行
|
|
|
+ insetedLine // 点击按钮前cityList在哪一行
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 城市选择按钮点击事件(line)
|
|
|
+ // 根据城市的选择情况判断省份的选择情况
|
|
|
+ changeCityStateForLine(province, city) {
|
|
|
+ if (this.singleChoice) {
|
|
|
+ this.setState()
|
|
|
+ }
|
|
|
+
|
|
|
+ this.getAllItem().selectedState = ''
|
|
|
+ province.selectedState = ''
|
|
|
+
|
|
|
+ if (this.singleChoice) {
|
|
|
+ // 单选情况下,需要先将其他选项取消掉
|
|
|
+ province.children.forEach((item) => (item.selected = false))
|
|
|
+ }
|
|
|
+ city.selected = !city.selected
|
|
|
+ // 判断省份的选择状态
|
|
|
+ let count = 0
|
|
|
+ const cityLength = province.children.length
|
|
|
+ if (cityLength) {
|
|
|
+ province.children.forEach((v) => {
|
|
|
+ // 前提是可点击的
|
|
|
+ if (v.canSelected && v.selected) {
|
|
|
+ count++
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (count === cityLength) {
|
|
|
+ // line状态下 ,城市全部选中,则只选中省份即可
|
|
|
+ province.selectedState = 'checked'
|
|
|
+ province.children.forEach((item) => (item.selected = false))
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 省份点击事件(城市列表中的省份按钮)(line)
|
|
|
+ clickProvinceInCityListForLine(province) {
|
|
|
+ if (this.singleChoice) {
|
|
|
+ this.setState()
|
|
|
+ this.getAllItem().selectedState = ''
|
|
|
+ }
|
|
|
+ const state = province.selectedState
|
|
|
+ province.children.forEach((v) => (v.selected = false))
|
|
|
+ if (state === 'checked') {
|
|
|
+ province.selectedState = ''
|
|
|
+ } else {
|
|
|
+ province.selectedState = 'checked'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 检查是否所有省份按钮被全选中
|
|
|
+ // 全部被全选->返回true
|
|
|
+ checkAllProvinceState() {
|
|
|
+ const stateArr = []
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ this.provinceListMap[key].forEach((item) => {
|
|
|
+ if (item.name !== '全国') {
|
|
|
+ if (item.selectedState === '') {
|
|
|
+ stateArr.push('unchecked')
|
|
|
+ } else if (item.selectedState === 'checked') {
|
|
|
+ stateArr.push('checked')
|
|
|
+ } else {
|
|
|
+ stateArr.push('other')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // 统计不同状态的个数
|
|
|
+ const counter = {
|
|
|
+ checked: 0,
|
|
|
+ unchecked: 0,
|
|
|
+ other: 0
|
|
|
+ }
|
|
|
+ for (let i = 0; i < stateArr.length; i++) {
|
|
|
+ const k = stateArr[i]
|
|
|
+ if (counter[k]) {
|
|
|
+ counter[k] += 1
|
|
|
+ } else {
|
|
|
+ counter[k] = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ state: stateArr,
|
|
|
+ allSelected: counter.checked === stateArr.length,
|
|
|
+ noSelected: counter.unchecked === stateArr.length
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setAllNoSelected() {
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ this.provinceListMap[key].forEach((item) => {
|
|
|
+ item.selectedState = ''
|
|
|
+ item.children.forEach((iitem) => {
|
|
|
+ iitem.selected = false
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 初始化选中城市数据(card/line共用)
|
|
|
+ setState(data = {}) {
|
|
|
+ // 设置全国
|
|
|
+ if (!data || Object.keys(data).length === 0) {
|
|
|
+ // 其他全部设置不选中,全国设置选中
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ this.provinceListMap[key].forEach((item) => {
|
|
|
+ item.selectedState = ''
|
|
|
+ item.children.forEach((iitem) => {
|
|
|
+ iitem.selected = false
|
|
|
+ })
|
|
|
+ if (item.name === '全国') {
|
|
|
+ item.selectedState = 'checked'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 先将所有城市选择取消
|
|
|
+ this.setState()
|
|
|
+ // 设置某几个省份被选中
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ this.provinceListMap[key].forEach((item) => {
|
|
|
+ const selectCityArr = data[item.name]
|
|
|
+ if (Array.isArray(selectCityArr)) {
|
|
|
+ if (selectCityArr.length === 0) {
|
|
|
+ // 全省被选中
|
|
|
+ item.children.forEach((iitem) => {
|
|
|
+ iitem.selected = false
|
|
|
+ })
|
|
|
+
|
|
|
+ item.selectedState = 'checked'
|
|
|
+ } else {
|
|
|
+ // 省份中的某些市被选中
|
|
|
+ item.children.forEach((iitem) => {
|
|
|
+ if (selectCityArr.indexOf(iitem.city) !== -1) {
|
|
|
+ iitem.selected = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // item.selectedState = 'half'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (item.name === '全国') {
|
|
|
+ item.selectedState = ''
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.getSelectedTagList(data)
|
|
|
+ },
|
|
|
+ // 获取当前选中城市数据
|
|
|
+ getState() {
|
|
|
+ const counter = {}
|
|
|
+ // 判断是否全国被选中
|
|
|
+ if (this.getAllItem().selectedState === 'checked') {
|
|
|
+ return counter
|
|
|
+ }
|
|
|
+
|
|
|
+ // 全国没有被选中,排除循环全国
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ // if (key === '#') continue
|
|
|
+ this.provinceListMap[key].forEach((item) => {
|
|
|
+ // 当前省份下被选中的城市数量
|
|
|
+ const selectedCityArr = []
|
|
|
+ const cityTotalCount = item.children.length
|
|
|
+ item.children.forEach((iitem) => {
|
|
|
+ if (iitem.selected && iitem.canSelected) {
|
|
|
+ selectedCityArr.push(iitem.city)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 先看是否有城市被选,再看是否省份被选
|
|
|
+ if (selectedCityArr.length) {
|
|
|
+ counter[item.name] = selectedCityArr
|
|
|
+ } else {
|
|
|
+ if (item.selectedState === 'checked') {
|
|
|
+ counter[item.name] = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return counter
|
|
|
+ },
|
|
|
+ provinceButtonActive(province) {
|
|
|
+ if (this.onlyProvince) {
|
|
|
+ return province.selectedState === 'checked'
|
|
|
+ } else {
|
|
|
+ return province.selectedState === 'checked' && province.name === '全国'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ confirmCitySelected() {
|
|
|
+ // 统计时候有城市被选中了
|
|
|
+ const cityLength = this.expandedProvince.children.length
|
|
|
+ let count = 0
|
|
|
+ if (cityLength) {
|
|
|
+ const selectedCityArr = this.expandedProvince.children.filter((v) => {
|
|
|
+ return v.canSelected && v.selected
|
|
|
+ })
|
|
|
+ count = selectedCityArr.length
|
|
|
+ // 判断是否仅能够选中城市
|
|
|
+ if (this.onlyCity) {
|
|
|
+ if (count === 0) {
|
|
|
+ return this.$toast('还未选择城市,请选择')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (this.showSelectedList) {
|
|
|
+ if (
|
|
|
+ this.expandedProvince.selectedState !== 'checked' &&
|
|
|
+ cityLength !== 0 &&
|
|
|
+ count === 0
|
|
|
+ ) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var beforeChange = this.beforeChange
|
|
|
+ if (beforeChange) {
|
|
|
+ var pass = beforeChange(this.expandedProvince)
|
|
|
+ if (!pass) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 替换赋值
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ // if (key === '#') continue
|
|
|
+ const res = this.provinceListMap[key].find((item) => {
|
|
|
+ if (item.name === this.expandedProvince.name) {
|
|
|
+ Object.assign(item, this.expandedProvince)
|
|
|
+ this.getAllItem().selectedState = ''
|
|
|
+ }
|
|
|
+ return item.name === this.expandedProvince.name
|
|
|
+ })
|
|
|
+ if (res) {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.selectedCity = this.getState()
|
|
|
+
|
|
|
+ this.getSelectedTagList(this.selectedCity)
|
|
|
+ this.cancelCitySelected()
|
|
|
+ this.$emit('change', this.selectedCity)
|
|
|
+ },
|
|
|
+ cancelCitySelected() {
|
|
|
+ const selected = this.getState()
|
|
|
+ if (selected) {
|
|
|
+ this.setState(selected)
|
|
|
+ }
|
|
|
+ for (const key in this.provinceListMap) {
|
|
|
+ this.provinceListMap[key].forEach((item) => {
|
|
|
+ item.expanded = false
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.expandedProvince = {
|
|
|
+ children: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getSelectedTagList(v) {
|
|
|
+ const privinceArr = []
|
|
|
+ let cityArr = []
|
|
|
+ for (const key in v) {
|
|
|
+ const item = v[key]
|
|
|
+ if (Array.isArray(item)) {
|
|
|
+ if (item.length === 0) {
|
|
|
+ privinceArr.push(key)
|
|
|
+ } else {
|
|
|
+ cityArr = cityArr.concat(item)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.selectedTagList = privinceArr.concat(cityArr)
|
|
|
+ },
|
|
|
+ tagClose(name) {
|
|
|
+ this.cancelCitySelected()
|
|
|
+ if (name === '全国') {
|
|
|
+ this.selectedTagList = []
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for (const key in this.selectedCity) {
|
|
|
+ const index = this.selectedCity[key].indexOf(name)
|
|
|
+ if (name === key) {
|
|
|
+ delete this.selectedCity[key]
|
|
|
+ break
|
|
|
+ } else if (index !== -1) {
|
|
|
+ this.selectedCity[key].splice(index, 1)
|
|
|
+ if (this.selectedCity[key].length === 0) {
|
|
|
+ delete this.selectedCity[key]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.setState(this.selectedCity)
|
|
|
+ this.confirmCitySelected()
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.region-selector-content {
|
|
|
+ padding-right: 32px;
|
|
|
+ .el-tag--plain {
|
|
|
+ color: $color-text--highlight;
|
|
|
+ border-color: $color-text--highlight;
|
|
|
+ .el-tag__close {
|
|
|
+ color: $color-text--highlight;
|
|
|
+ &:hover {
|
|
|
+ color: #fff;
|
|
|
+ background-color: $color-text--highlight;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-tag {
|
|
|
+ margin: 4px 6px;
|
|
|
+ height: 28px;
|
|
|
+ line-height: 26px;
|
|
|
+ }
|
|
|
+ .select-list {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding-right: 72px;
|
|
|
+ .index-item {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ .index-bar {
|
|
|
+ margin-left: 10px;
|
|
|
+ margin-right: 5px;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .j-button-item {
|
|
|
+ display: inline-block;
|
|
|
+ margin: 2px 5px;
|
|
|
+ padding: 1px 6px;
|
|
|
+ line-height: 20px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #fff;
|
|
|
+ cursor: pointer;
|
|
|
+ box-sizing: border-box;
|
|
|
+ &:hover {
|
|
|
+ color: $color-text--highlight;
|
|
|
+ }
|
|
|
+ &.active {
|
|
|
+ color: #fff;
|
|
|
+ background-color: $color-text--highlight;
|
|
|
+ border: 1px solid $color-text--highlight;
|
|
|
+ }
|
|
|
+ &.expand {
|
|
|
+ background-color: #f5f5fb;
|
|
|
+ border: 1px solid #e0e0e0;
|
|
|
+ border-bottom-color: transparent;
|
|
|
+ border-bottom-left-radius: 0;
|
|
|
+ border-bottom-right-radius: 0;
|
|
|
+ position: relative;
|
|
|
+ z-index: 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .city-list {
|
|
|
+ margin-top: -4px;
|
|
|
+ padding: 12px 20px;
|
|
|
+ width: 100%;
|
|
|
+ background-color: #f5f5fb;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #e0e0e0;
|
|
|
+ .city-item {
|
|
|
+ display: inline-block;
|
|
|
+ margin: 0 4px 4px;
|
|
|
+ padding: 4px 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ &.active {
|
|
|
+ color: #fff;
|
|
|
+ background-color: $color-text--highlight;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .city-list-footer {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin-top: 12px;
|
|
|
+ button {
|
|
|
+ padding: 4px 16px;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 18px;
|
|
|
+ color: #1d1d1d;
|
|
|
+ background-color: #fff;
|
|
|
+ cursor: pointer;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #e0e0e0;
|
|
|
+ &.confirm {
|
|
|
+ margin-right: 15px;
|
|
|
+ color: #fff;
|
|
|
+ background-color: #2cb7ca;
|
|
|
+ border-color: #2cb7ca;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .is-expand{
|
|
|
+ position: absolute;
|
|
|
+ top: 2px;
|
|
|
+ right: 0;
|
|
|
+ display: inline-block;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 22px;
|
|
|
+ color: #686868;
|
|
|
+ cursor: pointer;
|
|
|
+ i{
|
|
|
+ margin-left: 2px;
|
|
|
+ transform: rotate(0deg);
|
|
|
+ transition: transform .3s;
|
|
|
+ }
|
|
|
+ .is-reverse{
|
|
|
+ transform: rotate(180deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|