如何使用 Vue 实现城市选择器?

广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买

如何使用 Vue 实现城市选择器?

近年来,前端技术不断地更新,前端框架的出现也让我们日常开发中效率得到很大的提升。在 Vue.js 的框架下,我们可以很容易地实现许多常用的功能组件,比如城市选择器

那么,如何在 Vue 中实现城市选择器呢?本篇文章将给大家分享一个简单的实现方法。

一、数据准备

在实现城市选择器之前,我们需要准备好城市数据。由于城市数据比较多,我们需要使用一个 JSON 数据格式来存储。在这里,我提供了一个 JSON 数据文件,大家可以在网上或其他资源中寻找。

城市数据文件样例:

[  {    "label": "北京市",    "value": "110000",    "children": [      {        "label": "北京市",        "value": "110100",        "children": [          {            "label": "东城区",            "value": "110101"          },          {            "label": "西城区",            "value": "110102"          },          {            "label": "崇文区",            "value": "110103"          },          ...        ]      }    ]  },  {    "label": "上海市",    "value": "310000",    "children": [      {        "label": "上海市",        "value": "310100",        "children": [          {            "label": "黄浦区",            "value": "310101"          },          {            "label": "徐汇区",            "value": "310104"          },          {            "label": "长宁区",            "value": "310105"          },          ...        ]      }    ]  },  ...]
登录后复制

二、选择器组件实现

2.1 引入城市数据

我们需要在组件的 script 部分中引入城市数据:

