<template>
<div>
<van-index-bar :index-list="computedCityList">
<div v-for="data in cityList" :key="data.type">
<van-index-anchor :index="data.type" />
<van-cell @click="handleChangePage(item)" :title="item.name" :key="item.cityId" v-for="item in data.list"></van-cell>
</div>
</van-index-bar>
</</template>
van-index-bar
:这是一个带有索引的列表组件,index-list
属性绑定了计算属性computedCityList
,用于显示索引。v-for="data in cityList"
:遍历cityList
,每个data
代表一个按字母分组的城市列表。van-index-anchor
:显示当前组的索引字母。van-cell
:显示每个城市的名字,点击后调用handleChangePage
方法。
<script>
import http from '../utils'
import { mapMutations } from 'vuex'
export default {
data() {
return {
cityList: []
}
},
mounted() {
// 获取城市的数据
http({
url: '/gateway?k=2323064',
headers: {
'X-Host': 'mall.film-ticket.city.list'
}
}).then(({ data }) => {
this.handleCityData(data.data.cities)
})
},
computed: {
computedCityList() {
return this.cityList.map(item => item.type)
}
},
methods: {
...mapMutations(['changeCityData']),
// 组装城市列表数据
handleCityData (data) {
// console.log(data, 'data')
// 将数组处理成一个二位数组
const letterArr = []
for (let code = 65; code < 91; code++) {
letterArr.push(String.fromCharCode(code))
}
const newCities = []
letterArr.forEach(letter => {
const list = data.filter(item => {
return item.pinyin.substring(0, 1).toUpperCase() === letter
})
// 获取到每一个字母开头的城市数据
if (list.length) {
newCities.push({
type: letter,
list
})
}
})
this.cityList = newCities
console.log(newCities, 'newCities')
},
handleChangePage(item) {
this.changeCityData(item)
this.$router.back()
}
}
}
</script>
<script>
// import { mapActions, mapMutations, mapState } from 'vuex'
import { mapActions, mapState } from 'vuex'
import BetterScroll from 'better-scroll'
export default {
data() {
return {
height: 0
}
},
methods: {
...mapActions(['getCinemaList']),
onClickRight() {
this.$router.push('/cinema/search')
},
onClickLeft() {
this.$router.push('/city')
}
},
computed: {
...mapState({
cinemaList: state => state.Cinema.cinemaList,
cityName: state => state.City.cityName,
cityId: state => state.City.cityId
})
},
mounted() {
this.height = document.documentElement.clientHeight - 96 + 'px'
if (!this.cinemaList.length) {
this.getCinemaList(this.cityId)
}
this.$nextTick(() => {
new BetterScroll('.cinema', {
scrollbar: {
fade: true
}
})
})
}
}
</script>
<style lang="less" scoped>
.cinema {
height: 300px;
overflow: hidden;
position: relative;
li {
padding: 5px;
.address {
font-size: 12px;
color: gray
}
}
}
</style>
`` `.cinema`: 设置影院列表的默认高度、隐藏溢出内容、定位为相对位置。
- `li`: 设置每个列表项的内边距。
- `.address`: 设置地址文本的字体大小和颜色。
data()
:定义了组件的初始数据,这里只有一个空数组cityList
。mounted()
:组件挂载后执行,通过HTTP请求获取城市数据,并调用handleCityData
方法处理数据。computedCityList()
:计算属性,返回cityList
中所有分组的类型(即字母索引)。handleCityData(data)
:处理从服务器获取的城市数据,将其按首字母分组。letterArr
:生成A-Z的字母数组。newCities
:存储按字母分组后的城市数据。- 遍历
letterArr
,对每个字母过滤出对应的城市,并将其添加到newCities
中。
handleChangePage(item)
:当用户点击某个城市时,调用此方法,将选中的城市数据存储,并返回上一页。-
<template> <div> <!-- 导航栏 --> <van-nav-bar title="标题" @click-left="onClickLeft" @click-right="onClickRight" > <!-- 导航栏左侧内容 --> <template #left> {{cityName}}<van-icon color="black" name="arrow-down" /> </template> <!-- 导航栏右侧内容 --> <template #right> <van-icon size="23" color="black" name="search" /> </template> </van-nav-bar> <!-- 影院列表 --> <div class="cinema" :style="{ height: height }"> <ul> <li v-for="data in cinemaList" :key="data.cinemaId"> <div>{{ data.name }}</div> <div class="address">{{ data.address }}</div> </li> </ul> </div> </div> </template>
<van-nav-bar>
: 使用Vant组件导航栏组件,用于展示标题,并在两侧分别提供了点击事件。@click-left
: 点击导航栏左侧时触发的事件。@click-right
: 点击导航栏右侧时触发的事件。<template #left>
: 导航栏左侧显示内容,显示城市名称和一个向下箭头图标。<template #right>
: 导航栏右侧显示内容,显示一个搜索图标。:style="{ height: height }"
: 影院列表的高度绑定到一个变量height
上。v-for="data in cinemaList"
: 遍历cinemaList
数组,为每个电影院数据创建一个列表项。:key="data.cinemaId"
: 为每个列表项指定一个唯一的key,以提高渲染性能。import { mapActions, mapState } from 'vuex'
: 从Vuex导入mapActions
和State`,用于绑定actions和state到组件的methods和computed属性。import BetterScroll from 'better-scroll'
: 导入better-scroll
插件,用于增强滚动体验。data()
: 返回一个包含height
属性的对象,用于控制影院列表的高度。methods
: 包含mapActions
映射的getCinemaList
方法和导航点击事件onClickRight
、onClickLeft
。onClickRight
: 当点击导航栏右侧图标时,路由跳转到影院搜索页面。onClickLeft
: 当点击导航栏左侧图标时,路由跳转到城市选择页面。
computed
: 包含从Vuex store映射的状态cinemaList
、cityName
、cityId
。mounted()
: 在组件挂载后,设置height
属性为页面高度减去96像素,如果影院列表为空,则调用getCinemaList
方法获取数据,并初始化better-scroll
插件。