之前项目要做一个城市选择下拉菜单 ,类似携程网旅游类的,但是网上搜了一下很少有满意的,就自己在网上找了一个JSON文件,封装了一个,UI效果都很不错,应用场景不同,所以封装的比较简单,如果应用复杂场景,可在代码上修改。
<template>
<div>
<el-select ref="select_focus" style="width: 100%;" :filterable="false" @remove-tag="()=>{this.$parent.btn_focus = true} " class="tabone_from_select" @focus="()=>{this.$parent.btn_focus = true} "
v-model="address_data" multiple placeholder="请选择">
<div class="jt_city_header">
<div class="jt_city_header_tit">
以拼音首字母排列 <i @click="close_select" title="关闭" class="el-icon-close"></i>
</div>
<div class="jt_city_header_num">
<div @click="jtChangeTab(1)" :class="{'jt_city_act': city_act == 1}">热门</div>
<div @click="jtChangeTab(2)" :class="{'jt_city_act': city_act == 2}">ABCD</div>
<div @click="jtChangeTab(3)" :class="{'jt_city_act': city_act == 3}">EFGH</div>
<div @click="jtChangeTab(4)" :class="{'jt_city_act': city_act == 4}">JKLM</div>
<div @click="jtChangeTab(5)" :class="{'jt_city_act': city_act == 5}">NOPQRS</div>
<div @click="jtChangeTab(6)" :class="{'jt_city_act': city_act == 6}">TUVWX</div>
<div @click="jtChangeTab(7)" :class="{'jt_city_act': city_act == 7}">YZ</div>
</div>
</div>
<div class="jt_city_header_body scroll_box scroll_box_aside_background_yellow">
<div class="jt_city_body_num" v-show="chane_cityList.includes(item.initial)" v-for="(item,index) in cityData" :key="index">
<div class="jt_city_body_num_info" v-show="item.initial !='996'">{
{
item.initial}}</div>
<div class="jt_city_body_name">
<el-option v-for="(c_item,c_index) in item.list" :key="c_index" :label="c_item.name" :value="c_item.name">
<div>{
{
c_item.name}}</div>
</el-option>
</div>
</div>
</div>
</el-select>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: "tabnumOne",
data() {
return {
city_act: 1,
cityData: [],
chane_cityList: ['996'],
};
},
props: ["demoCityData"],
computed: {
address_data: {
get() {
let address_data = []
if (this.demoCityData) {
if (typeof this.demoCityData == 'string') {
address_data.push(this.demoCityData)
} else {
address_data = this.demoCityData
}
return address_data
} else {
return []
}
},
set(v) {
if (v.length > 5) {
return this.$message('最多选择5个目的地!')
}
if (v.length < 1) {
return this.$message('至少选择一个目的地!')
}
// this.$emit("update:demoCityData",v);
this.$bus.$emit("setBusCityData", v);
// this.$parent.setCityData(v)
// this.demoCityData = v
}
},
},
created() {
axios.get("https://qn-album.meetb.cn/journeycity%281%29.json").then((resp) => {
this.cityData = resp.data.city
})
},
methods: {
close_select(){
this.$nextTick(() => {
this.$refs.select_focus.blur()
})
},
jtChangeTab(num) {
this.chane_cityList = []
setTimeout(_ => {
this.city_act = num
switch (num) {
case 1:
this.chane_cityList = ['996']
break;
case 2:
this.chane_cityList = ['A', "B", "C", "D"]
break;
case 3:
this.chane_cityList = ['E', "F", "G", "H"]
break;
case 4:
this.chane_cityList = ['J', "K", "L", "M"]
break;
case 5:
this.chane_cityList = ['N', "O", "P", "Q", "R", "S"]
break;
case 6:
this.chane_cityList = ['T', "U", "V", "W", "X"]
break;
case 7:
this.chane_cityList = ['Y', "Z"]
break;
default:
return
break;
}
}, 10)
},
}
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/journey/journeyTabNum/oneselectCity";
.scroll_box_aside_background_yellow::-webkit-scrollbar-track {
background: #ffffff !important;
}
/deep/ .el-tag.el-tag--info{
border: none;
background-color: f2f2f2;
}
/deep/ .el-tag--small{
line-height: 24px;
}
/deep/ .el-select .el-tag__close.el-icon-close{
right: -4px;
font-size: 16px;
color: #696969;
background-color: rgba(235,235,235,1);
&:hover{
background-color: #333333;
color: #FFFFFF;
}
}
</style>
引入的css 文件代码 oneselectCity.css
@charset "UTF-8";
/deep/ .el-select-dropdown__item {
margin-bottom: 0px;
margin-right: 5px;
}
/deep/ .el-select__tags-text {
font-size: 12px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #000000;
}
.jt_city_header_body {
margin-top: 58px;
height: 185px;
overflow-y: scroll;
width: 505px;
display: flex;
/* flex-flow: column; */
flex-wrap: wrap;
.jt_city_body_num {
display: flex;
margin-bottom: 10px;
.jt_city_body_num_info {
width: 30px;
line-height: 34px;
text-align: center;
color: #000000;
}
.jt_city_body_name {
display: flex;
flex-wrap: wrap;
flex: 1;
align-content: flex-start;
}
}
}
.jt_city_header {
position: absolute;
top: 0;
left: 0;
z-index: 5;
width: 100%;
height: 55px;
padding: 10px 20px 0 20px;
box-sizing: border-box;
.jt_city_header_tit {
font-size: 12px;
opacity: 0.7;
i{
float: right;
font-size: 20px;
margin-right: -10px;
&:hover{
color: #FECE12;
}
}
}
.jt_city_header_num {
display: flex;
height: 25px;
border-bottom: 1px solid #DFDFDF;
margin-top: 8px;
font-size: 14px;
div {
padding: 0 5px;
margin-right: 16px;
margin-bottom: -2px;
&:hover {
color: #FECE12;
cursor: pointer;
}
}
.jt_city_act {
margin-bottom: -1px;
border-bottom: 2px solid #FECE12;
color: #FECE12;
}
}
}
<template>
<div>
<oneselect-city :demoCityData="push_data.dest"></oneselect-city>
</div>
</template>
<script>
export default {
name: "projectAdd",
components: {
oneselectCity: () => import("@/components/journeyList/journeyBody/journeyTabNum/oneselectCity.vue")
},
data() {
return {
push_data: {
dest: []
}
};
},
created() {
this.$bus.$on("setBusCityData", arg => {
this.setCityData(arg)
});
},
methods: {
setCityData(value){
this.push_data.dest = value
}
}
}
</script>
import Vue from 'vue'
const bus = new Vue()
export default bus;