草庐IT

省市区选择器

五号社会好青年 2023-03-28 原文

一、巧用watch来达到三级联动效果

1.在component文件夹下创建文件夹chooseArea,创建对应文件
2.在views下面注册组件,然后在router下面配置路由

{
      path:'/chooseArea',
      component:() => import('../views/chooseArea/index.vue'
 },

3.从github下载所需要的省市区数据


area2.png
area3.png
这里使用的是省市区三级联动数据,带编码的pca-code-json文件

4.代码

<template>
    <div>
       <el-select clearable  placeholder="请选择省份" v-model="province">
            <el-option v-for="item in areas" :key="item.code" :value="item.name" :lable="item.name"></el-option>
       </el-select>
       <el-select clearable  :disabled="!province" style="margin:0 20px" placeholder="请选择城市" v-model="city">
            <el-option v-for="item in selectCity" :key="item.code" :value="item.name" :lable="item.name"></el-option>
       </el-select>
       <el-select clearable  :disabled="!province || !city"   placeholder="请选择区域" v-model="area">
            <el-option v-for="item in selectArea" :key="item.code" :value="item.name" :lable="item.name"></el-option>
       </el-select>
    </div>
</template>

<script lang="ts" setup>
import { computed, ref,watch } from 'vue'
import allAreas from '../lib/pca-code.json'


// 下拉框选择省份的值
let province = ref<string>('')
// 下拉选择城市的值
let city = ref<string>('')
// 下拉选择区域的值
let area = ref<string>('')
// 所有的省市区数据
let areas = ref(allAreas)

// 城市下拉框所有的值
let selectCity = ref<any[]>([])

// 区域下拉框所有的值
let selectArea = ref<any>([])


// 监听选择省份
watch(()=>province.value,val =>{
    if(val){
        let cities = areas.value.find(item => item.name === province.value)!.children
        selectCity.value = cities
    }
    city.value = ''
    area.value = ''
})
// 监听选择城市
watch(()=>city.value,val =>{
    if(val){
        let area = selectCity.value.find(item => item.name === city.value)!.children
        selectArea.value = area
    }
    area.value = ''
})

</script>

<style lang="scss" scoped>

</style>

二、完善省市区组件并给父组件分发事件

1.创建接口并导出

export interface AreaItem{
    name:string,
    code:string,
    children?:AreaItem[]
}

export interface Data{
    name:string,
    code:string
}

2.分发事件给父组件

let emits = defineEmits(['change'])

3.监听选择区域

watch(()=>area.value,val => {
    if(val){
        let provinceData:Data ={
            name:province.value,
            code: province.value && allAreas.find(item => item.name === province.value)!.code
        }
        let cityData:Data = {
            name:city.value,
            code:city.value && selectCity.value.find(item => item.name === city.value)!.code
        }
        let areaData:Data = {
            name:val,
            code:val && selectArea.value.find(item => item.name === val)!.code
        }
        // console.log(provinceData,cityData,areaData);
        emits('change',{
            province:provinceData,
            city:cityData,
            area:areaData
        })
    }
})

4.在注册的父组件中,引入事件
views/chooseArea/index.vue

<template>
    <div>
        <m-choose-area @change="changeArea"></m-choose-area>
    </div>
</template>

<script lang="ts" setup>
import mChooseArea from '../../components/chooseArea/src/index.vue';
let changeArea = (val:any) => {
    console.log(val);
}

</script>

三、完整代码

components/chooseArea/src/index.vue

<!--
 * @Author: error: git config user.name && git config user.email & please set dead value or install git
 * @Date: 2022-06-09 14:30:50
 * @LastEditors: error: git config user.name && git config user.email & please set dead value or install git
 * @LastEditTime: 2022-06-09 19:04:18
 * @FilePath: \mm-components\src\components\chooseArea\src\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
    <div>
       <el-select clearable  placeholder="请选择省份" v-model="province">
            <el-option v-for="item in areas" :key="item.code" :value="item.name" :lable="item.name"></el-option>
       </el-select>
       <el-select clearable  :disabled="!province" style="margin:0 20px" placeholder="请选择城市" v-model="city">
            <el-option v-for="item in selectCity" :key="item.code" :value="item.name" :lable="item.name"></el-option>
       </el-select>
       <el-select clearable  :disabled="!province || !city"   placeholder="请选择区域" v-model="area">
            <el-option v-for="item in selectArea" :key="item.code" :value="item.name" :lable="item.name"></el-option>
       </el-select>
    </div>
</template>

<script lang="ts" setup>
import { computed, ref,watch } from 'vue'
import allAreas from '../lib/pca-code.json'

export interface AreaItem{
    name:string,
    code:string,
    children?:AreaItem[]
}

export interface Data{
    name:string,
    code:string
}

// 下拉框选择省份的值
let province = ref<string>('')
// 下拉选择城市的值
let city = ref<string>('')
// 下拉选择区域的值
let area = ref<string>('')
// 所有的省市区数据
let areas = ref(allAreas)

// 城市下拉框所有的值
let selectCity = ref<AreaItem[]>([])

// 区域下拉框所有的值
let selectArea = ref<AreaItem[]>([])

// 分发事件给父组件
let emits = defineEmits(['change'])

// 监听选择省份
watch(()=>province.value,val =>{
    if(val){
        let cities = areas.value.find(item => item.name === province.value)!.children
        selectCity.value = cities
    }
    city.value = ''
    area.value = ''
})
// 监听选择城市
watch(()=>city.value,val =>{
    if(val){
        let area = selectCity.value.find(item => item.name === city.value)!.children!
        selectArea.value = area
    }
    area.value = ''
})
// 监听选择区域
watch(()=>area.value,val => {
    if(val){
        let provinceData:Data ={
            name:province.value,
            code: province.value && allAreas.find(item => item.name === province.value)!.code
        }
        let cityData:Data = {
            name:city.value,
            code:city.value && selectCity.value.find(item => item.name === city.value)!.code
        }
        let areaData:Data = {
            name:val,
            code:val && selectArea.value.find(item => item.name === val)!.code
        }
        // console.log(provinceData,cityData,areaData);
        emits('change',{
            province:provinceData,
            city:cityData,
            area:areaData
        })
    }
    
})
</script>

<style lang="scss" scoped>

</style>

四、界面效果

省市区选择器.png
点击省选择器上的取消可以全部清除区域,点击市级选择器上的小叉叉可以清除市级和区级的内容,选择区级的小叉叉只能清除区级内容,重新选择时下级的内容也会全部清除,跟我们平时一些软件网页的选择器是一样的效果。

有关省市区选择器的更多相关文章

  1. ruby - Rails 3 的 RGB 颜色选择器 - 2

    状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基

  2. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  3. ruby-on-rails - Rails 单选按钮 - 模型中多列的一种选择 - 2

    我希望用户从一个模型的三个选项中选择一个。即我有一个模型视频,可以被评为正面/负面/未知目前我有三列bool值(pos/neg/unknown)。这是处理这种情况的最佳方式吗?为此,表单应该是什么样的?目前我有类似的东西但显然它允许多项选择,而我试图将它限制为只有一个..怎么办? 最佳答案 如果要使用字符串列,让我们说rating。然后在你的表单中:#...#...它只允许一个选择编辑完全相同但使用radio_button_tag: 关于ruby-on-rails-Rails单选按钮-模

  4. ruby-on-rails - CarrierWave - PDF - 只选择第一页 - 2

    我的Rails应用程序中安装了carrierwave。但是,当用户上传多页pdf时,我只希望应用程序获取文档中的第一页并将其转换为jpeg。这可能吗?用什么命令?这是我的uploader。#encoding:utf-8classImageUploader[200,300]##defscale(width,height)##dosomething#end#Createdifferentversionsofyouruploadedfiles:version:thumbdoprocess:resize_to_fill=>[150,210]process:convert=>:jpgdefful

  5. ruby-on-rails - ActiveAdmin 自定义选择过滤器下拉名称 - 2

    对于用户模型,我有一个过滤器来检查用户的预订状态,该状态由整数值(0、1或2)表示。UserActiveAdmin索引页上的过滤器是通过以下代码实现的:filter:booking_status,as::select然而,这会导致下拉选项为0、1或2。当管理员用户从下拉列表中选择它们时,我更愿意自己将它们命名为“未完成”、“待定”和“已确认”之类的名称。有没有办法在不改变booking_status在模型中的表示方式的情况下做到这一点? 最佳答案 假设booking_status是模型中的枚举字段,您可以使用:过滤器:booking

  6. ruby-on-rails - 多次选择一个随机数,但绝不会两次选择相同的随机数 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:HowdoIgeneratealistofnuniquerandomnumbersinRuby?我想做的事:Random.rand(0..10).timesdoputsRandom.rand(0..10)end但如果随机数已经显示过,则无法再次显示。如何最轻松地做到这一点?

  7. ruby - mixin方法名冲突时如何选择调用方法? - 2

    当你在类中包含方法名冲突的模块时,它会使用类定义的方法。有没有办法选择我想运行的?moduleBdefself.hello"helloB"endendclassAincludeBdefself.hello"helloA"endendA.hello#=>thisprints"helloA",whatifIwant"helloB"? 最佳答案 Ben,当你在Ruby中调用一个方法(比如hello)时,会发生以下情况:如果接收者的特征类有一个名为hello的方法,它将被调用。如果不是:如果接收者的类有一个名为hello的实例方法,它将被调

  8. ruby - 更快的 n 选择 k 来组合数组 ruby - 2

    在尝试解决“网格上的路径”问题时,我编写了代码defpaths(n,k)p=(1..n+k).to_ap.combination(n).to_a.sizeend代码工作正常,例如ifn==8andk==2代码返回45,这是正确的路径数。但是,当使用较大的数字时,代码非常慢,我正在努力想出如何加快这个过程。 最佳答案 与其构建组合数组只是为了计算它,不如编写function定义组合的数量。我敢肯定还有包含此功能和许多其他组合函数的gem。请注意,我使用的是gemDistribution对于Math.factorial方法,但这是另一种

  9. ruby - 选择包含子节点内文本的父节点 - 2

    基本上我想选择一个节点(div),其中它的子节点(h1,b,h3)包含指定的文本。Childtext1Childtext2...Childtext3我期待的是/html/div/而不是/html/div/h1我在下面有这个,但不幸的是返回了child,而不是div的xpath。expression="//div[contains(text(),'Childtext1')]"doc.xpath(expression)我期待的是/html/div/而不是/html/div/h1那么有没有一种方法可以简单地使用xpath语法来做到这一点? 最佳答案

  10. ruby - Nokogiri 'not' 选择器 - 2

    Nokogiri中是否有一种方法可以选择所有与选择器不匹配的元素。在jQuery中我会使用::not(*[@class='someclass'])但是下面的代码给我一个xpath语法错误dom=Nokogiri::HTML(@file)dom.css(":not(*[@class='someclass'])") 最佳答案 InCSS3,:not()takesaselectorlikeanyother,所以它会是:dom.css(":not(.someclass)")(未经测试,但选择器是正确的)

随机推荐