诗雨远方的博客

需要的是思想,不是形式。 贵州中测信息技术有限公司 www.iwiteks.com

vue 实现仿京东、淘宝省市区三级联动
vue 实现仿京东、淘宝省市区三级联动

在做电商或其他项目的时候,物流我们肯定会集成进去,那么我们肯定需要集成地址管理,地址管理除了最基本的省、市、区外,我们还要单独添加一个详细地址字段,不然我们无法精确到详细地址,那么最后我们的详细地址就是省市区加上我们的详细地址字段,好了,我们先来看一下省市区三级联动的效果图

其实这个功能可以封装成一个组件呢,我这里面集成了VUX移动端组件,你用的时候html里面加入,代码本来是对齐规范的,但是贴上来就变形了

1、html代码

<cell is-link title="所属地区" class="require" @click.native="choseAdd()" value-align="left">
<p style="margin-left: 20px">
{{receptAddtess.receiptProvince === '' ? "请选择" : receptAddtess.receiptProvince}} {{receptAddtess.receiptCity}} {{receptAddtess.receiptArea}}
</p>
</cell>

<!-- 省市区三级联动 -->
<section class="myAddress">
<!-- 居住地址三级联动选项 -->
<section class="showChose" v-show="showChose">
<section class="address">
<section class="titleTop">
<div class="titleTopLeft">
<span>选择地址</span>
</div>
<div class="titleTopRight">
<span @click="closeAdd()">×</span>
</div>
</section>
<hr style="height:1px;border:none;border-top:1px solid #EEEEEE;" >
<section class="title">
<div class="area" @click="provinceSelected()">
<span>{{Province?Province:info[province-1].name}}</span>
</div>
<div class="area" @click="citySelected()" :class="City?'':'active'">
{{City?City:'请选择'}}
</div>
<div class="area" @click="districtSelected()" :class="District?'':'active'" v-show="City">
{{District?District:'请选择'}}
</div>
</section>
<hr style="height:1px;border:none;border-top:1px solid #EEEEEE;" >
<ul>
<li class="addList" v-for="(v,k) in info" :key="(v,k).index"
@click="getProvinceId(v.id, v.name, k)"
v-show="showProvince"
:class="v.selected === true ? 'active' : ''">{{v.name}}</li>
<li class="addList" v-for="(v,k) in showCityList" :key="(v,k).index"
@click="getCityId(v.id, v.name, k)"
v-show="showCity"
:class="v.selected ? 'active' : ''">{{v.name}}</li>
<li class="addList" v-for="(v,k) in showDistrictList" :key="(v,k).index"
@click="getDistrictId(v.id, v.name, k)"
v-show="showDistrict"
:class="v.selected ? 'active' : ''">{{v.name}}</li>
</ul>
</section>
</section>
</section>

2、js方法如下

choseAdd () {
this.showChose = true
},
closeAdd () {
this.showChose = false
},
_filter(add, name, code) {
let result = []
for (let i = 0; i < add.length; i++) {
if (code === add[i].id) {
result = add[i][name]
}
}
return result
},
getProvinceId: function(code, input, index) {
this.province = code
this.Province = input
this.showProvince = false
this.showCity = true
this.showDistrict = false
this.showCityList = this._filter(this.info, 'city', this.province)
// 点击选择当前
this.info.map(a => { a.selected = false })
this.info[index].selected = true
this.receptAddtess.receiptProvince = input
},
provinceSelected: function() {
// 清除市级和区级列表
this.showCityList = false
this.showDistrictList = false
// 清除市级和区级选项
this.City = false
this.District = false
// 选项页面的切换
this.showProvince = true
this.showCity = false
this.showDistrict = false
},
getCityId: function(code, input, index) {
this.city = code
this.City = input
this.showProvince = false
this.showCity = false
this.showDistrict = true
this.showDistrictList = this._filter(this.showCityList, 'district', this.city)
// 选择当前添加active
this.showCityList.map(a => { a.selected = false })
this.showCityList[index].selected = true
this.receptAddtess.receiptCity = input
},
citySelected: function() {
this.showProvince = false
this.showCity = true
this.showDistrict = false
},
getDistrictId: function(code, input, index) {
this.district = code
this.District = input
// 选择当前添加active
this.showDistrictList.map(a => { a.selected = false })
this.showDistrictList[index].selected = true
// 选取市区选项之后关闭弹层
this.showChose = false
this.receptAddtess.receiptArea = input
},
districtSelected: function() {
this.showProvince = false
this.showCity = false
this.showDistrict = true
}

