该栗子是我直接从公司的项目单独拉出来的(懒得重新写一次了),所以代码会有些冗余,下面直接看效果:

接着上代码:

html:

  1. <template>
  2. <div>
  3. <div class="ysc-header">
  4. <p class="header-title">{{headerTxt}}</p>
  5. </div>
  6. <div class="addAddress" @click="choseAdd()">
  7. <input type="text" placeholder="所在地区" class="txtmangth" disabled="disabled" v-model="userAddress">
  8. </div>
  9. <!-- 收货地址三级联动选项 start-->
  10. <section class="address" :class="{toggHeight:istoggHeight}">
  11. <section class="title">
  12. <div class="area" @click="provinceSelected()" :class="[oneac ? 'accolor' : '']">{{Province?Province:'请选择'}}</div>
  13. <div class="area" @click="citySelected()" :class="[twoac ? 'accolor':'']" v-show="twoshow">{{City?City:'请选择'}}</div>
  14. <div class="area" @click="districtSelected()" :class="threeac ? 'accolor':''" v-show="threeshow">{{District?District:'请选择'}}</div>
  15. <div class="determine" v-show="showDeter" @click="determine()">确定</div>
  16. </section>
  17. <ul v-show="showProvince" class="proJuli">
  18. <li class="addList" v-for="(v,k) in info" @click="getProvinceId(v.id, v.name, k)" :key="v.id" :class="{active : v.selected}"><span>{{v.name}}</span></li>
  19. </ul>
  20. <ul v-show="showCity" class="citJuli">
  21. <li class="addList" v-for="(v,k) in showCityList" @click="getCityId(v.id, v.name, k)" :key="v.id" :class="{active : v.selected}"><span>{{v.name}}</span></li>
  22. </ul>
  23. <ul v-show="showDistrict" class="disJuli">
  24. <li class="addList" v-for="(v,k) in showDistrictList" @click="getDistrictId(v.id, v.name, k)" :key="v.id" :class="{active : v.selected}"><span>{{v.name}}</span></li>
  25. </ul>
  26. </section>
  27. <!-- 收货地址三级联动选项 end-->
  28. <div class="layout" :class="{layoutBg:islayout}" @click="closeAdd()"></div>
  29. </div>
  30. </template>

