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>

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

(0)

相关推荐

  • vue.js模仿京东省市区三级联动的选择组件实例代码

    前言 在最近的工作中需要一个盒京东购物车地址选择相似的一个省市区三级联动选择组件,google查了下都是下拉框形式的,于是自己写了一个,希望对使用vue开发项目的朋友有帮助,下面话不多说了,来一起看看详细的介绍吧. 显示效果如下: 注意:使用vue2.0开发 实例代码 html代码如下 <!--居住地址三级联动选项--> <section class="showChose" v-show="showChose"> <section cl

  • 基于Vue2实现简易的省市区县三级联动组件效果

    这是一个基于Vue2的简易省市区县三级联动组件,可以控制只显示省级或只显示省市两级,可设置默认值等.提供原始省市县代码和名称数据,适用于各种有关城市区县的应用. 安装 我们使用npm安装: npm install v-distpicker --save 使用 首先在模板中加入组件: <v-distpicker></v-distpicker> 如果要带默认值,则可以这样: <v-distpicker province="广东省" city="广州市

  • Vue使用vue-area-linkage实现地址三级联动效果的示例

    很多时候我们需要使用地址三级联动,即省市区三级联动.网上有很多插件,在此介绍Vue的一款地区联动插件:vue-area-linkage,下面介绍如何使用这个插件实现地址联动效果: 1.安装vue-area-linkage插件:npm install --save vue-area-linkage --registry=https://registry.npm.taobao.org --verbose 2.在main.js上进行依赖注入,如下图所示: 3.在对应vue文件的template模板上写

  • 使用vue2实现带地区编号和名称的省市县三级联动效果

    我们知道省市区县都有名称和对应的数字唯一编号,使用编号可以更方便查询以及程序处理,我们今天来了解一下使用vue2来实现常见的省市区下拉联动选择效果. 准备数据源 我们的省市区县的数据源来自本站文章 <基于Vue2的简易的省市区县三级联动组件> 中的districts.js,感谢 v-distpicker作者.districts.js中的数据格式大概是这样的: export default { 100000: { 110000: '北京市', 120000: '天津市', 130000: '河北

  • 详解Vue、element-ui、axios实现省市区三级联动

    现在大部分电商的网站.app都需要用户或者管理者去选择设置地区等位置信息.下面我就介绍一下前端开发者用vue,axios,element-ui开发一个省市区三级联动的组件. 1.准备工作,首先我们需要全中国的省市区资源的json数据(科普一下:前六位数字是身份证前六位) 2.搭建vue-cli,安装axios,element-ui,创建vue,webpack项目 1). 在控制台或者终端执行以下代码,其中只需要路由(y),其他e2e,eslint这些不需要(y) vue init webpack

  • vue基于mint-ui实现城市选择三级联动

    项目是基于vue2 的移动端项目,供大家参考,具体内容如下 1.实际效果 地址三级联动 mint-ui picker.png 2.首先你需要去下载一个包含中国省份,城市,区县的数据 如下: (这个地址里面包含二级联动数据,三级联动数据,四级联动数据等,找到自己需要的) (一个更好的中国地区数据,推荐用这个) 3.具体代码 主要是用到了mint-ui的picker组件,关于mint-ui的使用就自行看官网 Ⅰ .html组件 <div> <mt-picker :slots="my

  • Vue2仿淘宝实现省市区三级联动

    三级联动,随着越来越多的审美,出现了很多种,好多公司都仿着淘宝的三级联动 ,好看时尚,so我们公司也一样--为了贴代码方便,我把写在data里面省市区的json独立了出来,下载贴进去即可用,链接如下:vue.json(这个直接是个data,放入你的vue2项目中即可.(因为我的项目是用的vue2,所以,其他的属性跟博客内容是吻合的.请配合博客再下载此json)). 首先页面显示如下: 然后我们县级所在地区会出现三级联动,如下:(以下是片段,背景色未截取) 这个张什么样,以什么形式出现,取决于贵公

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

    本文实例为大家分享了vue移动端城市三级联动组件的具体代码,供大家参考,具体内容如下 先看效果图 以下组件代码 <template> <div class="address"> <div class="addressboxbg" @click="cancel"></div> <div class="addressbox"> <p class="text

  • Vue 过渡(动画)transition组件案例详解

    Vue过度(动画),本质走的是CSS3:transtion,animation. 控制器div显示/隐藏,代码如下: <div id="box"> <input type="button" value="按钮" @click="toggle"> <div id="div1" v-show="isShow"></div> </div&g

  • vue实现移动端H5数字键盘组件使用详解

    本文实例为大家分享了vue实现移动端H5数字键盘组件的使用代码,供大家参考,具体内容如下 我们平时扫码付款的时候,经常会输入一些数字进行付款,仔细看了下键盘和系统的键盘有点不一样,于是今天买甘蔗的时候扫码付款就想了一下要怎么去实现一个.话不多说,直接上代码. 结果如下: 代码如下: <template> <div class="keyboard-wrapper"> <input type="text" v-model="NUM

  • vue图片拖拉转放大缩小组件使用详解

    vue图片拖拉转放大缩小组件的具体使用方法,供大家参考,具体内容如下 <doc> 图片组件 - 用户放大缩小以及拖拽 </doc> <template> <div style="width: 100%;position: relative;overflow: hidden;text-align: center;border: 1px solid #f1f2f3;"> <el-button size='mini' @click=&qu

  • Vue下拉选择框Select组件使用详解(二)

    本文实例为大家分享了Vue下拉选择框Select组件的使用方法,供大家参考,具体内容如下 效果图如下: 下拉组件宽度可自定义设置以下属性: ①下拉组件宽度width属性,默认宽度290 ②placeholder属性 ③是否禁用下拉的disabled属性 已预设下拉列表最多8条,超过时滚动显示,具体可自定义调整,如果下拉选项过长省略号显示,鼠标悬浮显示全称,由于业务需求,设置mode属性,区别默认name和value  与  dictKey和dictVal ①创建组件Select.vue <tem

  • Vue下拉选择框Select组件使用详解(一)

    本文实例为大家分享了Vue下拉选择框Select组件的使用方法,供大家参考,具体内容如下 效果图如下: 展开图如下: ①创建组件Select.vue:预设两种主题色,亦可视情况进行自定义修改样式: <template>   <div class="m-select-wrap">     <input       :class="['u-select-input f16', color === 'blue' ? '' : 'white-color'

  • jQuery select表单提交省市区城市三级联动核心代码

    jQuery select表单提交省市区城市三级联动,引用的是"jquery-1.7.min"类库,地区码查询地区名用数组存在AreaData_min,下面摘要部分代码: SelectArea.htm文件 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transition

  • ajax实现城市三级联动

    本文实例为大家分享了ajax实现城市三级联动的具体代码,供大家参考,具体内容如下 在准备好服务器后 html部分 <div> <select name="" id="province"> <option value="">请选择省份</option> </select> <select name="" id="city"> <op

  • vue地区选择组件教程详解

    概述 主要用于全国地区数据的操作,包括省,市,区三级联动,地区数据的添加和删除: 在操作地区数据时,以前也用过树形的地区选择组件,但因其在再操作大量的地区数据时,渲染缓慢,所以我们就换了另一种数据展示形式和交互形式,从而就有了这个组件. 注意:该组件是 vue.js 组件 demo 抢鲜体验请点击这里 demo API Props 参数 类型 说明 area Array 传入组件的地区的数据 Events 事件名 参数 说明 selected area 组件中选中的地区 详细说明 Props a

随机推荐