效果:
用到 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!`))