script:

  1. <script>
  2. import maps from '../../static/js/map.js'
  3. export default {
  4. data () {
  5. return {
  6. islayout: false,
  7. istoggHeight: false,
  8. headerTxt: '添加新地址',
  9. isBc: false, // 用于控制保存按钮高亮
  10. toggle: false, // 用于切换默认地址
  11. showDeter: false,
  12. oneac: true,
  13. twoac: false,
  14. threeac: false,
  15. twoshow: false,
  16. threeshow: false,
  17. userAddress: '',
  18. oneliIndex: '', // 用于高亮子菜单
  19. twoliIndex: '',
  20. titleIndex: Number,
  21. showProvince: true, // 第一个li默认显示
  22. showCity: false, // 第二个li默认隐藏
  23. showDistrict: false, // 第三个li默认隐藏
  24. showCityList: [],
  25. showDistrictList: [],
  26. province: '',
  27. city: '',
  28. district: '',
  29. GetProvinceId: ,
  30. District: '',
  31. Province: '',
  32. City: '',
  33. // v-for循环判断是否为当前
  34. selected: true,
  35. info: maps.map // 三级联动城市列表
  36. }
  37. },
  38. mounted () {
  39. document.querySelector('body').style.backgroundColor = '#f5f7fa'
  40. },
  41. created () {
  42. if (this.$route.query.data !== undefined) { // 如果是点击编辑地址过来,则执行...当然了,不一定非要用路由传参的方式,你也可以用本地存储,反正能证明你是点击了编辑地址过来就好
  43. this.showDeter = true
  44. this.headerTxt = '编辑收货地址'
  45.  
  46. let editDate = JSON.parse(this.$route.query.data)
  47. this.province = editDate.province
  48. this.city = editDate.city
  49. this.district = editDate.district
  50. address.getAddressData({}).then((res) => { // axios请求,目的获取新增地址时,保存的地址ID,用于高亮显示
  51. if (res.isSuccess === ) {
  52. // 初始化页面,如果是编辑地址的话,则
  53. this.twoshow = true // 控制第二个nav显示
  54. this.threeshow = true // 给第三个nav显示
  55. this.Province = editDate.areaDescription.split(' ')[]
  56. this.City = editDate.areaDescription.split(' ')[]
  57. this.District = editDate.areaDescription.split(' ')[]
  58. this.showCityList = this._filter(this.info, 'city', editDate.province) // editDate.province由后台获取的id
  59. this.showDistrictList = this._filter(this.showCityList, 'district', editDate.city) // editDate.city由后台获取的id
  60. // 高亮后台返回选中的地址,需要对应id
  61. this._newArr(this.info, editDate.province)
  62. this._newArr(this.showCityList, editDate.city)
  63. this._newArr(this.showDistrictList, editDate.district)
  64. }
  65. })
  66. } else {
  67. // address.getAddressData({}).then((res) => {
  68. // if (res.isSuccess === 1) {
  69. // this.info = res.resData[0].regionalInformation
  70. // }
  71. // })
  72. console.log()
  73. }
  74. },
  75. methods: {
  76. choseAdd: function () { // 选择地址弹层,打开弹层
  77. this.islayout = true
  78. this.istoggHeight = true
  79. if (this.$route.query.data !== undefined) {
  80. this._gotoTop('.proJuli', )
  81. }
  82. },
  83. closeAdd: function () { // 关闭弹层
  84. this.istoggHeight = false
  85. this.islayout = false
  86. },
  87. determine () {
  88. this.istoggHeight = false
  89. this.islayout = false
  90. // this.showDeter = false
  91. this.userAddress = this.Province + ' ' + this.City + ' ' + this.District
  92. },
  93. _newArr (arr, selectid) {
  94. for (var i = ; i < arr.length; i++) {
  95. if (arr[i].id === selectid) {
  96. this.$set(arr[i], 'selected', true)
  97. } else if (selectid === -) {
  98. this.$set(arr[i], 'selected', false)
  99. }
  100. }
  101. return arr
  102. },
  103. _filter (add, name, code) { // 数组,对应数组内容,对应数组id
  104. let result = []
  105. for (let i = ; i < add.length; i++) {
  106. if (code === add[i].id) {
  107. // console.log(code, add[i].id)
  108. result = add[i][name]
  109. }
  110. }
  111. return result
  112. },
  113. _gotoTop (info, index) { // 滚动距离 --> 对应class,第几个index
  114. let proJuliBox = document.querySelector(info)
  115. let activeBox = document.getElementsByClassName('active')[index]
  116. let t = activeBox.offsetTop - + // 后面的数据,根据页面情况自己调整
  117. proJuliBox.scrollTo(, t)
  118. },
  119. getProvinceId: function (code, input, index) { // 点击第一个li
  120. // console.log('code', code, input, index)
  121. this.titleIndex = Number
  122. this.province = code
  123. this.Province = input // 获取选中的省份
  124. this.showProvince = false
  125. this.showCity = true
  126. this.showDistrict = false
  127. this.showCityList = this._filter(this.info, 'city', this.province)
  128. // 点击选择当前
  129. this.info.map(a => { a.selected = false })
  130. this.info[index].selected = true
  131. // console.log(this.info[index].name) // 点击的省份的名字
  132.  
  133. this.oneac = false // 给第一个nav去掉高亮
  134. this.twoac = true // 给第二个nav添加高亮
  135. this.threeac = false // 去除第三个li的高亮
  136. this.twoshow = true // 控制第二个nav显示
  137. // this.City = false // 清除市级和区级nav选项
  138. // this.District = false // 清除市级和区级nav选项
  139. this.City = '' // 第二nav置空
  140. this.threeshow = false // 第三nav隐藏
  141. this.oneliIndex = index
  142. this._newArr(this.showCityList, -) // 清除市级高亮
  143. this.showDeter = false
  144. },
  145. provinceSelected: function () {
  146. // console.log('点击了第一个nav')
  147. // this.titleIndex = 1
  148. // 清除市级和区级列表
  149. // this.showCityList = true
  150. // this.showDistrictList = true
  151. // 清除市级和区级nav选项
  152. // this.City = false
  153. // this.District = false
  154. // 选项页面的切换
  155. this.showProvince = true
  156. this.showCity = false
  157. this.showDistrict = false
  158. this.oneac = true // 给第一个nav添加高亮
  159. this.twoac = false // 给第二个nav去除高亮
  160. this.threeac = false // 给第三个nav去掉高亮
  161. },
  162. getCityId: function (code, input, index) { // 点击第二个li
  163. // console.log('id', code, input, 'index', index)
  164. this.titleIndex = Number
  165. this.city = code
  166. this.City = input
  167. this.showProvince = false
  168. this.showCity = false
  169. this.showDistrict = true
  170. this.showDistrictList = this._filter(this.showCityList, 'district', this.city)
  171. // 选择当前添加active
  172. this.showCityList.map(a => { a.selected = false })
  173. this.showCityList[index].selected = true
  174. this.twoliIndex = index
  175.  
  176. this.twoac = false // 给第二个nav去除高亮
  177. this.threeac = true // 给第三个nav添加高亮
  178. this.threeshow = true // 给第三个nav显示
  179. this.District = '' // 第三nav置空
  180. this._newArr(this.showDistrictList, -) // 清除区级高亮
  181. this.showDeter = false
  182. },
  183. citySelected: function () {
  184. // console.log('点击了第二个nav')
  185. this.titleIndex =
  186. this.showProvince = false
  187. this.showCity = true
  188. this.showDistrict = false
  189.  
  190. this.oneac = false // 给第一个nav去掉高亮
  191. this.twoac = true // 给第二个nav添加高亮
  192. this.threeac = false // 给第三个nav去掉高亮
  193. if (this.$route.query.data !== undefined) {
  194. this.$nextTick(() => { // 让li标签回到顶部
  195. this._gotoTop('.citJuli', )
  196. })
  197. }
  198. },
  199. getDistrictId: function (code, input, index) {
  200. this.titleIndex = Number
  201. this.district = code
  202. this.District = input
  203. // 选择当前添加active
  204. this.showDistrictList.map(a => { a.selected = false })
  205. this.showDistrictList[index].selected = true
  206. // 选取市区选项之后关闭弹层
  207.  
  208. this.oneac = false // 给第一个nav去掉高亮
  209. this.showDeter = true
  210. },
  211. districtSelected: function () { // 第三个选择
  212. // console.log('点击了第三个nav')
  213. this.showProvince = false
  214. this.showCity = false
  215. this.showDistrict = true
  216.  
  217. this.oneac = false // 给第一个nav去掉高亮
  218. this.twoac = false // 给第二个nav去掉高亮
  219. this.threeac = true // 给第三个nav添加高亮
  220. if (this.$route.query.data !== undefined) {
  221. this.$nextTick(() => { // 让li标签回到顶部
  222. this._gotoTop('.disJuli', )
  223. })
  224. }
  225. }
  226. },
  227. beforeDestroy () {
  228. document.querySelector('body').style.backgroundColor = '#fff'
  229. }
  230. }
  231. </script>

