vue移动端城市三级联动组件使用详解


Posted in Javascript onJuly 26, 2019

本文实例为大家分享了vue移动端城市三级联动组件的具体代码,供大家参考,具体内容如下

先看效果图

vue移动端城市三级联动组件使用详解

以下组件代码

<template>
 <div class="address">
  <div class="addressboxbg" @click="cancel"></div>
  <div class="addressbox">
   <p class="text_btn"><span style="float:left;" @click="cancel">取消</span><span style="float:right;color:#107E52;" @click="complete">完成</span></p>
   <div class="addressSelect" >
    <div class="selectbox"></div>
    <ul @touchstart="touchStart($event,'province')" @touchmove="touchMove($event,'province')" @touchend="touchEnd($event,'province')" :style="provinceStyle" :class="[{'selectAni':addSelect}]">
     <li v-for="(item,index) in list" :class="[{'addSelectActive':index == provinceIndex}]" :key="index">{{item.name}}</li>
    </ul>
    <ul @touchstart="touchStart($event,'city')" @touchmove="touchMove($event,'city')" @touchend="touchEnd($event,'city')" :style="cityStyle" :class="[{'selectAni':addSelect}]">
     <li v-for="(item,index) in list2" :class="[{'addSelectActive':index == cityIndex}]" :key="index">{{item.name}}</li>
    </ul>
    <ul @touchstart="touchStart($event,'district')" @touchmove="touchMove($event,'district')" @touchend="touchEnd($event,'district')" :style="districtStyle" :class="[{'selectAni':addSelect}]">
     <li v-for="(item,index) in list3" :class="[{'addSelectActive':index == districtIndex}]" :key="index" >{{item.name}}</li>
    </ul>
   </div>
  </div>
 </div>
</template>
 
<script>
export default {
 data () {
  return {
   list: [],
   list2: [],
   list3: [],
   provinceStyle: {
    WebkitTransform: 'translate3d(0px,0px,0px)'
   },
   cityStyle: {
    WebkitTransform: 'translate3d(0px,0px,0px)'
   },
   districtStyle: {
    WebkitTransform: 'translate3d(0px,0px,0px)'
   },
   startTop: 0,
   provinceIndex: 0,
   cityIndex: 0,
   districtIndex: 0,
   translateY: 0,
   maxScroll: 0,
   addHeight: 0,
   addSelect: false,
   provinceVal: '',
   cityVal: '',
   areaVal: '',
   val: {
    'provinceVal': '',
    'cityVal': '',
    'areaVal': ''
   }
  }
 },
 watch: {
  // 监听省滑动
  provinceVal (value) {
   this.$axiosGet(this.$api.area, {parentId: value}).then((res) => {
    if (res.code === 1) {
     this.list2 = res.data.length > 1 ? res.data : [{name: '-'}]
     if (res.data.length < 1) {
      this.list3 = [{name: '-'}]
     }
     this.cityVal = this.list2[0].value
    }
   })
  },
  // 监听市滑动
  cityVal (value) {
   if (value) {
    this.$axiosGet(this.$api.area, {parentId: value}).then((res) => {
     if (res.code === 1) {
      this.list3 = res.data.length > 1 ? res.data : [{name: '-'}]
     }
    })
   }
  }
 },
 created () {
  // 初始化数据
  // 拿省的数据
  this.$axiosGet(this.$api.area).then((res) => {
   if (res.code === 1) {
    this.list = res.data
    this.val.provinceVal = this.list[0]
   }
  })
  // 拿市区的数据
  this.$axiosGet(this.$api.area, {parentId: '1'}).then((res) => {
   if (res.code === 1) {
    this.list2 = res.data
    this.val.cityVal = this.list2[0]
   }
  })
  this.val.areaVal = {
   'name': '',
   'value': ''
  }
  // 第一条数据为直辖市 so '-' 符号表示为第三列
  this.list3 = [{name: '-'}]
 },
 methods: {
  // 点击取消
  cancel () {
   this.$emit('cancel', false)
  },
  // 点击完成
  complete () {
   if (!this.val.areaVal.value) {
    this.val.areaVal = {
     'name': '',
     'value': ''
    }
   }
   if (!this.val.cityVal.value) {
    this.val.cityVal = {
     'name': '',
     'value': ''
    }
   }
   this.$emit('complete', this.val)
  },
  // 滑动开始
  touchStart (e, val) {
   e.preventDefault()
   this.addSelect = false
   this.addHeight = e.currentTarget.children[0].offsetHeight
   this.maxScroll = this.addHeight * e.currentTarget.children.length
   this.startTop = e.targetTouches[0].pageY
   switch (val) {
    case 'province':
     this.translateY = parseInt(this.provinceStyle.WebkitTransform.slice(this.provinceStyle.WebkitTransform.indexOf(',') + 1, this.provinceStyle.WebkitTransform.lastIndexOf(',')))
     break
    case 'city':
     this.translateY = parseInt(this.cityStyle.WebkitTransform.slice(this.cityStyle.WebkitTransform.indexOf(',') + 1, this.cityStyle.WebkitTransform.lastIndexOf(',')))
     break
    case 'district':
     this.translateY = parseInt(this.districtStyle.WebkitTransform.slice(this.districtStyle.WebkitTransform.indexOf(',') + 1, this.districtStyle.WebkitTransform.lastIndexOf(',')))
     break
    default:
     break
   }
  },
  // 滑动进行中
  touchMove (e, val) {
   e.preventDefault()
   switch (val) {
    case 'province':
     if ((e.targetTouches[0].pageY - this.startTop + this.translateY) > 0) {
      this.provinceStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
     } else if ((e.targetTouches[0].pageY - this.startTop + this.translateY) < -(this.maxScroll - this.addHeight)) {
      this.provinceStyle.WebkitTransform = 'translate3d(0px,' + -(this.maxScroll - this.addHeight) + 'px,0px)'
     } else {
      this.provinceStyle.WebkitTransform = 'translate3d(0px,' + (e.targetTouches[0].pageY - this.startTop + this.translateY) + 'px,0px)'
     }
     break
    case 'city':
     if ((e.targetTouches[0].pageY - this.startTop + this.translateY) > 0) {
      this.cityStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
     } else if ((e.targetTouches[0].pageY - this.startTop + this.translateY) < -(this.maxScroll - this.addHeight)) {
      this.cityStyle.WebkitTransform = 'translate3d(0px,' + -(this.maxScroll - this.addHeight) + 'px,0px)'
     } else {
      this.cityStyle.WebkitTransform = 'translate3d(0px,' + (e.targetTouches[0].pageY - this.startTop + this.translateY) + 'px,0px)'
     }
     break
    case 'district':
     if ((e.targetTouches[0].pageY - this.startTop + this.translateY) > 0) {
      this.districtStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
     } else if ((e.targetTouches[0].pageY - this.startTop + this.translateY) < -(this.maxScroll - this.addHeight)) {
      this.districtStyle.WebkitTransform = 'translate3d(0px,' + -(this.maxScroll - this.addHeight) + 'px,0px)'
     } else {
      this.districtStyle.WebkitTransform = 'translate3d(0px,' + (e.targetTouches[0].pageY - this.startTop + this.translateY) + 'px,0px)'
     }
     break
    default:
     break
   }
  },
  // 滑动结束
  touchEnd (e, val) {
   e.preventDefault()
   this.addSelect = true
   switch (val) {
    case 'province':
     let provinceTranslateY = parseInt(this.provinceStyle.WebkitTransform.slice(this.provinceStyle.WebkitTransform.indexOf(',') + 1, this.provinceStyle.WebkitTransform.lastIndexOf(',')))
     this.provinceIndex = -Math.round(provinceTranslateY / this.addHeight)
     this.provinceStyle.WebkitTransform = 'translate3d(0px,' + (Math.round(provinceTranslateY / this.addHeight) * this.addHeight) + 'px,0px)'
     this.cityStyle.WebkitTransform = this.districtStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
     this.cityIndex = this.districtIndex = 0
     break
    case 'city':
     let cityTranslateY = parseInt(this.cityStyle.WebkitTransform.slice(this.cityStyle.WebkitTransform.indexOf(',') + 1, this.cityStyle.WebkitTransform.lastIndexOf(',')))
     this.cityIndex = -Math.round(cityTranslateY / this.addHeight)
     this.cityStyle.WebkitTransform = 'translate3d(0px,' + (Math.round(cityTranslateY / this.addHeight) * this.addHeight) + 'px,0px)'
     this.districtStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
     this.districtIndex = 0
     break
    case 'district':
     let districtTranslateY = parseInt(this.districtStyle.WebkitTransform.slice(this.districtStyle.WebkitTransform.indexOf(',') + 1, this.districtStyle.WebkitTransform.lastIndexOf(',')))
     this.districtIndex = -Math.round(districtTranslateY / this.addHeight)
     this.districtStyle.WebkitTransform = 'translate3d(0px,' + (Math.round(districtTranslateY / this.addHeight) * this.addHeight) + 'px,0px)'
     break
    default:
     break
   }
   // 滑动结束后 处理数据
   this.dataProcessing()
  },
  // 数据处理
  dataProcessing () {
   // 滑动数据传输 数据处理
   this.val.provinceVal = this.list[this.provinceIndex]
   this.provinceVal = this.list[this.provinceIndex].value
   this.val.cityVal = this.list2[this.cityIndex]
   this.cityVal = this.list2[this.cityIndex].value
   this.val.areaVal = this.list3[this.districtIndex]
   this.areaVal = this.list3[this.districtIndex].value
   // this.val.cityVal = this.addressData[this.provinceIndex].city[this.cityIndex].name
   // this.val.areaVal = this.addressData[this.provinceIndex].city[this.cityIndex].area[this.districtIndex]
   // this.$emit('getAddress', this.val)
   // this.test([this.val.provinceVal, this.cityIndex, this.districtIndex])
  }
 }
}
</script>
 
<style>
.address{
 position:absolute;
 top: 0px;
 bottom: 0px;
 left: 0px;
 right: 0px;
}
.address .addressbox{
 height: 40%;
 position: absolute;
 z-index: 101;
 width: 100%;
 max-height: 100%;
 overflow: hidden;
 background: #fff;
 bottom: 0px;
}
.address .addressbox .text_btn{
 height: 30px;
 font-size: 14px;
 line-height: 30px;
 border-top: 1px solid #ccc;
 border-bottom: 1px solid #ccc;
 padding: 0 10px;
 background: #F9F9F9;
}
.addressSelect .selectbox{
 width: 100%;
 height: 26px;
 border-top: 1px solid #ccc;
 border-bottom: 1px solid #ccc;
 margin-top: 60px;
 background: #F9F9F9;
}
.address .addressboxbg{
 position: absolute;
 left: 0;
 top: 0;
 z-index: 100;
 width: 100%;
 height: 100%;
 background: rgba(0,0,0,.7);
}
.addressSelect{width: 100%; position: relative; background: #fff; height: 190px;overflow: hidden; -webkit-mask-box-image: linear-gradient(0deg,transparent,transparent 5%,#fff 20%,#fff 80%,transparent 95%,transparent); font-size: 14px;}
.addressSelect ul{width: 33.333333%; position: absolute; left: 0; top:60px; -webkit-transform-style: preserve-3d; -webkit-backface-visibility:hidden; text-align: center; padding-left: 0;}
.addressSelect ul li{white-space : nowrap;overflow: hidden; text-overflow:ellipsis; color:rgba(0,0,0,.54); padding: 3px 0;}
.addressSelect ul:nth-of-type(2){left: 33.333333%;}
.addressSelect ul:nth-of-type(3){left: 66.666666%;}
.addressSelect ul li.addSelectActive{color:rgba(0,0,0,.87); transform: scale(1.1); transition: 0.5s;}
.selectAni{transition: 0.8s;}
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery异步获取返回值中文乱码的解决方法
Jan 29 Javascript
快速学习jQuery插件 Form表单插件使用方法
Dec 01 Javascript
JS+Canvas绘制时钟效果
Aug 20 Javascript
AngularJS基础 ng-submit 指令简单示例
Aug 03 Javascript
快速解决js中window.location.href不工作的问题
Nov 02 Javascript
基于JavaScript实现窗口拖动效果
Jan 18 Javascript
jQuery Ajax全解析
Feb 13 Javascript
bootstrap table 多选框分页保留示例代码
Mar 08 Javascript
使用Vue构建可重用的分页组件
Mar 26 Javascript
vue下拉刷新组件的开发及slot的使用详解
Dec 23 Vue.js
vue使用require.context实现动态注册路由
Dec 25 Vue.js
vue实现可移动的悬浮按钮
Mar 04 Vue.js
Bootstrap实现省市区三级联动(亲测可用)
Jul 26 #Javascript
layui实现下拉框三级联动
Jul 26 #Javascript
layui添加动态菜单与选项卡
Jul 26 #Javascript
layer设置maxWidth及maxHeight解决方案
Jul 26 #Javascript
javascript中的闭包概念与用法实践分析
Jul 26 #Javascript
layui自定义插件citySelect实现省市区三级联动选择
Jul 26 #Javascript
微信小程序自定义头部导航栏和导航栏背景图片 navigationStyle问题
Jul 26 #Javascript
You might like
模板引擎Smarty深入浅出介绍
2006/12/06 PHP
用PHP实现的生成静态HTML速度快类库
2007/03/31 PHP
php float不四舍五入截取浮点型字符串方法总结
2013/10/28 PHP
php实现HTML实体编号与非ASCII字符串相互转换类实例
2016/11/02 PHP
Prototype最新版(1.5 rc2)使用指南(1)
2007/01/10 Javascript
使用JavaScript构建JSON格式字符串实现步骤
2013/03/22 Javascript
document.forms[].submit()使用介绍
2014/02/19 Javascript
javascript实现简单的页面右下角提示信息框
2015/07/31 Javascript
jQuery ajax提交Form表单实例(附demo源码)
2016/04/06 Javascript
动态加载js、css的简单实现代码
2016/05/26 Javascript
javascript定时器取消定时器及优化方法
2017/07/08 Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
2018/01/25 Javascript
vue如何安装使用Quill富文本编辑器
2018/09/21 Javascript
React 路由懒加载的几种实现方案
2018/10/23 Javascript
vue列表单项展开收缩功能之this.$refs的详解
2019/05/05 Javascript
layui table动态表头 改变表格头部 重新加载表格的方法
2019/09/21 Javascript
javascript操作元素的常见方法小结
2019/11/13 Javascript
深入理解webpack process.env.NODE_ENV配置
2020/02/23 Javascript
[36:43]NB vs Optic 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
浅析Python中的for 循环
2016/06/09 Python
Python变量和数据类型详解
2017/02/15 Python
python利用正则表达式搜索单词示例代码
2017/09/24 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
Python3批量移动指定文件到指定文件夹方法示例
2019/09/02 Python
flask框架url与重定向操作实例详解
2020/01/25 Python
Python json转字典字符方法实例解析
2020/04/13 Python
Python并发concurrent.futures和asyncio实例
2020/05/04 Python
什么是python的必选参数
2020/06/21 Python
python boto和boto3操作bucket的示例
2020/10/30 Python
公证委托书模板
2014/04/03 职场文书
工地安全质量标语
2014/06/07 职场文书
2014客服代表实习自我鉴定
2014/09/18 职场文书
群众路线个人对照检查材料2014
2014/09/26 职场文书
初中优秀学生评语
2014/12/29 职场文书
医院合作意向书范本
2015/05/08 职场文书
Nginx代理Redis哨兵主从配置的实现
2022/07/15 Servers