姜堰区网站建设,境外网站,手机网络不好怎么回事但信号是满的,进出口代理公司城市选择-基本功能 能够封装城市选择组件#xff0c;并且完成基础的显示隐藏的交互功能 #xff08;1#xff09;封装通用组件src/components/city/index.vue
script langts setup nameCity/script
templatediv class…城市选择-基本功能 能够封装城市选择组件并且完成基础的显示隐藏的交互功能 1封装通用组件src/components/city/index.vue
script langts setup nameCity/script
templatediv classcitydiv classselectspan classplaceholder请选择配送地址/spanspan classvalue/spani classiconfont icon-angle-down/i/divdiv classoptionspan classellipsis v-fori in 24 :keyi北京市/span/div/div
/templatestyle scoped langless
.city {display: inline-block;position: relative;z-index: 400;.select {border: 1px solid #e4e4e4;height: 30px;padding: 0 5px;line-height: 28px;cursor: pointer;.active {background: #fff;}.placeholder {color: #999;}.value {color: #666;font-size: 12px;}i {font-size: 12px;margin-left: 5px;}}.option {width: 542px;border: 1px solid #e4e4e4;position: absolute;left: 0;top: 29px;background: #fff;min-height: 30px;line-height: 30px;display: flex;flex-wrap: wrap;padding: 10px; span {width: 130px;text-align: center;cursor: pointer;border-radius: 4px;padding: 0 3px;:hover {background: #f5f5f5;}}}
}
/style全局注册
import XtxCity from /components/city/index.vue
export default {install(app: App) {app.component(City, City)},
}提供类型 src/global.d.ts
import XtxCity from /components/city/index.vue
declare module vue {City: typeof City}
}2在商品详情组件中渲染city组件 src/views/goods/components/goods-name.vue
dldt配送/dtdd至 City/City/dd
/dl3控制城市的显示和隐藏 点击的时候切换省市区的样式切换城市弹层的显示或隐藏 script langts setup nameCityimport { ref } from vue
const active ref(false)
const toggle () {active.value !active.value
}
/scripttemplatediv classcitydiv classselect clicktoggle :class{ active: active }span classplaceholder请选择配送地址/spanspan classvalue/spani classiconfont icon-angle-down/i/divdiv classoption v-showactivespan classellipsis v-fori in 24 :keyi北京市/span/div/div
/template4点击弹层外部关闭弹层
script langts setup
import { ref } from vue
import { onClickOutside } from vueuse/core
const active ref(false)
const toggle () {active.value !active.value
}
// 点击外面关闭弹窗
const target ref(null)
onClickOutside(target, () {
// 参数1监听哪个元素,target是通过ref绑定给我们监听盒子的
// 参数2点击了该元素外其他地方触发的函数active.value false
})
/script
templatediv classcity reftargetdiv classselect clicktoggle :class{ active: active }span classplaceholder请选择配送地址/spanspan classvalue/spani classiconfont icon-angle-down/i/divdiv classoption v-ifactivespan classellipsis v-fori in 24 :keyi北京市/span/div/div
/template城市选择-动态渲染
需求完成城市数据的获取以及渲染
注意
城市数据并不是直接从接口服务器中获取的而是从阿里云服务器上获取的数据所以不能使用封装好的request发送请求直接使用 原生的axios 发送请求即可。https://yjy-oss-files.oss-cn-zhangjiakou.aliyuncs.com/tuxian/area.jsonopen in new window
1定义数据类型
// 城市列表类型
export type AreaList {code: stringlevel: numbername: stringareaList: AreaList[]
}2获取数据src/components/city/index.vue 需求: 从接口获取城市数据赋值给本地数据 定义列表数据变量 const cityList refAreaList[]([])封装调接口的方法方法内部调用接口把获取到的结果赋值给cityList调用方法 script langts setup nameCity
import { ref } from vue
import { onClickOutside } from vueuse/core
import type { AreaList } from /types/goods
import axios from axios
// 控制弹层的显示隐藏
const active ref(false)
const toggle () {active.value !active.value
}
const target ref(null)
onClickOutside(target, (e) {// console.log(e)// 当点击target元素的外面的时候就会触发active.value false
})const cityList refAreaList[]([])
const getCityList async () {const res await axios.getAreaList[](https://yjy-oss-files.oss-cn-zhangjiakou.aliyuncs.com/tuxian/area.json)cityList.value res.data
}
getCityList()
/script3渲染数据src/components/City/index.vue
templatediv classcity reftargetdiv classselect :class{ active: active } clicktogglespan classplaceholder请选择配送地址/spanspan classvalue/spani classiconfont icon-angle-down/i/divdiv classoption v-showactivespan classellipsis v-foritem in cityList :keyitem.code{{ item.name }}/span/div/div
/template4点击弹层外部关闭弹层
script langts setup
import { ref } from vue
import { onClickOutside } from vueuse/core
const active ref(false)
const toggle () {active.value !active.value
}
// 点击外面关闭弹窗
const target ref(null)
onClickOutside(target, () {
// 参数1监听哪个元素,target是通过ref绑定给我们监听盒子的
// 参数2点击了该元素外其他地方触发的函数active.value false
})
/script
templatediv classcity reftargetdiv classselect clicktoggle :class{ active: active }span classplaceholder请选择配送地址/spanspan classvalue/spani classiconfont icon-angle-down/i/divdiv classoption v-ifactivespan classellipsis v-fori in 24 :keyi北京市/span/div/div
/template城市选择-交互逻辑 需求 点击选择省市区的时候能够把省市区数据存储起来 根据点击的每一个节点的level决定他应该存储到省/城/区的哪个下面点击的时候需要把当前弹层城市信息替换为当前点击节点的子节点的城市信息点击省显示市点击市显示县如果点击的是区的节点则需要关弹层如果中途点击了关闭弹层则需要重置城市数据 点击某个省显示省下面的市。点击市显示市下面的县。 根据level判断级别。 1给城市注册点击事件
div classoption v-ifactivespanclassellipsisv-foritem in cityList:keyitem.codeclickselectCity(item){{ item.name }}/span
/div2城市切换逻辑
// 选择城市
const changeResult ref({provinceCode: ,provinceName: ,cityCode: ,cityName: ,countyCode: ,countyName:
})const selectCity (city: AreaList) {if (city.level 0) {// 省changeResult.value.provinceName city.namechangeResult.value.provinceCode city.codecityList.value city.areaList}if (city.level 1) {// 市changeResult.value.cityName city.namechangeResult.value.cityCode city.codecityList.value city.areaList}if (city.level 2) {// 县区changeResult.value.countyName city.namechangeResult.value.countyCode city.code// 关闭弹窗active.value false}
}3关闭时恢复城市数据
const cityList refAreaList[]([])
const cacheList refAreaList[]([])const getCityData async () {const {data:res} await axios.getAreaListObj[](https://yjy-oss-files.oss-cn-zhangjiakou.aliyuncs.com/tuxian/area.json)cityList.value rescacheList.value res
}
getCityData()// 监听关闭弹窗的处理恢复数据
watch(active, (value) {// 当关闭active的时候需要回复数据if (!value) {cityList.value cacheList.value}
})城市选择-完整地址处理 需求描述 默认展示的配送地址需要从父组件传递过来(登录的用户可以拿到当前用户的默认配送地址)子组件选择完省市区需要传递给父组件由父组件组织数据传给子组件进行展示默认展示配送地址的数据源在父组件 注意完整地址需要父组件传递给子组件将来如果登录的用户父组件可以获取到完整的地址。 1父组件将城市数据传递给子组件
script langts setup
const userAddress ref(江西省 九江市 不知道县)
/scriptCity :userAddressuserAddress/City/dd2子组件接收并且进行展示 注意点:具体的地址和请选择配送同时只展示一个 defineProps{userAddress?: string
}()div classselect clicktoggle :class{ active }span classvalue v-ifuserAddress{{ userAddress }}/spanspan classplaceholder v-else请选择配送地址/spani classiconfont icon-angle-down/i
/div3子组件选择完城市需要将数据传递给父组件
// 选择的城市结果类型
export type CityResult {provinceCode: stringprovinceName: stringcityCode: stringcityName: stringcountyCode: stringcountyName: string
}const changeResult refPartialCityResult({})const emit defineEmits{(e: changeCity, value: CityResult): void
}()const selectCity (city: AreaList) {if (city.level 0) {// 省changeResult.value.provinceName city.namechangeResult.value.provinceCode city.codecityList.value city.areaList}if (city.level 1) {// 市changeResult.value.cityName city.namechangeResult.value.cityCode city.codecityList.value city.areaList}if (city.level 2) {// 县区changeResult.value.countyName city.namechangeResult.value.countyCode city.code// 关闭弹窗active.value false// 子传父emit(changeCity, changeResult.value)}
}优化代码可选
const changeResult refPartialCityResult({})
// record接受两个泛型参数第一个为对象key的类型第二个为对象值的类型
const cityMap: Recordnumber, province | city | county {0: province,1: city,2: county
}
const selectedCity (city: AreaList) {changeResult.value[${cityMap[city[level]]}Name] city.namechangeResult.value[${cityMap[city[level]]}Code] city.codeif (city.level 2) {setIsShowCity(false)emits(changeCity, changeResult.value)} else {cityList.value city.areaList}
}4父组件接受数据并且处理
dldt配送/dtdd至XtxCitychangeCitychangeCity:fullPathfullPath/XtxCity/dd
/dlconst userAddress ref(江西省 九江市 不知道县)
const changeCity (changeResult: CityResult) {userAddress.value changeResult.provinceName changeResult.cityName changeResult.countyName
}
, changeResult.value)} else {cityList.value city.areaList}
}4父组件接受数据并且处理
dldt配送/dtdd至XtxCitychangeCitychangeCity:fullPathfullPath/XtxCity/dd
/dlconst userAddress ref(江西省 九江市 不知道县)
const changeCity (changeResult: CityResult) {userAddress.value changeResult.provinceName changeResult.cityName changeResult.countyName
}