style:

  1. </script>
  2. <style>
  3. *{
  4. margin: ;
  5. padding: ;
  6. }
  7. .ysc-header{
  8. font-size: .28rem;
  9. text-align: center;
  10. }
  11. .addAddress input {
  12. height: .8rem;
  13. width: %;
  14. background: #fff;
  15. color: #262e31;
  16. font-size: .3rem;
  17. border: none;
  18. margin: .3rem;
  19. padding: .3rem;
  20. }
  21. /* 地址选择弹层 */
  22. .ac{
  23. color: #!important;
  24. border-bottom: .02rem solid #fff!important;
  25. }
  26. .myAddress{
  27. width: %;
  28. background-color: white;
  29. border-top: 4px solid rgba(,,,);
  30. color:#;
  31. }
  32. .myAddress .cont{
  33. border-bottom: 1px solid rgba(,,,0.8);
  34. }
  35. .myAddress .cont span{
  36. display: inline-block;
  37. font-size: .28rem;
  38. color: #;
  39. line-height: .88rem;
  40. margin-left: .32rem;
  41. }
  42. .myAddress .cont section{
  43. float:left;
  44. }
  45. .myAddress .cont p{
  46. display: inline-block;
  47. font-size: .28rem;
  48. color: #;
  49. line-height: .88rem;
  50. margin-left: 1rem;
  51. }
  52. .myAddress .cont .pic2{
  53. float: right;
  54. width: .14rem;
  55. height: .24rem;
  56. margin: .32rem .32rem .32rem ;
  57. }
  58. .myAddress .cont p.text{
  59. margin-left: .72rem;
  60. }
  61. .address{
  62. position:absolute;
  63. bottom:;
  64. left:;
  65. z-index:;
  66. background:#fff;
  67. width:%;
  68. height: ;
  69. overflow: hidden;
  70. transition: height .5s;
  71. }
  72. .toggHeight{
  73. height: .7rem;
  74. }
  75. .layout{
  76. width:%;
  77. height:%;
  78. position:fixed;
  79. top:;
  80. left:;
  81. z-index:;
  82. opacity: ;
  83. transition: all .5s;
  84. background:rgb(, , );
  85. visibility: hidden;
  86. }
  87. .layoutBg{
  88. opacity: .;
  89. visibility: visible;
  90. }
  91. .area{
  92. float: left;
  93. display:inline-block;
  94. font-size:.24rem;
  95. height: .48rem;
  96. line-height:.48rem;
  97. margin-left:.42rem;
  98. color:#262e31;
  99. margin-top: .31rem;
  100. max-width: calc(% - %);overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
  101. }
  102. .addList{
  103. margin-left: .4rem;
  104. font-size:.3rem;
  105. line-height:.67rem;
  106. color:#262e31;
  107. }
  108. .address ul{
  109. height: calc(% - .82rem);
  110. overflow:auto;
  111. }
  112. .address ul li{
  113. list-style: none;
  114. }
  115. .address .title .accolor{
  116. color: #d2a24e;
  117. border-bottom:.04rem solid #d2a24e;
  118. }
  119. .address ul .active{
  120. color:#d2a24e;
  121. }
  122. .address ul .active span::after{
  123. content: '';
  124. background-image: url(../assets/images/gou_img.png);
  125. width: .4rem;
  126. height: .2rem;
  127. background-repeat: no-repeat;
  128. background-size: .2rem .13rem;
  129. background-position: left .16rem center;
  130. display: inline-block;
  131. }
  132. .title{
  133. height: .82rem;
  134. border-bottom: .01rem solid #8a96a3;
  135. }
  136. .determine{
  137. display: inline-block;
  138. width: .75rem;
  139. text-align: center;
  140. float: right;
  141. height: .82rem;
  142. line-height: .82rem;
  143. margin-right: .3rem;
  144. color: #d2a24e;
  145. font-size: .28rem;
  146. }
  147. </style>