3、css代码如下

// 省市区三级联动CSS
.myAddress .cont{
border-bottom: 1px solid rgba(245,245,245,0.8);
}
.myAddress .cont span{
display: inline-block;
font-size: 0.28rem;
color: #333;
line-height: 0.88rem;
margin-left: 0.32rem;
}
.myAddress .cont section{
float:left;
}
.myAddress .cont p{
display: inline-block;
font-size: 0.28rem;
color: #333333;
line-height: 0.88rem;
margin-left: 1rem;
}
.myAddress .cont .pic2{
float: right;
width: 0.14rem;
height: 0.24rem;
margin: 0.32rem 0.32rem 0.32rem 0;
}
.myAddress .cont p.text{
margin-left: 0.72rem;
}
.showChose{
width:100%;
height:100%;
position:fixed;
top:0;
left:0;
z-index:120;
background:rgba(77,82,113,0.8);
}
.address{
.titleTop {
display inline
text-align center
.titleTopLeft {
padding-top 5px
padding-bottom 5px
span {
font-size 18px
}
}
.titleTopRight {
span {
position absolute
right 10px
top -5px
font-size 30px
color: #929292
}
}
}
position:absolute;
bottom:0;
left:0;
z-index:121;
background:#fff;
width:100%;
height: 430px
}

.title {
padding-top 4px
padding-bottom 5px
}
.title h4{
display:inline-block;
font-size:18px;
font-weight:normal;
}
.area{
display:inline-block;
font-size:15px;
margin-left:25px;
}
.addList{
width:85%;
padding-left:0.32rem;
font-size:15px;
line-height:32px;
}
/* 修改的格式 */
.address ul{
width:95%;
height:78%;
overflow:auto;
}
.address ul li{
margin-left:20px;
}
.address .title .active{
color:red;
border-bottom:0.02rem solid red;
}
.address ul .active{
color:red;
}

完成的一个界面如下,我这里面还调了接口,但是利用上面的代码就可以集成了,我的界面完成代码如下

<template>
<div class="modifyAddress">
<v-header title="添加地址" ref="header">
<div slot="right" class="headerRight" style="top: 2px; right: 5px;" @click="handleSaveInfo">
<span>保存</span>
</div>
</v-header>
<div class="inputWrapper">
<x-input placeholder="请输入收货人姓名" v-model="receptAddtess.receiptName">
<p slot="label" style="margin-right:20px">
<font color="red">*</font>昵称</p>
</x-input>
<x-input :max="13" is-type="china-mobile" placeholder="请输入手机号码" v-model="receptAddtess.receiptPhone">
<p slot="label" style="margin-right:20px">
<font color="red">*</font>手机号码</p>
</x-input>
<cell is-link title="所属地区" class="require" @click.native="choseAdd()" value-align="left">
<p style="margin-left: 20px">
{{receptAddtess.receiptProvince === '' ? "请选择" : receptAddtess.receiptProvince}} {{receptAddtess.receiptCity}} {{receptAddtess.receiptArea}}
</p>
</cell>

