vue仿饿了么选择城市地址自动滚动

效果:
在这里插入图片描述

用到 vue axios better-scroll (这里我全部用得cdn引入) node.js express

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
		<script src="https://unpkg.com/better-scroll/dist/bscroll.min.js"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
		<style>
			#app {
				height: 100vh;
				width: 100vw;
				box-sizing: border-box;
				padding: 10px;
				overflow: hidden;
			}
			.wrap {
				/* height: 100%; */
				overflow: auto;
			}
			.city_wrap .title {
				font-size: 14px;
				color: #aaa;
				padding-left: 10px;
			}
			.city_wrap .hot_city {
				display: flex;
				padding: 0 16px;
				margin-top: 20px;
				flex-wrap: wrap;
			}
			.city_wrap .hot_city li {
				width: 30%;
				padding: 10px;
				text-align: center;
				box-sizing: border-box;
				background: #f1f1f1;
				margin: 0 10px 10px 0;
				font-size: 14px;
			}
			.city_title {
				color: #aaa;
				padding: 15px 0;
			}
			.city_item {
				padding: 10px;
				border-bottom: 1px solid #eee;
				font-size: 14px;
			}
			.scroll_keys {
				position: fixed;
				right: 0;
				top: 25%;
				color: #aaa;
				font-size: 12px;
				line-height: 1.4;
				text-align: center;
				padding: 0 5px;
			}
		</style>
	</head>
	<body>
		<div id="app" ref="area_scroll">
			<div class="wrap">
				<!-- 热门城市 -->
				<div class="city_wrap citylist">
					<div class="title">热门城市</div>
					<ul class="hot_city">
						<li :key="index" v-for="(item,index) in cityInfo.hotCities">
							{{item.name}}
						</li>
					</ul>
				</div>
				<!-- 所有城市 -->
				<div class="all_city">
					<div class="city_keys">
						<!-- 城市首字母 -->
						<div
							class="city_alpha citylist"
							v-for="(item,index) in keys"
							:key="index"
						>
							<div class="city_title">{{item}}</div>
							<!-- 首字母对应的城市 -->
							<div
								class="city_item"
								v-for="(city,index1) in cityInfo[item]"
								:key="index1"
							>
								{{city.name}}
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="scroll_keys">
				<div @click="selectKey(0)">#</div>
				<div @click="selectKey(index+1)" v-for="(item,index) in keys">
					{{item}}
				</div>
			</div>
		</div>
	</body>
	<script>
		let url = 'http://localhost:3000/address'

		let vm = new Vue({
			el: '#app',
			data: {
				cityInfo: {}, //城市信息
				keys: [], //城市首字母
				scroll: null,
			},
			created() {
				this.getCityInfo()
			},
			methods: {
				async getCityInfo() {
					const res = await axios.get(url)
					this.cityInfo = res.data
					// 处理key值  注释①
					this.keys = Object.keys(res.data)
					//处理掉最后数组中的最后一个值 hotcities
					this.keys.pop()
					//对数组进行排序
					this.keys.sort()
					console.log(this.keys)
					//注释②
					this.$nextTick(() => {
            //在页面发生变化之后再初始化
						this.initScroll()
					})
				},
				//实例化better-scroll
				initScroll() {
					this.scroll = new BScroll(this.$refs.area_scroll, { click: true })
				},
				selectKey(index) {
				//注释③
					let el = document.querySelectorAll('.citylist')
					this.scroll.scrollToElement(el[index], 250)
			},
		})
	</script>
</html>

注释①:res.data的值如下图所示,所以我们需要用object.keys得到key值在这里插入图片描述得到之后得到一个数组如下图所示在这里插入图片描述
然后我们处理掉数组的最后一个值 再对数组进行排序。

注释② 这里必须要等数据渲染完了 再给better-scroll进行初始化。这就用到了$nextTick

注释③

scrollToElement(el, time, offsetX, offsetY, easing)

  • 参数:
  • {DOM | String} el 滚动到的目标元素, 如果是字符串,则内部会尝试调用 querySelector 转换成 DOM 对象。
  • {Number} time 滚动动画执行的时长(单位 ms)
  • {Number | Boolean} offsetX 相对于目标元素的横轴偏移量,如果设置为 true,则滚到目标元素的中心位置
  • {Number | Boolean} offsetY 相对于目标元素的纵轴偏移量,如果设置为 true,则滚到目标元素的中心位置
  • {Object} easing 缓动函数,一般不建议修改,如果想修改,参考源码中的 ease.js 里的写法
  • 作用:滚动到指定的目标元素

接口是自己用node.js写了一个

const express = require('express')
const app = express()
const port = 3000
const fs = require('fs')

app.get('/address', (req, res) => {
	var data = fs.readFileSync('address.json', 'utf-8') //address.json 就是数据
	res.send(data)
})
app.listen(port, () => console.log(`Example app listening on port port!`))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值