当前位置: 首页 > news >正文

网络制作公司专业制作网站三个好消息

网络制作公司专业制作网站,三个好消息,温州建设网站,上海高端工作室网站在日常前端开发中,地址选择器是非常常见的功能,尤其是包含“省、市、区”三级联动的组件。借助 china-region 这个库,我们可以非常轻松地实现这一需求,并与 Vue3 组件系统自然集成。本文将带你一步步构建一个带有回显功能的省市区…

在日常前端开发中,地址选择器是非常常见的功能,尤其是包含“省、市、区”三级联动的组件。借助 china-region 这个库,我们可以非常轻松地实现这一需求,并与 Vue3 组件系统自然集成。本文将带你一步步构建一个带有回显功能的省市区选择器。

技术栈

  • Vue 3 + <script setup>
  • TypeScript
  • china-region(省市区数据)
  • 自定义 Select 组件(来自 shadcn-vue,可以根据需要选用)

需求描述

一个三级联动的选择器,用户选择省份后自动加载对应城市,选择城市后再加载对应的区县。更改省级或市级的选择时,其下的选择器也能对应的清空值并且获取新的选取列表。同时支持通过 props 设置默认选中项。


依赖安装

npm install china-region

编写组件

1. 基础数据和 Props 接收

const props = defineProps<{province?: string;city?: string;district?: string;
}>();const provinces = ref(getProvinces());
const selectedProvince = ref(props.province || "");
const selectedCity = ref(props.city || "");
const selectedDistrict = ref(props.district || "");

支持外部传入 默认选中省市区,非常适合做表单回显。


2. 响应式联动逻辑