<script>  import cityData from './city-data.json';  export default {    // 组件属性和方法  }</script>
登录后复制

2.2 定义选择器组件

由于城市选择器可以用于多个地方,我们可以将它定义为一个组件。在这个组件中,我们需要定义一些属性和方法。

属性:

modelValue:当前选中的城市值;placeholder:选择器输入框中的提示语;width:选择器输入框的宽度;disabled:选择器是否禁用;readonly:选择器是否只读。

方法:

handleChangeCity:选中城市后的回调方法。
<template>  <div class="city-picker">    <input type="text" :readonly="readonly" :disabled="disabled" :placeholder="placeholder" :style="{width: width}" v-model="selectedCity">    <!-- 其他相关 DOM 结构 -->  </div></template><script>  import cityData from './city-data.json';  export default {    props: {      modelValue: {        type: String,        default: ''      },      placeholder: {        type: String,        default: '请选择城市'      },      width: {        type: String,        default: '200px'      },      disabled: {        type: Boolean,        default: false      },      readonly: {        type: Boolean,        default: false      }    },    data() {      return {        selectedCity: this.modelValue,        // 城市数据        cityData: []      }    },    methods: {      handleChangeCity(value) {        this.selectedCity = value;        // 触发父组件的 onChange 事件        this.$emit('onChange', value);      }    },    mounted() {      this.cityData = cityData;    }  }</script>
登录后复制

2.3 渲染城市数据

在选择器中显示城市数据需要进行递归渲染。在渲染时,我们需要定义一个函数,递归遍历每一层的城市数据。由于城市数据可能有多级,我们需要使用递归的方式进行遍历。在代码实现中,我们使用了 Vue 组件中定义的 template 的方式进行渲染。

<template>  <div>    <!-- 递归渲染省份数据 -->    <template v-for="province in cityData">      <div :key="province.value" class="province">        <div @click="handleShowCity(province)">{{ province.label }}</div>        <template v-if="province.children && province.children.length > 0">          <div v-show="province.showCity">            <!-- 递归渲染城市和区县数据 -->            <template v-for="city in province.children">              <div :key="city.value" class="city">                <div @click="handleShowDistrict(city)">{{ city.label }}</div>                <template v-if="city.children && city.children.length > 0">                  <div v-show="city.showDistrict">                    <div v-for="district in city.children" :key="district.value">{{ district.label }}</div>                  </div>                </template>              </div>            </template>          </div>        </template>      </div>    </template>  </div></template><script>  import cityData from './city-data.json';  export default {    props: {      modelValue: {        type: String,        default: ''      },      placeholder: {        type: String,        default: '请选择城市'      },      width: {        type: String,        default: '200px'      },      disabled: {        type: Boolean,        default: false      },      readonly: {        type: Boolean,        default: false      }    },    data() {      return {        selectedCity: this.modelValue,        // 城市数据        cityData: []      }    },    methods: {      handleShowCity(province) {        // 点击省份时,展开或关闭城市数据        province.showCity = !province.showCity;      },      handleShowDistrict(city) {        // 点击城市时,展开或关闭区县数据        city.showDistrict = !city.showDistrict;        // 选中城市后,调用 handleChangeCity 方法        this.handleChangeCity(city.label);      },      handleChangeCity(value) {        this.selectedCity = value;        // 触发父组件的 onChange 事件        this.$emit('onChange', value);      },      // 递归遍历城市数据,渲染出每一个层级的城市数据      renderCity(cityData) {        cityData.forEach(city => {          city.showDistrict = false;          if (city.children && city.children.length > 0) {            this.renderCity(city.children);            city.showCity = false;          }        })      }    },    mounted() {      this.cityData = cityData;      // 渲染城市数据      this.renderCity(this.cityData);    }  }</script>
登录后复制

2.4 完整选择器组件代码

最终的城市选择器组件代码如下所示:

<template>  <div class="city-picker">    <input type="text" :readonly="readonly" :disabled="disabled" :placeholder="placeholder" :style="{width: width}" v-model="selectedCity">    <!-- 城市选择器弹出框 -->    <div class="city-picker-modal" v-show="showModal">      <div class="city-picker-header">        <span>请选择城市</span>        <span class="close-icon" @click="handleCloseModal">&times;</span>      </div>      <div class="city-picker-body">        <!-- 渲染城市选择器树形结构 -->        <div class="city-picker-tree">          <div class="top-tab">            <div              :class="{ active: (activeTab === 'province') }"              @click="handleToggleTab('province')"            >省份</div>            <div              :class="{ active: (activeTab === 'city') }"              @click="handleToggleTab('city')"            >城市</div>            <div              :class="{ active: (activeTab === 'district') }"              @click="handleToggleTab('district')"            >区县</div>          </div>          <div class="tab-content">            <template v-if="activeTab === 'province'">              <!-- 渲染省份数据 -->              <template v-for="province in cityData">                <div :key="province.value" class="province">                  <div @click="handleShowCity(province)">{{ province.label }}</div>                  <template v-if="province.children && province.children.length > 0">                    <div v-show="province.showCity">                      <!-- 渲染城市数据 -->                      <template v-for="city in province.children">                        <div :key="city.value" class="city">                          <div @click="handleShowDistrict(city)">{{ city.label }}</div>                          <template v-if="city.children && city.children.length > 0">                            <div v-show="city.showDistrict">                              <!-- 渲染区县数据 -->                              <div v-for="district in city.children" :key="district.value">{{ district.label }}</div>                            </div>                          </template>                        </div>                      </template>                    </div>                  </template>                </div>              </template>            </template>            <template v-else-if="activeTab === 'city'">              <!-- 渲染城市数据 -->              <template v-for="province in cityData">                <template v-if="province.children && province.children.length > 0">                  <template v-for="city in province.children">                    <div :key="city.value" class="city">{{ city.label }}</div>                  </template>                </template>              </template>            </template>            <template v-else-if="activeTab === 'district'">              <!-- 渲染区县数据 -->              <template v-for="province in cityData">                <template v-if="province.children && province.children.length > 0">                  <template v-for="city in province.children">                    <template v-if="city.children && city.children.length > 0">                      <template v-for="district in city.children">                        <div :key="district.value">{{ district.label }}</div>                      </template>                    </template>                  </template>                </template>              </template>            </template>          </div>        </div>      </div>    </div>  </div></template><script>  import cityData from './city-data.json';  export default {    props: {      modelValue: {        type: String,        default: ''      },      placeholder: {        type: String,        default: '请选择城市'      },      width: {        type: String,        default: '200px'      },      disabled: {        type: Boolean,        default: false      },      readonly: {        type: Boolean,        default: false      }    },    data() {      return {        // 当前选中的城市        selectedCity: this.modelValue,        // 城市数据        cityData: [],        // 显示弹出框标志位        showModal: false,        // 当前显示的 tab 标签页        activeTab: 'province'      }    },    methods: {      // 选中省份时,展开或关闭城市数据      handleShowCity(province) {        province.showCity = !province.showCity;        this.activeTab = (province.showCity ? 'city' : 'province');      },      // 选中城市时,展开或关闭区县数据,并选中城市      handleShowDistrict(city) {        city.showDistrict = !city.showDistrict;        this.activeTab = (city.showDistrict ? 'district' : 'city');        this.selectedCity = city.label;        // 触发父组件 onChange 事件        this.$emit('onChange', city.label);        // 关闭弹出层        this.showModal = false;      },      // 切换 tab 标签页      handleToggleTab(tab) {        this.activeTab = tab;      },      // 关闭城市选择器弹窗      handleCloseModal() {        this.showModal = false;      }    },    mounted() {      this.cityData = cityData;      // 递归渲染城市数据,设置状态      this.cityData.forEach((province) => {        province.showCity = false;        if (province.children && province.children.length > 0) {          province.children.forEach((city) => {            city.showDistrict = false;          })        }      })    }  }</script>
登录后复制

三、使用城市选择器

在 Vue 项目中的使用城市选择器组件很简单,只需要在需要使用的页面中引入城市选择器组件,然后在使用时传入相应的参数即可。下面是使用代码示例:

<template>  <div>    <CityPicker      v-model="city"      :width="200"    ></CityPicker>  </div></template><script>  import CityPicker from './components/CityPicker';  export default {    components: {      CityPicker    },    data() {      return {        city: ''      }    },    methods: {      handleChangeCity(value) {        console.log('选中的城市为:', value);      }    }  }</script>
登录后复制

至此,我们已经可以在 Vue 应用中使用城市选择器组件了。这个城市选择器组件代码非常简单,但是实现了基本的城市选择功能,可以依照自己的需求进行扩展和优化。

以上就是如何使用 Vue 实现城市选择器?的详细内容,更多请关注9543建站博客其它相关文章!

广告:SSL证书一年128.66元起,点击购买~~~

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:微信小程序 页面跳转和数据传递
下一篇:vue怎么适配ios手机下面的小黑框

发表评论

关闭广告
关闭广告