<!-- 省市区三级联动 -->
<section class="myAddress">
<!-- 居住地址三级联动选项 -->
<section class="showChose" v-show="showChose">
<section class="address">
<section class="titleTop">
<div class="titleTopLeft">
<span>选择地址</span>
</div>
<div class="titleTopRight">
<span @click="closeAdd()">×</span>
</div>
</section>
<hr style="height:1px;border:none;border-top:1px solid #EEEEEE;" >
<section class="title">
<div class="area" @click="provinceSelected()">
<span>{{Province?Province:info[province-1].name}}</span>
</div>
<div class="area" @click="citySelected()" :class="City?'':'active'">
{{City?City:'请选择'}}
</div>
<div class="area" @click="districtSelected()" :class="District?'':'active'" v-show="City">
{{District?District:'请选择'}}
</div>
</section>
<hr style="height:1px;border:none;border-top:1px solid #EEEEEE;" >
<ul>
<li class="addList" v-for="(v,k) in info" :key="(v,k).index"
@click="getProvinceId(v.id, v.name, k)"
v-show="showProvince"
:class="v.selected === true ? 'active' : ''">{{v.name}}</li>
<li class="addList" v-for="(v,k) in showCityList" :key="(v,k).index"
@click="getCityId(v.id, v.name, k)"
v-show="showCity"
:class="v.selected ? 'active' : ''">{{v.name}}</li>
<li class="addList" v-for="(v,k) in showDistrictList" :key="(v,k).index"
@click="getDistrictId(v.id, v.name, k)"
v-show="showDistrict"
:class="v.selected ? 'active' : ''">{{v.name}}</li>
</ul>
</section>
</section>
</section>

<x-textarea placeholder="街道、楼牌号等" :show-counter="false" :rows="1" autosize v-model="receptAddtess.detailAddress">
<p slot="label" style="margin-right:20px">
<font color="red">*</font>详细地址</p>
</x-textarea>
</div>
<!-- 是否默认地址 -->
<div class="recommededWrapper">
<x-switch title="设为默认地址" :value-map="[0, 1]" v-model="receptAddtess.defaultAddress" @on-change="ifDefault"></x-switch>
</div>
</div>
</template>

<script>
import VHeader from '@/components/v-header/v-header'
import { XInput, Group, Cell, XTextarea, XSwitch } from 'vux'
import axios from '@/api/axiosApi'
import info from '@/assets/json/address.json'
import { localUser } from '@/assets/js/local'
export default {
data () {
return {
pageTitle: '居住地址',
address: '',
showChose: false,
showProvince: true,
showCity: false,
showDistrict: false,
showCityList: false,
showDistrictList: false,
province: 1,
city: 3,
district: 57,
GetProvinceId: 2,
District: false,
Province: false,
City: false,
// areaProvince: '',
// areaCity: '',
// areaDistrict: '',
// v-for循环判断是否为当前
selected: false,
info,
receptAddtess: {
userId: '',
receiptName: '',
receiptPhone: '',
detailAddress: '',
defaultAddress: 0,
receiptProvince: '',
receiptCity: '',
receiptArea: ''
}
}
},
mounted () {
},
created () {
},
methods: {
handleSaveInfo () {
if (this.receptAddtess.receiptName === '') {
this.$vux.toast.text('收货人不能为空', 'middle')
return
}
if (this.receptAddtess.receiptPhone === '') {
this.$vux.toast.text('电话号码不能为空', 'middle')
return
}
if (this.receptAddtess.receiptProvince === '') {
this.$vux.toast.text('所属地区不能为空', 'middle')
return
}
if (this.receptAddtess.detailAddress === '') {
this.$vux.toast.text('详细地址不能为空', 'middle')
return
}
this.handleAddReceptAddress()
},
ifDefault (value) {
this.receptAddtess.defaultAddress = value
},
// 添加收货地址,每个用户不超过20个地址
handleAddReceptAddress () {
this.receptAddtess.userId = localUser.get('id')
axios.post(this, '/v1/receiptAddress', this.receptAddtess, (data) => {
this.$vux.confirm.show({
title: '温馨提示',
content: '添加地址成功'
})
})
},
choseAdd () {
this.showChose = true
},
closeAdd () {
this.showChose = false
},
_filter(add, name, code) {
let result = []
for (let i = 0; i < add.length; i++) {
if (code === add[i].id) {
result = add[i][name]
}
}
return result
},
getProvinceId: function(code, input, index) {
this.province = code
this.Province = input
this.showProvince = false
this.showCity = true
this.showDistrict = false
this.showCityList = this._filter(this.info, 'city', this.province)
// 点击选择当前
this.info.map(a => { a.selected = false })
this.info[index].selected = true
this.receptAddtess.receiptProvince = input
},
provinceSelected: function() {
// 清除市级和区级列表
this.showCityList = false
this.showDistrictList = false
// 清除市级和区级选项
this.City = false
this.District = false
// 选项页面的切换
this.showProvince = true
this.showCity = false
this.showDistrict = false
},
getCityId: function(code, input, index) {
this.city = code
this.City = input
this.showProvince = false
this.showCity = false
this.showDistrict = true
this.showDistrictList = this._filter(this.showCityList, 'district', this.city)
// 选择当前添加active
this.showCityList.map(a => { a.selected = false })
this.showCityList[index].selected = true
this.receptAddtess.receiptCity = input
},
citySelected: function() {
this.showProvince = false
this.showCity = true
this.showDistrict = false
},
getDistrictId: function(code, input, index) {
this.district = code
this.District = input
// 选择当前添加active
this.showDistrictList.map(a => { a.selected = false })
this.showDistrictList[index].selected = true
// 选取市区选项之后关闭弹层
this.showChose = false
this.receptAddtess.receiptArea = input
},
districtSelected: function() {
this.showProvince = false
this.showCity = false
this.showDistrict = true
}
},
components: {
VHeader,
XInput,
Group,
Cell,
XTextarea,
axios,
XSwitch,
localUser
}
}
</script>

