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>
                        <option
                            v-for="(item, index) in cities"
                            :value="item"
                            :key="index"
                        >
                            {{ item }}
                        </option>
                    </select>
                </label>
                <label>
                    <select
                        v-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">
                        <li
                            v-if="showCityTab"
                            :class="{ active: tab === 2 }"
                            @click="resetCity"
                        >
                            {{
                                currentCity && !staticPlaceholder
                                    ? currentCity
                                    : placeholders.city
                            }}
                        </li>
                        <li
                            v-if="showAreaTab && !hideArea"
                            :class="{ active: tab === 3 }"
                        >
                            {{
                                currentArea && !staticPlaceholder
                                    ? currentArea
                                    : placeholders.area
                            }}
                        </li>
                    </template>
                </ul>
            </div>
            <div :class="addressContainer">
                <ul v-if="tab === 1">
                    <li
                        v-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">
                        <li
                            v-for="(item, index) in cities"
                            :class="{ active: item === currentCity }"
                            @click="chooseCity(item)"
                            :key="index"
                        >
                            {{ item }}
                        </li>
                    </ul>
                    <ul v-if="tab === 3 && !hideArea">
                        <li
                            v-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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值