监听省份,更新城市
watch(selectedProvince, (newProvince) => {selectedCity.value = "";selectedDistrict.value = "";if (newProvince) {// 因为输入框的value被绑定为了地区名称,而getPrefectures函数只接收行政区号,所以这里需要先根据省份名称获取行政区号const provinceCode = getCodeByProvinceName(newProvince);cities.value = getPrefectures(provinceCode);if (props.city) {const targetCity = cities.value.find((city) => city.name === props.city);if (targetCity) selectedCity.value = props.city;}} else {cities.value = [];}
}, { immediate: true });
监听城市,更新区县
watch(selectedCity, (newCity) => {selectedDistrict.value = "";if (newCity) {// china-region没有提供根据城市名获取行政区号的函数,所以只能在cities中查找到与newcity同名的城市的区号const cityCode = cities.value.find((item) => item.name === newCity)?.code;districts.value = getCounties(cityCode);if (props.district) {const targetDistrict = districts.value.find((district) => district.name === props.district,);if (targetDistrict) selectedDistrict.value = props.district;}} else {districts.value = [];}
}, { immediate: true });

3. 输出选中地址

const selectedRegion = computed(() => {
// 可以根据需要返回相对应的数据格式,这里的数据格式为字符串,示例:中国,浙江省,杭州市,西湖区return `中国,${selectedProvince.value},${selectedCity.value},${selectedDistrict.value}`;
});defineExpose({ selectedRegion });

在父组件可以通过 ref 引用组件,拿到完整的地址信息。


模板部分(UI)

<template><div><div class="text-sm">地区选择</div><div class="flex gap-4"><!-- 省 --><Select v-model="selectedProvince"><SelectTrigger class="w-[100px]"><SelectValue placeholder="请选择省份" /></SelectTrigger><SelectContent class="h-60"><!-- china-region返回的数据结构也支持使用行政区号,这里使用了地区名称--><SelectItemv-for="item in provinces":key="item.name":value="item.name">{{ item.name }}</SelectItem></SelectContent></Select><!-- 市 --><Select v-model="selectedCity" :disabled="!selectedProvince || !cities.length"><SelectTrigger class="w-[100px]"><SelectValue placeholder="请选择城市" /></SelectTrigger><SelectContent class="h-60"><SelectItemv-for="item in cities":key="item.name":value="item.name">{{ item.name }}</SelectItem></SelectContent></Select><!-- 区 --><Select v-model="selectedDistrict" :disabled="!selectedCity"><SelectTrigger class="w-[100px]"><SelectValue placeholder="请选择区县" /></SelectTrigger><SelectContent class="max-h-60"><SelectItemv-for="item in districts":key="item.name":value="item.name">{{ item.name }}</SelectItem></SelectContent></Select></div></div>
</template>

这里的样式简单的使用了Tailwind Css,也可以根据需要加入自定义的样式


完整的组件代码

<script setup lang="ts">
import { ref, computed, watch } from "vue";
import {Select,SelectContent,SelectItem,SelectTrigger,SelectValue,
} from "@/components/ui/select";
import {getProvinces,getPrefectures,getCounties,getCodeByProvinceName,
} from "china-region";// 1. 接收父组件的 `props`
const props = defineProps<{province?: string;city?: string;district?: string;
}>();// 2. 省份数据
const provinces = ref(getProvinces());
const selectedProvince = ref(props.province || "");
const selectedCity = ref(props.city || "");
const selectedDistrict = ref(props.district || "");
const cities = ref([]);
const districts = ref([]);// 3. 监听 `selectedProvince`,更新 `cities` 并恢复 `props.city`
watch(selectedProvince,(newProvince) => {selectedCity.value = "";selectedDistrict.value = "";if (newProvince) {const provinceCode = getCodeByProvinceName(newProvince);cities.value = getPrefectures(provinceCode);// 如果 `props.city` 存在,并且 `cities` 里有这个城市,则选中if (props.city) {const targetCity = cities.value.find((city) => city.name === props.city,);if (targetCity) {selectedCity.value = props.city;}}} else {cities.value = [];}},{ immediate: true },
);// 4. 监听 `selectedCity`,更新 `districts` 并恢复 `props.district`
watch(selectedCity,(newCity) => {selectedDistrict.value = "";if (newCity) {const cityCode = cities.value.find((item) => item.name === newCity).code;districts.value = getCounties(cityCode);// 如果 `props.district` 存在,并且 `districts` 里有这个区县,则选中if (props.district) {const targetDistrict = districts.value.find((district) => district.name === props.district,);if (targetDistrict) {selectedDistrict.value = props.district;}}} else {districts.value = [];}},{ immediate: true },
);// 5. 监听 `props` 变化,确保 `props.city` 和 `props.district` 正确赋值
watch(() => props.province,(newVal) => {if (newVal) {selectedProvince.value = newVal;}},
);
watch(() => props.city,(newVal) => {if (newVal && cities.value.some((city) => city.name === newVal)) {selectedCity.value = newVal;}},
);
watch(() => props.district,(newVal) => {if (newVal &&districts.value.some((district) => district.name === newVal)) {selectedDistrict.value = newVal;}},
);// 6. 计算选中的地区
const selectedRegion = computed(() => {return `中国,${selectedProvince.value},${selectedCity.value},${selectedDistrict.value}`;
});// 7. 让父组件可以访问选中的数据
defineExpose({selectedRegion,
});
</script><template><div><div class="text-sm">工作地区</div><!-- 省份选择 --><div class="flex gap-4"><Select v-model="selectedProvince"><SelectTrigger class="w-[100px]"><SelectValue placeholder="请选择省份" /></SelectTrigger><SelectContent class="h-60"><SelectItemv-for="item in provinces":key="item.name":value="item.name">{{ item.name }}</SelectItem></SelectContent></Select><!-- 城市选择 --><Selectv-model="selectedCity":disabled="!selectedProvince || !cities.length"><SelectTrigger class="w-[100px]"><SelectValue placeholder="请选择城市" /></SelectTrigger><SelectContent class="h-60"><SelectItemv-for="item in cities":key="item.name":value="item.name">{{ item.name }}</SelectItem></SelectContent></Select><!-- 区县选择 --><Select v-model="selectedDistrict" :disabled="!selectedCity"><SelectTrigger class="w-[100px]"><SelectValue placeholder="请选择区县" /></SelectTrigger><SelectContent class="max-h-60"><SelectItemv-for="item in districts":key="item.name":value="item.name">{{ item.name }}</SelectItem></SelectContent></Select></div></div>
</template>

总结

本组件的优势:

  • 使用 china-region 获取权威行政区域数据;
  • 响应式联动逻辑清晰;
  • 支持外部 props 赋值,方便做表单回显;
  • 使用 defineExpose 暴露接口,增强复用性。

这个组件可以作为表单组件的基础模块,配合表单校验、提交逻辑后非常实用。


这个组件只实现了最简单的三级地区选择以及回显,下一步可以尝试:

  • 添加“清空选择”按钮;
  • 使用 pinia 等状态管理库联动其他表单项。

如果你觉得这篇文章对你有帮助,欢迎点赞收藏!有问题也欢迎留言讨论!

http://www.dtcms.com/a/408828.html

相关文章:

  • 兰州做网站官方网站建设网站
  • 网站建设深圳官网yy传媒
  • 织梦网站栏目无法生成wordpress建站有广告吗
  • ps网站参考线怎么做wordpress博客 houdini
  • 网站建设评审意见怎样做网站表白墙
  • google网站怎么做流量织梦网站安装dir
  • 地方网站娄底企业网站建设公司
  • 做张家界旅游网站多少钱淘宝网首页电脑版登录入口
  • 网站维护和建设工作范围中小企业网站建设与管理
  • 室内设计案例去什么网站网站开发 项目式说课
  • 网站的规划 建设与分析论文山东网站建站系统平台
  • 网站怎么做定时任务做网上营销怎样推广
  • 做网站编写代码电商平台开发系统
  • 搜狐快站做淘宝客网站有哪些网站做返利模式
  • 网站免费源码大全不用下载手机seo快速排名
  • wordpress企业网站制作视频教程md短视频传媒免费版怎么下载
  • 网站登录账号密码保存深圳罗湖商城网站建设
  • 免费的好网站潍坊做网页的公司
  • 厦门 网站开发新的网站做淘宝客
  • php p2p网站开发网站建设开发费会计处理
  • 深圳市网站设计公做网站搞流量
  • 我的网站要怎样做才能让人家搜到建设公司企业简介
  • 安全的南昌网站制作APP和网站是一样吗
  • phpcms 恢复网站桂林象鼻山
  • 购物网站怎么做代码怎么在中国做网站网站
  • 自适应网站功能公司宣传页设计印刷
  • 建设门户网站都需要什么意思企业内部管理信息系统
  • 网站开发流行工具官方网站的资料做证据
  • 广州营销型网站建设怎么样百度快照 直接进入网站
  • 如何寻找建设网站的公司专业做农牧应聘的网站