<style lang="stylus" scoped>
@import '~@/assets/css/variable.styl'
.modifyAddress {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: $color-background;
z-index: 101;
height:100%;
}

.inputWrapper {
background-color white

}
// 省市区三级联动CSS
.myAddress .cont{
border-bottom: 1px solid rgba(245,245,245,0.8);
}
.myAddress .cont span{
display: inline-block;
font-size: 0.28rem;
color: #333;
line-height: 0.88rem;
margin-left: 0.32rem;
}
.myAddress .cont section{
float:left;
}
.myAddress .cont p{
display: inline-block;
font-size: 0.28rem;
color: #333333;
line-height: 0.88rem;
margin-left: 1rem;
}
.myAddress .cont .pic2{
float: right;
width: 0.14rem;
height: 0.24rem;
margin: 0.32rem 0.32rem 0.32rem 0;
}
.myAddress .cont p.text{
margin-left: 0.72rem;
}
.showChose{
width:100%;
height:100%;
position:fixed;
top:0;
left:0;
z-index:120;
background:rgba(77,82,113,0.8);
}
.address{
.titleTop {
display inline
text-align center
.titleTopLeft {
padding-top 5px
padding-bottom 5px
span {
font-size 18px
}
}
.titleTopRight {
span {
position absolute
right 10px
top -5px
font-size 30px
color: #929292
}
}
}
position:absolute;
bottom:0;
left:0;
z-index:121;
background:#fff;
width:100%;
height: 430px
}

.title {
padding-top 4px
padding-bottom 5px
}
.title h4{
display:inline-block;
font-size:18px;
font-weight:normal;
}
.area{
display:inline-block;
font-size:15px;
margin-left:25px;
}
.addList{
width:85%;
padding-left:0.32rem;
font-size:15px;
line-height:32px;
}
/* 修改的格式 */
.address ul{
width:95%;
height:78%;
overflow:auto;
}
.address ul li{
margin-left:20px;
}
.address .title .active{
color:red;
border-bottom:0.02rem solid red;
}
.address ul .active{
color:red;
}

.recommededWrapper {
margin-top 10px
background-color white
}
</style>

<style>
.modifyAddress .require .vux-label:before {
content: '*';
display: inline-block;
color: red;
}
</style>



哈哈,效果就实现了


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013144287/article/details/79997664
个人分类: Vue
想对作者说点什么? 我来说一句

仿京东地址选择省市区三级联动

2016年12月06日 100KB 下载

Vue2中省市区三级联动json

2017年06月06日 377KB 下载

android 仿京东收货地址 三级联动

2017年07月18日 20.95MB 下载

没有更多推荐了,返回首页

不良信息举报

vue 实现仿京东、淘宝省市区三级联动

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