v-distpicker 直辖市的修改
v-distpicker 直辖市的修改
一.v-distpicker 的用法
1.安装:npm install v-distpicker
二。改造直辖市
这个组件在选择四个直辖市的时候有点问题,比如选择北京,就是北京市,北京市,···区,这样显示感觉想出错了一样:如果
1.第一种,将直辖市,改成北京,北京市,XX区,淘宝手机地址更换就是这样的,看起来也比北京市,北京市好。
比较推荐这种方式,因为改动小,简单。
唯一的问题就是,在引用的时候,如果是通过npm install 安装引用的,更改node_module中的文件时没效果的,
解决方式:更改引用插件的源码,使其生效,需要我们把插件下载下来,放到项目中,已组件的形式引用,这样改过的源码才会生效。但是这样做有一个问题就是不能时时更新这个插件,比如这个级联插件在git上又有代码迭代,想要获取新的代码,就要重新下载新的版本,把自己之前的改动放上去,再重新引入。好在这个省市区级联的问题,更新的内容不大,所以下载后引用的方式影响不大。
步骤:
找v-distPicekr到需要的版本下载下来
解压后找到src下面的三个文件
复制三个文件,到一个文件夹,比如我的areaPicker,放到项目中作为组件引用
作为正常组件引用即可
此事修改这个areaPicker里面的districts.js文件就可以了,去掉省级单位中直辖市的市字就生效了。
这种方案改动小,而且简单,也好于“北京市北京市”这种的
第二种,当选择直辖市事,去掉中间的市,直接显示区,如图:
回显是,city传空即可。
这种修改也需要修改源码,所以改动是在第一种方法下载引用的文件中修改。
引用和回显都没问题,由于是帮别人改的代码,效果实现了,但没有过多测试。
直接附上修改的 Distpicker.vue代码,其他文件没有改动。
<template><div :class="wrapper"><template v-if="type !== 'mobile'"><label><select@change="getCities"v-model="currentProvince":disabled="disabled || provinceDisabled"><option :value="placeholders.province">{{ placeholders.province }}</option><option v-for="(item, index) in provinces" :value="item" :key="index">{{ item }}</option></select></label><template v-if="!onlyProvince"><label><select@change="getAreas"v-model="currentCity":disabled="disabled || cityDisabled"v-if="!isDirectlyCity"><option :value="placeholders.city">{{ placeholders.city }}</option><optionv-for="(item, index) in cities":value="item":key="index">{{ item }}</option></select></label><label><selectv-if="!hideArea"v-model="currentArea":disabled="disabled || areaDisabled"><option :value="placeholders.area">{{ placeholders.area }}</option><option v-for="(item, index) in areas" :value="item" :key="index">{{ item }}</option></select></label></template></template><template v-else><div :class="addressHeader"><ul><li :class="{ active: tab === 1 }" @click="resetProvince">{{currentProvince && !staticPlaceholder? currentProvince: placeholders.province}}</li><template v-if="!onlyProvince"><liv-if="showCityTab":class="{ active: tab === 2 }"@click="resetCity">{{currentCity && !staticPlaceholder? currentCity: placeholders.city}}</li><liv-if="showAreaTab && !hideArea":class="{ active: tab === 3 }">{{currentArea && !staticPlaceholder? currentArea: placeholders.area}}</li></template></ul></div><div :class="addressContainer"><ul v-if="tab === 1"><liv-for="(item, index) in provinces":class="{ active: item === currentProvince }"@click="chooseProvince(item)":key="index">{{ item }}</li></ul><template v-if="!onlyProvince"><ul v-if="tab === 2"><liv-for="(item, index) in cities":class="{ active: item === currentCity }"@click="chooseCity(item)":key="index">{{ item }}</li></ul><ul v-if="tab === 3 && !hideArea"><liv-for="(item, index) in areas":class="{ active: item === currentArea }"@click="chooseArea(item)":key="index">{{ item }}</li></ul></template></div></template></div>
</template><script>
import DISTRICTS from "./districts";const DEFAULT_CODE = 100000;export default {name: "v-distpicker",props: {province: { type: [String, Number], default: "" },city: { type: [String, Number], default: "" },area: { type: [String, Number], default: "" },type: { type: String, default: "" },hideArea: { type: Boolean, default: false },onlyProvince: { type: Boolean, default: false },staticPlaceholder: { type: Boolean, default: false },placeholders: {type: Object,default() {return {province: "省",city: "市",area: "区",};},},districts: {type: [Array, Object],default() {return DISTRICTS;},},disabled: { type: Boolean, default: false },provinceDisabled: { type: Boolean, default: false },cityDisabled: { type: Boolean, default: false },areaDisabled: { type: Boolean, default: false },addressHeader: { type: String, default: "address-header" },addressContainer: { type: String, default: "address-container" },wrapper: { type: String, default: "distpicker-address-wrapper" },},data() {return {tab: 1,showCityTab: false,showAreaTab: false,isDirectlyCity: false,provinces: [],cities: [],areas: [],currentProvince:this.determineType(this.province) || this.placeholders.province,currentCity: this.determineType(this.city) || this.placeholders.city,currentArea: this.determineType(this.area) || this.placeholders.area,};},created() {if (this.type != "mobile") {this.provinces = this.getDistricts();if (this.province) {if (this.province == "北京市" ||this.province == "上海市" ||this.province == "天津市" ||this.province == "重庆市") {this.isDirectlyCity = true;this.areas = this.getDistricts(this.getAreaCode(this.determineType(this.province), this.area));return false;} else {this.cities = this.getDistricts(this.getAreaCode(this.determineType(this.province)));}} else {this.cities = [];}this.areas = this.city? this.getDistricts(this.getAreaCode(this.determineType(this.city), this.area)): [];// this.provinces = this.getDistricts();// this.cities = this.province// ? this.getDistricts(this.getAreaCode(this.determineType(this.province)))// : [];// let directCity = this.isDirectCity(this.province, this.city);// this.areas = this.city// ? this.getDistricts(// this.getAreaCode(// this.determineType(this.city),// directCity ? this.determineType(this.city) : this.area// )// )// : [];} else {if (this.area && !this.hideArea && !this.onlyProvince) {this.tab = 3;this.showCityTab = true;this.showAreaTab = true;let directCity = this.isDirectCity(this.province, this.city);this.areas = this.getDistricts(this.getAreaCode(this.determineType(this.city),directCity ? this.determineType(this.city) : this.area));} else if (this.city && this.hideArea && !this.onlyProvince) {this.tab = 2;this.showCityTab = true;this.cities = this.getDistricts(this.getAreaCode(this.determineType(this.province)));} else {this.provinces = this.getDistricts();}}},watch: {currentProvince(vaule) {this.$emit("province", this.setData(vaule, "province"));if (this.onlyProvince) {this.emit("selected");}},currentCity(value) {this.$emit("city", this.setData(value, "city", this.currentProvince));if (value != this.placeholders.city && this.hideArea) {this.emit("selected");}},currentArea(value) {this.$emit("area", this.setData(value, "area", this.currentProvince, true));if (value != this.placeholders.area) {this.emit("selected");}},province(value) {this.currentProvince = this.province || this.placeholders.province;this.cities = this.determineValue("province",this.currentProvince,this.placeholders.province);},city(value) {this.currentCity = this.city || this.placeholders.city;this.areas = this.determineValue("city",this.currentCity,this.placeholders.city,this.currentProvince);},area(value) {this.currentArea = this.area || this.placeholders.area;},},methods: {setData(value, type, check = "", isArea = false) {let code;if (isArea) {code = this.getCodeByArea(value);} else {code = this.getAreaCode(value, check, type);}return {code: code,value: value,};},getCodeByArea(value) {let areas_map = {};let arr_keys = Object.keys(this.areas);for (let i = 0; i < arr_keys.length; i++) {let arr_key = arr_keys[i];let arr_value = this.areas[arr_key];areas_map[arr_value] = arr_key;}return areas_map[value];},emit(name) {let data = {province: this.setData(this.currentProvince, "province"),};if (!this.onlyProvince) {this.$set(data,"city",this.setData(this.currentCity, "city", this.currentProvince));}if (!this.onlyProvince || this.hideArea) {this.$set(data,"area",this.setData(this.currentArea, "area", this.currentProvince, true));}this.$emit(name, data);},getCities() {this.currentCity = this.placeholders.city;this.currentArea = this.placeholders.area;if (this.currentProvince == "北京市" ||this.currentProvince == "天津市" ||this.currentProvince == "上海市" ||this.currentProvince == "重庆市") {this.cities = [];this.isDirectlyCity = true;this.getAreas(this.isDirectlyCity);} else {this.isDirectlyCity = false;this.cities = this.determineValue("province",this.currentProvince,this.placeholders.province);this.cleanList("areas");}if (this.cities.length === 0) {this.emit("selected");this.tab = 1;this.showCityTab = false;}},getAreas(isDirectlyCity) {this.currentArea = this.placeholders.area;if (isDirectlyCity === true) {this.areas = this.determineValue("city",this.currentProvince,this.placeholders.province,this.currentProvince);return false;} else {this.areas = this.determineValue("city",this.currentCity,this.placeholders.city,this.currentProvince);}if (this.areas.length === 0) {this.emit("selected");this.tab = 2;this.showAreaTab = false;}},resetProvince() {this.tab = 1;this.provinces = this.getDistricts();this.showCityTab = false;this.showAreaTab = false;},resetCity() {this.tab = 2;this.showCityTab = true;this.showAreaTab = false;this.getCities();},chooseProvince(name) {this.currentProvince = name;if (this.onlyProvince) return;this.tab = 2;this.showCityTab = true;this.showAreaTab = false;this.getCities();},chooseCity(name) {this.currentCity = name;if (this.hideArea) return;this.tab = 3;this.showCityTab = true;this.showAreaTab = true;this.getAreas();},chooseArea(name) {this.currentArea = name;},getAreaCodeByPreCode(name, preCode) {let codes = [];for (let x in this.districts) {for (let y in this.districts[x]) {if (name === this.districts[x][y]) {codes.push(y);}}}if (codes.length > 1) {let index;codes.forEach((item, i) => {if ((preCode.length === 2 && item.slice(0, 2) === preCode) ||(preCode.length === 4 && item.slice(0, 4) !== preCode)) {index = i;}});return codes[index];} else {return codes[0];}},getAreaCode(name, check = "", type = "") {for (let x in this.districts) {for (let y in this.districts[x]) {if (name === this.districts[x][y]) {if (check.length > 0) {let code = y;if (check) {let preCode =type === "city"? this.getAreaCode(this.currentProvince).slice(0,2): y.slice(0, 2);code = this.getAreaCodeByPreCode(name, preCode);}if (!code || y.slice(0, 2) !== code.slice(0, 2)) {continue;} else {return code;}} else {return y;}}}}},getCodeValue(code) {for (let x in this.districts) {for (let y in this.districts[x]) {if (code === parseInt(y)) {return this.districts[x][y];}}}},getDistricts(code = DEFAULT_CODE) {return this.districts[code] || [];},determineValue(type, currentValue, placeholderValue, check = "") {if (currentValue === placeholderValue) {return [];} else {return this.getDistricts(this.getAreaCode(currentValue, check, type));}},determineType(value) {if (typeof value === "number") {return this.getCodeValue(value);}return value;},cleanList(name) {this[name] = [];},isDirectCity(province, city) {if (province && city) {return (this.determineType(this.province) === this.determineType(this.city));}return false;},},
};
</script><style lang="scss">
.distpicker-address-wrapper {color: #9caebf;select {padding: 0.5rem 0.75rem;height: 40px;font-size: 1rem;line-height: 1.25;color: #464a4c;background-color: #fff;background-image: none;-webkit-background-clip: padding-box;background-clip: padding-box;border: 1px solid rgba(0, 0, 0, 0.15);border-radius: 0.25rem;-webkit-transition: border-color ease-in-out 0.15s,-webkit-box-shadow ease-in-out 0.15s;transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;-o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s,-webkit-box-shadow ease-in-out 0.15s;option {font-weight: normal;display: block;white-space: pre;min-height: 1.2em;padding: 0px 2px 1px;}}ul {margin: 0;padding: 0;li {list-style: none;}}.address-header {background-color: #fff;ul {display: flex;justify-content: space-around;align-items: stretch;li {display: inline-block;padding: 10px 10px 7px;&.active {border-bottom: #52697f solid 3px;color: #52697f;}}}}.address-container {background-color: #fff;ul {height: 100%;overflow: auto;li {padding: 8px 10px;border-top: 1px solid #f6f6f6;&.active {color: #52697f;}}}}
}
.disabled-color {background: #f8f8f8;
}
</style>