首页 技术 正文
技术 2022年11月15日
0 收藏 610 点赞 5,007 浏览 5182 个字

项目地址:

https://github.com/caochangkui/vue-cli3

项目代码:

城市列表首页:

City.vue

<template>
<div id="city">
<!-- <img src="/logo.png" alt="" height="10px"> -->
<div class="word" v-show="showWord">
<span>{{letter}}</span>
</div>
<div class="title">城市选择</div>
<city-list
:cities="cities"
:hot="hotCities"
:letter="letter"
></city-list>
<city-alphabet
:cities="cities"
@change="handleLetterChange"
></city-alphabet>
</div>
</template><script>
import axios from 'axios'
import CityList from './components/List'
import CityAlphabet from './components/Alphabet'
export default {
name: 'City',
components: {
CityList,
CityAlphabet
},
data () {
return {
showWord: false,
cities: {},
hotCities: [],
letter: ''
}
},
methods: {
getCityInfo () {
axios.get('/mock/city.json').then(this.handleGetCityInfoSucc)
},
handleGetCityInfoSucc (res) {
console.log(res.data)
res = res.data
if (res.ret && res.data) {
const data = res.data
this.cities = data.cities
this.hotCities = data.hotCities
}
},
handleLetterChange (letter) {
console.log(letter)
this.letter = letter
this.showWord = true
setTimeout(() => {
this.showWord = false
console.log(this.showWord)
}, 500)
}
},
mounted () {
this.getCityInfo()
}
}
</script><style scoped>
.title {
line-height: 40px;
background: #10d1eb;
color: #fff;
}
.word {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
z-index: 99;
}
.word span {
display: inline-block;
height: 60px;
width: 60px;
background: rgba(0, 0, 0, .2);
display: flex;
justify-content: center;
align-items: center;
}
</style>

城市列表组件:

List.vue

<template>
<div class="list" ref="wrapper">
<div>
<div class="area">
<div class="title">当前城市</div>
<div class="button-list">
<div class="button-wrapper">
<div class="button">{{this.currentCity}}</div>
</div>
</div>
</div>
<div class="area">
<div class="title">热门城市</div>
<div class="button-list">
<div
class="button-wrapper"
v-for="item in hot"
:key="item.id"
@click="handleCityClick(item.name)"
>
<div class="button">{{item.name}}</div>
</div>
</div>
</div>
<div
class="area"
v-for="(item, index) in cities"
:key="index"
:ref="index"
>
<div class="title">{{index}}</div>
<div
class="item-list"
v-for="innerItem in item"
:key=innerItem.id
@click="handleCityClick(innerItem.name)"
>
<div class="item"> {{innerItem.name}} </div>
</div>
</div>
</div>
</div>
</template><script>
import Bscroll from 'better-scroll'
import { mapState, mapMutations } from 'vuex'
export default {
name: 'CityList',
props: {
hot: Array,
cities: Object,
letter: String
},
data () {
return { }
},
computed: {
...mapState({
currentCity: 'city'
})
},
watch: {
// 监听 Alphabet 中传过来的letter,如有变化,则滚动区域自动滚动到对应元素上
letter () {
if (this.letter) {
const element = this.$refs[this.letter][0] // 获取对应字母的ref
this.scroll.scrollToElement(element) // 利用better-scroll插件 滚动到指定元素element
console.log(element)
}
}
},
methods: {
...mapMutations(['changeCity']),
handleCityClick (city) {
console.log(city)
// this.$store.commit('changeCity', city) // 将参数city传给vuex中的mutations中的changeCity函数
this.changeCity(city)
this.$router.push('/') // 页面跳转 参考
}
},
mounted () {
this.scroll = new Bscroll(this.$refs.wrapper, {
click: true
})
},}
</script><style scoped>
.list {
position: absolute;
top: 40px;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.title {
line-height: 40px;
background: #eee;
padding-left: 10px;
color: #666;
font-size: 14px;
text-align: left;
}
.button-list {
overflow: hidden;
padding: 10px 30px 10px 10px;
}
.button-wrapper {
float: left;
width: 33.33%;
}
.button {
margin: 4px;
padding: 4px 0;
text-align: center;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
color: #555;
}
.item {
line-height: 40px;
padding-left: 16px;
text-align: left;
border-bottom: 1px solid #eee;
}
</style>

字母检索组件:

Alphabet.vue

<template>
<div class="list-wrapper">
<ul class="list">
<li class="item"
v-for="item of letters"
:key="item"
:ref="item"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
@click="handleLetterClick"
>{{item}}</li>
</ul>
</div>
</template><script>
export default {
name: 'CityAlphabet',
props: {
cities: Object
},
data () {
return {
touchStatus: false,
startY: 0,
timeer: null
}
},
computed: {
letters () {
const letters = []
for (let i in this.cities) {
letters.push(i)
}
return letters
}
},
// 生命周期函数
updated () {
this.startY = this.$refs['A'][0].offsetTop // A字母距离滚动条顶部距离
console.log('updated---> ', this.startY)
},
methods: {
handleLetterClick (e) {
this.$emit('change', e.target.innerText)
console.log(1)
},
handleTouchStart () {
console.log('开始滑动')
this.touchStatus = true
},
handleTouchMove (e) {
if (this.touchStatus) {
if (this.timeer) {
clearTimeout(this.timeer)
}
this.timeer = setTimeout(() => {
console.log(e.touches[0])
const touchY = e.touches[0].clientY - 40 // 手指触摸当前位置距离视口顶部的距离减去40(40指滚动区域最上边和页面顶部之间的距离)
const index = Math.floor((touchY - this.startY) / 26) // 手指触摸当前位置所在的字母索引(26指单个字母的高度)
if (index >= 0 && index < this.letters.length) {
this.$emit('change', this.letters[index])
}
}, 16)
}
},
handleTouchEnd () {
this.touchStatus = false
}
}
}
</script><style scoped>
.list {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
right: 0;
top: 40px;
bottom: 0;
width: 30px;
list-style: none;
background: rgba(0, 0, 0, .2);
margin: 0;
padding: 0;
z-index: 999;
}
.item {
line-height: 24px;
color: #068b9c;
font-size: 14px;
text-align: center;
width: 100%;
}</style>

通过vuex管理已选城市:

import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)let defaultCity = '北京'try {
if (localStorage.city) {
defaultCity = localStorage.city
}
} catch (e) {e}const state = {
count: 1,
city: defaultCity
}const mutations = {
changeCity (state, city) {
state.city = city
try {
localStorage.city = city
} catch (e) {e}
}
}const actions = { }export default new Vuex.Store({
state,
mutations,
actions
})
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,992
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,506
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,349
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,134
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,767
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,844