当前位置:Gxlcms > JavaScript > vue移动端城市三级联动组件使用详解

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

时间:2021-07-01 10:21:17 帮助过:14人阅读

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

先看效果图

以下组件代码

  1. <template>
  2. <div class="address">
  3. <div class="addressboxbg" @click="cancel"></div>
  4. <div class="addressbox">
  5. <p class="text_btn"><span style="float:left;" @click="cancel">取消</span><span style="float:right;color:#107E52;" @click="complete">完成</span></p>
  6. <div class="addressSelect" >
  7. <div class="selectbox"></div>
  8. <ul @touchstart="touchStart($event,'province')" @touchmove="touchMove($event,'province')" @touchend="touchEnd($event,'province')" :style="provinceStyle" :class="[{'selectAni':addSelect}]">
  9. <li v-for="(item,index) in list" :class="[{'addSelectActive':index == provinceIndex}]" :key="index">{{item.name}}</li>
  10. </ul>
  11. <ul @touchstart="touchStart($event,'city')" @touchmove="touchMove($event,'city')" @touchend="touchEnd($event,'city')" :style="cityStyle" :class="[{'selectAni':addSelect}]">
  12. <li v-for="(item,index) in list2" :class="[{'addSelectActive':index == cityIndex}]" :key="index">{{item.name}}</li>
  13. </ul>
  14. <ul @touchstart="touchStart($event,'district')" @touchmove="touchMove($event,'district')" @touchend="touchEnd($event,'district')" :style="districtStyle" :class="[{'selectAni':addSelect}]">
  15. <li v-for="(item,index) in list3" :class="[{'addSelectActive':index == districtIndex}]" :key="index" >{{item.name}}</li>
  16. </ul>
  17. </div>
  18. </div>
  19. </div>
  20. </template>
  21. <script>
  22. export default {
  23. data () {
  24. return {
  25. list: [],
  26. list2: [],
  27. list3: [],
  28. provinceStyle: {
  29. WebkitTransform: 'translate3d(0px,0px,0px)'
  30. },
  31. cityStyle: {
  32. WebkitTransform: 'translate3d(0px,0px,0px)'
  33. },
  34. districtStyle: {
  35. WebkitTransform: 'translate3d(0px,0px,0px)'
  36. },
  37. startTop: 0,
  38. provinceIndex: 0,
  39. cityIndex: 0,
  40. districtIndex: 0,
  41. translateY: 0,
  42. maxScroll: 0,
  43. addHeight: 0,
  44. addSelect: false,
  45. provinceVal: '',
  46. cityVal: '',
  47. areaVal: '',
  48. val: {
  49. 'provinceVal': '',
  50. 'cityVal': '',
  51. 'areaVal': ''
  52. }
  53. }
  54. },
  55. watch: {
  56. // 监听省滑动
  57. provinceVal (value) {
  58. this.$axiosGet(this.$api.area, {parentId: value}).then((res) => {
  59. if (res.code === 1) {
  60. this.list2 = res.data.length > 1 ? res.data : [{name: '-'}]
  61. if (res.data.length < 1) {
  62. this.list3 = [{name: '-'}]
  63. }
  64. this.cityVal = this.list2[0].value
  65. }
  66. })
  67. },
  68. // 监听市滑动
  69. cityVal (value) {
  70. if (value) {
  71. this.$axiosGet(this.$api.area, {parentId: value}).then((res) => {
  72. if (res.code === 1) {
  73. this.list3 = res.data.length > 1 ? res.data : [{name: '-'}]
  74. }
  75. })
  76. }
  77. }
  78. },
  79. created () {
  80. // 初始化数据
  81. // 拿省的数据
  82. this.$axiosGet(this.$api.area).then((res) => {
  83. if (res.code === 1) {
  84. this.list = res.data
  85. this.val.provinceVal = this.list[0]
  86. }
  87. })
  88. // 拿市区的数据
  89. this.$axiosGet(this.$api.area, {parentId: '1'}).then((res) => {
  90. if (res.code === 1) {
  91. this.list2 = res.data
  92. this.val.cityVal = this.list2[0]
  93. }
  94. })
  95. this.val.areaVal = {
  96. 'name': '',
  97. 'value': ''
  98. }
  99. // 第一条数据为直辖市 so '-' 符号表示为第三列
  100. this.list3 = [{name: '-'}]
  101. },
  102. methods: {
  103. // 点击取消
  104. cancel () {
  105. this.$emit('cancel', false)
  106. },
  107. // 点击完成
  108. complete () {
  109. if (!this.val.areaVal.value) {
  110. this.val.areaVal = {
  111. 'name': '',
  112. 'value': ''
  113. }
  114. }
  115. if (!this.val.cityVal.value) {
  116. this.val.cityVal = {
  117. 'name': '',
  118. 'value': ''
  119. }
  120. }
  121. this.$emit('complete', this.val)
  122. },
  123. // 滑动开始
  124. touchStart (e, val) {
  125. e.preventDefault()
  126. this.addSelect = false
  127. this.addHeight = e.currentTarget.children[0].offsetHeight
  128. this.maxScroll = this.addHeight * e.currentTarget.children.length
  129. this.startTop = e.targetTouches[0].pageY
  130. switch (val) {
  131. case 'province':
  132. this.translateY = parseInt(this.provinceStyle.WebkitTransform.slice(this.provinceStyle.WebkitTransform.indexOf(',') + 1, this.provinceStyle.WebkitTransform.lastIndexOf(',')))
  133. break
  134. case 'city':
  135. this.translateY = parseInt(this.cityStyle.WebkitTransform.slice(this.cityStyle.WebkitTransform.indexOf(',') + 1, this.cityStyle.WebkitTransform.lastIndexOf(',')))
  136. break
  137. case 'district':
  138. this.translateY = parseInt(this.districtStyle.WebkitTransform.slice(this.districtStyle.WebkitTransform.indexOf(',') + 1, this.districtStyle.WebkitTransform.lastIndexOf(',')))
  139. break
  140. default:
  141. break
  142. }
  143. },
  144. // 滑动进行中
  145. touchMove (e, val) {
  146. e.preventDefault()
  147. switch (val) {
  148. case 'province':
  149. if ((e.targetTouches[0].pageY - this.startTop + this.translateY) > 0) {
  150. this.provinceStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
  151. } else if ((e.targetTouches[0].pageY - this.startTop + this.translateY) < -(this.maxScroll - this.addHeight)) {
  152. this.provinceStyle.WebkitTransform = 'translate3d(0px,' + -(this.maxScroll - this.addHeight) + 'px,0px)'
  153. } else {
  154. this.provinceStyle.WebkitTransform = 'translate3d(0px,' + (e.targetTouches[0].pageY - this.startTop + this.translateY) + 'px,0px)'
  155. }
  156. break
  157. case 'city':
  158. if ((e.targetTouches[0].pageY - this.startTop + this.translateY) > 0) {
  159. this.cityStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
  160. } else if ((e.targetTouches[0].pageY - this.startTop + this.translateY) < -(this.maxScroll - this.addHeight)) {
  161. this.cityStyle.WebkitTransform = 'translate3d(0px,' + -(this.maxScroll - this.addHeight) + 'px,0px)'
  162. } else {
  163. this.cityStyle.WebkitTransform = 'translate3d(0px,' + (e.targetTouches[0].pageY - this.startTop + this.translateY) + 'px,0px)'
  164. }
  165. break
  166. case 'district':
  167. if ((e.targetTouches[0].pageY - this.startTop + this.translateY) > 0) {
  168. this.districtStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
  169. } else if ((e.targetTouches[0].pageY - this.startTop + this.translateY) < -(this.maxScroll - this.addHeight)) {
  170. this.districtStyle.WebkitTransform = 'translate3d(0px,' + -(this.maxScroll - this.addHeight) + 'px,0px)'
  171. } else {
  172. this.districtStyle.WebkitTransform = 'translate3d(0px,' + (e.targetTouches[0].pageY - this.startTop + this.translateY) + 'px,0px)'
  173. }
  174. break
  175. default:
  176. break
  177. }
  178. },
  179. // 滑动结束
  180. touchEnd (e, val) {
  181. e.preventDefault()
  182. this.addSelect = true
  183. switch (val) {
  184. case 'province':
  185. let provinceTranslateY = parseInt(this.provinceStyle.WebkitTransform.slice(this.provinceStyle.WebkitTransform.indexOf(',') + 1, this.provinceStyle.WebkitTransform.lastIndexOf(',')))
  186. this.provinceIndex = -Math.round(provinceTranslateY / this.addHeight)
  187. this.provinceStyle.WebkitTransform = 'translate3d(0px,' + (Math.round(provinceTranslateY / this.addHeight) * this.addHeight) + 'px,0px)'
  188. this.cityStyle.WebkitTransform = this.districtStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
  189. this.cityIndex = this.districtIndex = 0
  190. break
  191. case 'city':
  192. let cityTranslateY = parseInt(this.cityStyle.WebkitTransform.slice(this.cityStyle.WebkitTransform.indexOf(',') + 1, this.cityStyle.WebkitTransform.lastIndexOf(',')))
  193. this.cityIndex = -Math.round(cityTranslateY / this.addHeight)
  194. this.cityStyle.WebkitTransform = 'translate3d(0px,' + (Math.round(cityTranslateY / this.addHeight) * this.addHeight) + 'px,0px)'
  195. this.districtStyle.WebkitTransform = 'translate3d(0px,0px,0px)'
  196. this.districtIndex = 0
  197. break
  198. case 'district':
  199. let districtTranslateY = parseInt(this.districtStyle.WebkitTransform.slice(this.districtStyle.WebkitTransform.indexOf(',') + 1, this.districtStyle.WebkitTransform.lastIndexOf(',')))
  200. this.districtIndex = -Math.round(districtTranslateY / this.addHeight)
  201. this.districtStyle.WebkitTransform = 'translate3d(0px,' + (Math.round(districtTranslateY / this.addHeight) * this.addHeight) + 'px,0px)'
  202. break
  203. default:
  204. break
  205. }
  206. // 滑动结束后 处理数据
  207. this.dataProcessing()
  208. },
  209. // 数据处理
  210. dataProcessing () {
  211. // 滑动数据传输 数据处理
  212. this.val.provinceVal = this.list[this.provinceIndex]
  213. this.provinceVal = this.list[this.provinceIndex].value
  214. this.val.cityVal = this.list2[this.cityIndex]
  215. this.cityVal = this.list2[this.cityIndex].value
  216. this.val.areaVal = this.list3[this.districtIndex]
  217. this.areaVal = this.list3[this.districtIndex].value
  218. // this.val.cityVal = this.addressData[this.provinceIndex].city[this.cityIndex].name
  219. // this.val.areaVal = this.addressData[this.provinceIndex].city[this.cityIndex].area[this.districtIndex]
  220. // this.$emit('getAddress', this.val)
  221. // this.test([this.val.provinceVal, this.cityIndex, this.districtIndex])
  222. }
  223. }
  224. }
  225. </script>
  226. <style>
  227. .address{
  228. position:absolute;
  229. top: 0px;
  230. bottom: 0px;
  231. left: 0px;
  232. right: 0px;
  233. }
  234. .address .addressbox{
  235. height: 40%;
  236. position: absolute;
  237. z-index: 101;
  238. width: 100%;
  239. max-height: 100%;
  240. overflow: hidden;
  241. background: #fff;
  242. bottom: 0px;
  243. }
  244. .address .addressbox .text_btn{
  245. height: 30px;
  246. font-size: 14px;
  247. line-height: 30px;
  248. border-top: 1px solid #ccc;
  249. border-bottom: 1px solid #ccc;
  250. padding: 0 10px;
  251. background: #F9F9F9;
  252. }
  253. .addressSelect .selectbox{
  254. width: 100%;
  255. height: 26px;
  256. border-top: 1px solid #ccc;
  257. border-bottom: 1px solid #ccc;
  258. margin-top: 60px;
  259. background: #F9F9F9;
  260. }
  261. .address .addressboxbg{
  262. position: absolute;
  263. left: 0;
  264. top: 0;
  265. z-index: 100;
  266. width: 100%;
  267. height: 100%;
  268. background: rgba(0,0,0,.7);
  269. }
  270. .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;}
  271. .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;}
  272. .addressSelect ul li{white-space : nowrap;overflow: hidden; text-overflow:ellipsis; color:rgba(0,0,0,.54); padding: 3px 0;}
  273. .addressSelect ul:nth-of-type(2){left: 33.333333%;}
  274. .addressSelect ul:nth-of-type(3){left: 66.666666%;}
  275. .addressSelect ul li.addSelectActive{color:rgba(0,0,0,.87); transform: scale(1.1); transition: 0.5s;}
  276. .selectAni{transition: 0.8s;}
  277. </style>

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

人气教程排行