PS:那个地址的JS文件由于太大我就不贴出来了,大家可以去我的github那里下载完整的demo(觉得这个栗子还不错的话,记得给个star哦,么么哒),里面有---->https://github.com/yy-biboy/sanjiliandongDemo

开了一个公众号,喜欢的朋友可以关注一下哦《时间的信箱》

下载demo后执行以下命令即可运行

1、npm install

2、npm run dev

vue省市区三级联动(高仿京东)的更多相关文章

  1. vue省市区三级联动

    仿照小米之家做的一个省市区三级联动,先上代码: HTML: <template> <section class="myAddress"> <secti ...

  2. vue仿京东省市区三级联动选择组件

    工作中需要一个盒京东购物车地址选择相似的一个省市区三级联动选择组件,google查了下都是下拉框形式的,于是自己写了一个,希望对使用vue开发项目的朋友有帮助,显示效果如下:使用vue2.0开发 ht ...

  3. vue 引用省市区三级联动(element-ui Cascader)

    npm 下载 npm install element-china-area-data -S main.js import {provinceAndCityData,regionData,provinc ...

  4. vue 引用省市区三级联动(插件)

    vue 用省市区三级联动之傻瓜式教程(复制粘贴即用) npm 下载 npm install v-distpicker --save main.js //引入 省市区三级联动 import Distpi ...

  5. JS实现年月日三级联动+省市区三级联动+国家省市三级联动

    开篇随笔:最近项目需要用到关于年月日三级联动以及省市区三级联动下拉选择的功能,于是乎网上搜了一些做法,觉得有一些只是给出了小的案例或者只有单纯的js还不完整,却很难找到详细的具体数据(baidu搜索都 ...

  6. 省市区三级联动 pickerView

    效果图 概述 关于 省市区 三级联动的 pickerView,我想大多数的 iOS 开发者应该都遇到过这样的需求.在遇到这样的需求的时候,大多数人都会觉的这个很复杂,一时无从下手.其实真的没那么复杂. ...

  7. QQ JS省市区三级联动

    如下图: 首先写一个静态的页面: <!DOCTYPE html> <html> <head> <title>QQ JS省市区三级联动</title ...

  8. 【转】纯JS省市区三级联动(行政区划代码更新至2015-9-30)

    本文代码实现的功能是省市区三级联动下拉列表,纯Javascript,网上已有很多这方面的代码.但是作为一个新手,这是我的第一篇CSDN博客,发此文的目的主要是学习交流,希望看到的朋友发现有什么不对的地 ...

  9. 插件 原生js 省市区 三级联动 源码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. niuke --abc

    链接:https://ac.nowcoder.com/acm/contest/1083/A来源:牛客网 给出一个字符串s,你需要做的是统计s中子串”abc”的个数.子串的定义就是存在任意下标a< ...

  2. Shell脚本日志关键字监控+告警

    最近小张的爬虫程序越来越多,可当爬虫程序报错,不能及时的发现,从而造成某些重要信息不能及时获取的问题,更有甚者,遭到领导的批评.于是就在想有没有一种方法,当爬取信息报错的时候,可以通过邮件或者短信的方 ...

  3. 从hfctf学习JWT伪造

    本文作者:Ch3ng easy_login 简单介绍一下什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519) ...

  4. vue2.x学习笔记(十三)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12595860.html. 组件的注册 注册组件有一些规范约定与注意事项. 组件名的命名规范 在注册一个组件的时候, ...

  5. Nmap-脚本检测CVE漏洞

    Nmap的一个鲜为人知的部分是NSE,即Nmap Scripting Engine,这是Nmap最强大和最灵活的功能之一.它允许用户编写(和共享)简单脚本,以自动执行各种网络任务.Nmap内置了全面的 ...

  6. python 进阶篇 python 的值传递

    值传递和引用传递 值传递,通常就是拷贝参数的值,然后传递给函数里的新变量,这样,原变量和新变量之间互相独立,互不影响. 引用传递,通常是指把参数的引用传给新的变量,这样,原变量和新变量就会指向同一块内 ...

  7. 大数据并行计算框架Spark

    Spark2.1. http://dblab.xmu.edu.cn/blog/1689-2/ 0+入门:Spark的安装和使用(Python版) Spark2.1.0+入门:第一个Spark应用程序: ...

  8. 全网最全最细的appium自动化测试环境搭建教程以及appium工作原理

    一.前言 ​ 对于appium自动化测试环境的搭建我相信90%的自学者都是在痛苦中挣扎,在挣扎中放弃,在放弃后又重新开始,只有10%的人,人品比较好,能够很快并顺利的搭建成功.appium 自动化测试 ...

  9. PHP如何实现判断提交的是什么方式

    function get_request_method() { // $_SERVER包含了诸多头信息.路径.以及脚本位置等等信息的数组,这个数组中的项目有web服务器创建. if (isset($_ ...

  10. 微信小程序 POST传值跳坑

    来源:https://www.cnblogs.com/ordinaryk/p/8430462.html 加这个就行了: header : { 'content-type': 'application/ ...