// 传入你要获取的参数的名字 function getParam (name) { var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'); var r = window.location.search.substr(1).match(reg); //获取url中'?'符后的字符串并正则匹配 var context = ''; if (r != null) context = r[2]; // 释放变量 reg = null; r = null; return context == null || context == '' || context == 'undefined' ? '' : context; } // 需要结合area-three-sidebar-template.js使用 function getRandomString (len) { let randomString = '' if (len) { var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678' var maxPos = $chars.length for (let i = 0; i < len; i++) { randomString += $chars.charAt(Math.floor(Math.random() * maxPos)) } } else { randomString = Math.random().toString(36).substring(2) } return randomString } var AreaThreeSidebarTemplate = ` ` var areaThreeSidebarComponent = { name: 'area-three-sidebar-template', template: AreaThreeSidebarTemplate, components: { SidebarSelectorUi: SidebarSelectorUi }, props: { height: { type: String, default: '' }, value: { type: Object, default () { return {} } }, /** * 省份城市布局分割 */ useProvinceCitySplit: { type: Boolean, default: false }, /** * 城市选择禁用 */ disabledCitySelect: { type: Boolean, default: false }, /** * 数据统计tag显示 */ tagTextOnlySelectedCount: { type: Boolean, default: false }, /** * 二级子项 "全部" 文字的替换 */ childrenAddText: String, /** * 更改确认函数 * * 如果传入该函数,点击二级子项会触发,返回true会确认成功,返回false则会阻止更改 */ beforeChange: Function, /** * 是否可全不选中 */ canEmptySelected: { type: Boolean, default: false } }, model: { prop: 'value', event: 'modelChange' }, watch: { value: { handler(newVal) { this.setState(newVal) }, deep: true } }, data () { return { // 原始数组 provinceListMapExp: { '#': ['全国'], A: ['安徽', '澳门'], B: ['北京'], C: ['重庆'], F: ['福建'], G: ['广东', '广西', '贵州', '甘肃'], H: ['河北', '湖北', '黑龙江', '海南', '河南', '湖南'], J: ['吉林', '江苏', '江西'], L: ['辽宁'], N: ['内蒙古', '宁夏'], Q: ['青海'], S: ['山西', '陕西', '上海', '山东', '四川'], T: ['天津', '台湾'], X: ['西藏', '新疆', '香港'], Y: ['云南'], Z: ['浙江'] }, whenParentLevel0Selected: false, // 原始城市数据 // chinaMapJSON, provinceListMap: { // A: [ // { // name: '安徽', // expanded: false, // canExpanded: true, // selectedState: '', // children: [] // } // ] }, provinceList: [], // indexBar数据 indexList: [], provinceExp: { name: '安徽', value: '', // 展开状态 expanded: false, // 是否可以展开 canExpanded: false, children: [] }, sourceFirstCount: {}, // 全国二级菜单名 allCountryRefName: null, // 二级菜单ref名 secondRefNameObj: {} } }, created () { this.init(this.provinceListMapExp) }, mounted () { var defaultVal = this.canEmptySelected ? -1 : {} this.setState(defaultVal) this.setActiveTab(1) }, methods: { setActiveTab (num) { var { firstSidebar } = this.$refs firstSidebar.setActiveTab(num) }, // 整理城市数据列表(并初始化indexBar数据) init (provinceListMapExp) { // 整理数据得到List,同时获得indexList var provinceListMap = {} var indexList = [] this.secondRefNameObj = {} this.allCountryRefName = null for (var key in provinceListMapExp) { var areaArr = [] indexList.push(key) provinceListMapExp[key].forEach(pName => { var provinceExp = JSON.parse(JSON.stringify(this.provinceExp)) provinceExp.name = pName provinceExp.id = `ap-${getRandomString(8).toLowerCase()}` // 记录下二级ref this.$set(this.secondRefNameObj, pName, 'secondSidebar_' + provinceExp.id) if(pName === '全国') { this.allCountryRefName = 'secondSidebar_' + provinceExp.id } if (pName !== '全国') { var cities = this.getCitiesFromJSONMap(pName) // 筛选掉直辖市和特别行政区(台湾省也不不需要展开) if (cities.ProRemark === '省份' || cities.ProRemark === '自治区') { if (cities.ProID === 32) { provinceExp.children = [] provinceExp.canExpanded = false } else { cities.city.forEach(c => { // 将区县数据取出,处理成新数组,放入城市 let districtChildren = [] if(c.area && c.area.length > 0) { districtChildren = c.area.map(dItem => { return { district: dItem, selected: false, canSelected: true, id: `adi-${getRandomString(8).toLowerCase()}` } }) } // 将市区重组成一个新的对象 provinceExp.children.push({ city: c.name, selected: false, canSelected: true, id: `ac-${getRandomString(8).toLowerCase()}`, children: districtChildren// 区县 }) }) } } else if (cities.ProRemark === '直辖市') { // 直辖市,将区县放置到第二级 if(cities.city && Array.isArray(cities?.city)) { var orgDistrict = cities?.city[0].area || [] // 将区县数据取出,处理成新数组,放入城市 let districtChildren = orgDistrict.map(dItem => { return { district: dItem, selected: false, canSelected: true, id: `adi-${getRandomString(8).toLowerCase()}` } }) provinceExp.children.push({ city: provinceExp.name?.indexOf('市') > -1 ? provinceExp.name : provinceExp.name + '市', selected: false, canSelected: true, id: `ac-${getRandomString(8).toLowerCase()}`, children: districtChildren }) } } else { provinceExp.children = [] provinceExp.canExpanded = false } } provinceExp.canExpanded = provinceExp.children.length !== 0 areaArr.push(provinceExp) }) provinceListMap[key] = areaArr } this.provinceListMap = provinceListMap this.indexList = indexList.filter(i => i !== '#') // 给provinceListMap赋值 for (var k in provinceListMap) { this.$set(this.provinceListMap, k, provinceListMap[k]) } this.initProvinceList(provinceListMap) }, // 循环chinaMapJSON,找到对应省下面对应的市 getCitiesFromJSONMap (provinceName) { let temp = null for (let i = 0; i < chinaMapJSON.length; i++) { var findThis = chinaMapJSON[i].name.indexOf(provinceName) !== -1 // 如果找到了,就不再循环后面的了 if (findThis) { temp = chinaMapJSON[i] break } } return temp }, initProvinceList (provinceListMap) { var provinceList = [] for (var key in provinceListMap) { var provinces = provinceListMap[key] provinces.forEach(province => { if (province.name === '全国') { province.level = 0 } else { province.level = 1 } var cities = [] if (Array.isArray(province.children)) { province.children.forEach(city => { // 将区县数据取出,处理成新数组,放入城市 let districtChildren = [] if(Array.isArray(city.children)) { districtChildren = city.children.map(dItem => { return { topName: province.name, parentName: city.city, name: dItem.district, value: dItem.district, id: dItem.id, level: 3 } }) } cities.push({ id: city.id, name: city.city, value: city.city, level: 2, parentName: province.name, sourceChildrenCount: districtChildren.length, // 子集真实数量 children: districtChildren // 区县 }) }) } provinceList.push({ id: province.id, name: province.name, value: province.name, level: province.level, sourceChildrenCount: cities.length, // 子集真实数量 children: cities, hasThree: true }) }) } this.provinceList = provinceList }, disabledCityClick () { this.$emit('on-disabled-city-click') }, beforeChildChange (parent, child) { if (this.beforeChange) { return this.beforeChange(parent, child) } // 已选的省份列表 const selectedProvinceList = [] for(var key in this.sourceFirstCount) { selectedProvinceList.push(key) } if (this.disabledCitySelect) { if(parent.parentName && selectedProvinceList.indexOf(parent.parentName) > -1) { return true } else { this.disabledCityClick() return false } } else { return true } }, getState () { var { state } = this.getStateMore() return state }, /** * 最后输出数据结构 * 参数area示例 * { * 澳门: {} * 北京: { * 北京: ['朝阳区'] * }, * 河南: { * 南阳市: [], * 郑州: ['金水区'], * 洛阳市: ['栾川县','老城区'] * } * } */ getStateMore () { // 选中状态 var state = {} // 选中数量统计 var stateCounter = {} // 是否选了全国 var isSelectedCountry = false // 所有二级市区遍历 for(let refKey in this.secondRefNameObj) { var refName = this.secondRefNameObj[refKey] var renderList = this.$refs[refName]?.renderList || [] for (let i = 0; i < renderList.length; i++) { var parent = renderList[i] var children = parent.children var provinceName = parent.parentName // 全国选中 if (parent.level === 0 && provinceName === '全国') { if (children && children[0]._selected) { isSelectedCountry = true break } continue } // 当前省份下,全部选中(保存当前省份) if(parent.level === 0 && provinceName !== '全国') { // 市区【全部】和区县【全部】都选中 if (parent._selected) { state[provinceName] = {} break } continue } // 当前市全选中(【市区】和【全部】选中) if(parent.level === 2 && parent._selected) { if(!state[provinceName]) { state[provinceName] = {} } this.$set(state[provinceName], parent.name, []) continue } // 区县选择 if (Array.isArray(children)) { var childSelected = [] for (let j = 0; j < children.length; j++) { var child = children[j] if (child.level === 0) { continue } else { if (child._selected) { childSelected.push(child.value) } } } if (childSelected.length > 0) { if(!state[provinceName]) { state[provinceName] = {} } if(!state[provinceName][parent.name]) { this.$set(state[provinceName], parent.name, []) } state[provinceName][parent.name] = childSelected } } } } var resultState = state if(Object.keys(state).length === 0 && !isSelectedCountry && this.canEmptySelected) { resultState = -1 } return { state: resultState, stateCounter } }, /** * 设置组件状态 * getState中获取的数据能够直接传入进行状态恢复 * 全部不选中传入-1 */ setState (state) { // 所有都不选中 if (state === -1) { this.resetSelect(false) this.$emit('modelChange', -1) return } var firstSidebar = this.$refs.firstSidebar firstSidebar.setAllState(false) firstSidebar.refreshAllChildrenState(false) // 重置第二级,并且选中全国 this.resetSelect() if (typeof state === 'object' && Object.keys(state).length > 0) { this.setSidebarState(state) this.$refs[this.allCountryRefName]?.setParentLevel0State(false) } // 重新计算parent数据统计 firstSidebar.refreshAllChildrenState() this.$emit('modelChange', state || {}) }, setSidebarState (state) { for(var proName in state) { var refName = this.secondRefNameObj[proName] var refItem = this.$refs[refName] if(!refItem) { return } // 选择了全省 var stateProvince = state[proName] // 第一级省份下选中的市区数量 let _children_selectedCount = 0 refItem.setState(renderList => { // 选择了全省 if(stateProvince && Object.keys(stateProvince).length === 0) { refItem.setAllState(true) refItem.refreshAllChildrenState(true) // 更新第一级 side-bar 的状态 _children_selectedCount = renderList.length - 1 } else { renderList.forEach(parent => { // 当前市下选择的区域数组 var stateDistrict = stateProvince[parent.name] if(stateDistrict) { if (Array.isArray(stateDistrict)) { _children_selectedCount += 1 // 选择了全市 if (stateDistrict.length === 0) { refItem.setChildrenState(parent.children, true) } else { // 选择了部分区域 parent.children.forEach(child => { if (stateDistrict.includes(child.value)) { child._selected = true } }) } } refItem.checkChildrenAllChecked(parent, parent.children) } }) } // 更新第一级 side-bar 的状态 this.$set(this.sourceFirstCount, proName, { _children_selectedCount: _children_selectedCount, _children_count: renderList.length - 1 }) }) refItem.refreshAllChildrenState() } }, // 重置所有选择 resetSelect(selectedAll = true) { var { firstSidebar } = this.$refs firstSidebar.setAllState(false) firstSidebar.refreshAllChildrenState(false) firstSidebar.setParentLevel0State(selectedAll) var firstRenderList = firstSidebar.renderList for(let item of firstRenderList) { var secondRef = this.$refs['secondSidebar_' + item.id] secondRef.setAllState(false) secondRef.refreshAllChildrenState(false) if(item.name === '全国'){ secondRef.setParentLevel0State(selectedAll) } } this.sourceFirstCount = {} }, // 处理第一级 side-bar 组件的变化事件 onChangeFirst({ parent, child, renderList }) { if (parent.level === 0 && parent.name === '全国') { this.resetSelect() } else { this.$set(this.sourceFirstCount, parent.value, { _children_selectedCount: parent._children_selectedCount, _children_count: parent._children_count }) this.$refs.firstSidebar.setParentLevel0State(false) } }, // 处理第二级 side-bar 组件的变化事件 onChange ({ parent, child, renderList }, value) { this.disposeSecondCount({ parent, child, renderList }, value) var stateValue = this.getState() var payload = { parent, child, value: stateValue } this.$emit('modelChange', payload.value) this.$emit('change', payload) }, // 处理二级菜单选择 disposeSecondCount ({ parent, child, renderList }, value) { if(parent.level === 0 && parent.parentName ==='全国'){ this.resetSelect() return } // 将全国选择重置掉 if(this.allCountryRefName) { this.$refs[this.allCountryRefName]?.setParentLevel0State(false) } var selectedNum = renderList?.filter(temp => temp._children_selectedCount > 0)?.length || 0 var result = { _children_selectedCount: selectedNum, _children_count: renderList.length - 1 } // 更新第一级 side-bar 的状态 this.$set(this.sourceFirstCount, value, result) this.$refs.firstSidebar.setParentLevel0State(false) }, // 是否是港澳台地区 isGAT(val) { var GATList = ['香港', '澳门', '台湾'] return val && GATList.indexOf(val) > -1 } } }