您的位置:首页 > Web前端 > Vue.js

vue用mint-ui的picker组件封装一个省市区三级联动组件

2018-03-13 10:32 525 查看
原文链接:https://www.geek-share.com/detail/2731870766.html

    最近公司在用vue做项目,然后需要做一个省市区的三级联动的功能,于是研究了一下mint-ui,写了效果如下的一个组件

首先我们的数据文件如下形式,将他分开成一个js文件并将数据暴露出来:

cityData.js

export const CITY_DATA= [
{
"id": "110000",
"name": "北京市",
"city": [
{
"id": "110100",
"name": "北京市",
"district": [
{
"id": "110101",
"name": "东城区"
},{
"id": "110102",
"name": "西城区"
}]
}]
}]

然后子组件需要实现三级联动的效果,并将用户的选择结果(选择的城市及对应的id)返回到父组件,内容如下:

linkage.vue

<template>
<div>
<div class="mask" @click="_hideLinkage"></div>
<div class="clearfix linkage">
<div class="province pickerWrapper">
<mt-picker :slots="provinces" @change="onProvinceChange" value-key="name"></mt-picker>
</div>
<div class="city pickerWrapper">
<mt-picker :slots="citys" @change="onCityChange" value-key="name"></mt-picker>
</div>
<div class="area pickerWrapper">
<mt-picker :slots="areas" @change="onAreaChange" value-key="name"></mt-picker>
</div>
</div>
</div>
</template>

<script>
import {CITY_DATA} from '../../api/cityData'  //引入cityData数据
export default {
computed: {
result() {
return {
name:this.province.name+this.city.name+this.area.name,
id:this.province.id+','+this.city.id+','+this.area.id
}
}
},
data() {
return {
province:{
name:'四川省',
id:'510000'
},
maskFlag:false,
city:{
name:'成都市',
id:'510100'
},
area:{
name:'市辖区',
id:'510101'
},
flag:0, //最开始省市区那三个picker会初始化调用change事件,但是此时没有省市区数据,因此会报错,
//所以以这个标识符来控制当时第一次初始化时调用change事件时直接return
provinces: [
{
flex: 1,
values: this._getProvince(),
className: 'slot1',
textAlign: 'center'
}, {
divider: true,
content: '-',
className: 'right'
}
],
citys: [
{
flex: 1,
values: this._getCity('四川省'),
className: 'slot1',
textAlign: 'center'
}, {
divider: true,
content: '-',
className: 'slot2'
}
],
areas: [
{
flex: 1,
values: this._getArea('四川省','成都市'),
className: 'slot1',
textAlign: 'center'
}
]

};
},
methods:{
_hideLinkage(){
this.$emit('getLinkage',this.result); //触发父组件的getLinkage事件接收结果数据
},
onProvinceChange(picker, values) {
if(this.flag===0){
return
}
let provinceIndex=picker.getSlotValue(0)
this.province=provinceIndex
let city=this._getCity(provinceIndex.name)
this.citys[0].values=city
this.city=city[0]
},
onCityChange(picker, values) {
if(this.flag===0){
return
}
let cityIndex=picker.getSlotValue(0)
this.city=cityIndex
let provinceIndex=this.province
let area=this._getArea(provinceIndex.name,cityIndex.name)
this.areas[0].values=area
this.area=area[0]
},
onAreaChange(picker, values) {
if(this.flag===0){
this.flag=1
return
}
let areaIndex=picker.getSlotValue(0)
this.area=areaIndex
},
//得到省份数据
_getProvince(){
let province=[]
CITY_DATA.forEach(function(item,index){
let obj={}
obj.id=item.id
obj.name=item.name
province.push(obj)
})
return province
},
//根据省份得到城市数据
_getCity(province){
let city=[]
CITY_DATA.forEach((item,index)=>{
if(item.name === province){
item.city.forEach((item,index)=>{
let obj={}
obj.id=item.id
obj.name=item.name
city.push(obj)
return
})
}
})
return city
},
//根据城市和省份得到区域数据
_getArea(province,city){
let area=[]
CITY_DATA.forEach((item,index)=>{
if(item.name === province){
item.city.forEach((item,index)=>{
if(item.name === city){
item.district.forEach((item)=>{
let obj={}
obj.id=item.id
obj.name=item.name
area.push(obj)
return
})
}
})
}
})
if(area.length==0){ //如果没有区域数据则第三个picker显示的内容
area.push({
name:'没有',
id:'000000'
})
}
return area
}
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.mask{
position: fixed;
top:0;
left:0;
height: 100%;
width: 100%;
background: rgba(0,0,0,0.5);
}
.linkage{
position: fixed;
bottom: 0;
width: 100%;
background: white;
left: 0;
overflow: hidden;
}
.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden}
.pickerWrapper{
width:33.3%;
float: left;
}

</style>

父组件只需要引入子组件,并得到用户选择的结果,展示在自己的页面上,内容如下:

parent.vue

<template>
<div>
<transition name="fade">
<linkage @getLinkage='_showChildMsg' v-show="showLinkage"></linkage>
</transition>
<p v-html="result" class="getCity" @click="_showLinkage"></p>
<p v-html="id" class="getCity" ></p>
</div>
</template>

<script type="text/ecmascript-6">
import Linkage from '../base/linkage/linkage' //引入子组件

export default{
data(){
return{
showLinkage:false, //控制子组件的显示隐藏
result:'请选择所在省市',
id:'显示对应id'
}
},
components:{
Linkage, //注册子组件
},
methods:{
_showChildMsg(msg){ //接收子组件数据
this.result = msg.name
this.id=msg.id
this.showLinkage=false
},
_showLinkage(){
this.showLinkage=true
}
}
}
</script>

<style scoped >
.getCity{
font-size: 20px;
}
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to  {
opacity: 0;
}

</style>

到这里,我们的三级联动组件就封装好了,这种公用的组件可以放到项目公用的文件里,以后在其他组件中也可以调用

转载于:https://www.geek-share.com/detail/2731870766.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: