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 相关文章推荐
使用Post提交时须将空格转换成加号的解释
Jan 14 Javascript
javascript写的一个模拟阅读小说的程序
Apr 04 Javascript
require.js的用法详解
Oct 20 Javascript
js 定位到某个锚点的方法
Nov 19 Javascript
详解堆的javascript实现方法
Nov 29 Javascript
微信小程序 九宫格实例代码
Jan 21 Javascript
vue项目实现记住密码到cookie功能示例(附源码)
Jan 31 Javascript
详解Vue项目中出现Loading chunk {n} failed问题的解决方法
Sep 14 Javascript
vue输入节流,避免实时请求接口的实例代码
Oct 30 Javascript
Vue.js仿Select下拉框效果
Feb 18 Javascript
Selenium执行Javascript脚本参数及返回值过程详解
Apr 01 Javascript
JS页面动态绘图工具SVG,Canvas,VML介简介
Oct 16 Javascript
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
Win7 64位系统下PHP连接Oracle数据库
2014/08/20 PHP
优化网页之快速的呈现我们的网页
2007/06/29 Javascript
javascript xml为数据源的下拉框控件
2009/07/07 Javascript
动态创建样式表在各浏览器中的差异测试代码
2011/09/13 Javascript
基于jquery打造的百分比动态色彩条插件
2012/09/19 Javascript
zeroclipboard 单个复制按钮和多个复制按钮的实现方法
2014/06/14 Javascript
多个checkbox被选中时如何判断是否有自己想要的
2014/09/22 Javascript
深入解析JavaScript中的立即执行函数
2016/05/21 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
js内置对象处理_打印学生成绩单的简单实现
2016/09/24 Javascript
jquery 仿锚点跳转到页面指定位置的实例
2017/02/14 Javascript
从零学习node.js之搭建http服务器(二)
2017/02/21 Javascript
js简易版购物车功能
2017/06/17 Javascript
详解webpack进阶之插件篇
2017/07/06 Javascript
vuex实现登录状态的存储,未登录状态不允许浏览的方法
2018/03/09 Javascript
vue select组件的使用与禁用实现代码
2018/04/10 Javascript
Bootbox将后台JSON数据填充Form表单的实例代码
2018/09/10 Javascript
vue、react等单页面项目部署到服务器的方法及vue和react的区别
2018/09/29 Javascript
浏览器事件循环与vue nextTicket的实现
2019/04/16 Javascript
bootstrap-table+treegrid实现树形表格
2019/07/26 Javascript
nodejs对mongodb数据库的增加修删该查实例代码
2020/01/05 NodeJs
Node.js API详解之 string_decoder用法实例分析
2020/04/29 Javascript
[08:17]Ti9 现场cosplay
2019/09/10 DOTA
python获取文件版本信息、公司名和产品名的方法
2014/10/05 Python
python实现简单温度转换的方法
2015/03/13 Python
Python管理Windows服务小脚本
2018/03/12 Python
安装python及pycharm的教程图解
2019/10/10 Python
windows、linux下打包Python3程序详细方法
2020/03/17 Python
Python填充任意颜色,不同算法时间差异分析说明
2020/05/16 Python
Swisse官方海外旗舰店:澳大利亚销量领先,自然健康品牌
2017/12/15 全球购物
linux面试相关问题
2013/04/28 面试题
钳工实习自我鉴定
2013/09/19 职场文书
党的群众路线教育实践活动整改落实情况自查报告
2014/10/28 职场文书
2014年居委会工作总结
2014/12/09 职场文书
长江三峡导游词
2015/01/31 职场文书
观看禁毒宣传片后的感想
2015/08/11 职场文书