前面,我们将页面布局实现了。现在开始,我们要实现页面逻辑了。
本篇,我们将实现城市选择页面的动态数据渲染。
通过ajax 获得json 数据。
首先,新建一个分支 city-ajax ,pull 下来,在新分支上写代码。
好啦。
先把模拟数据city.json 放在static/mock 下面。
与首页相似,我们把ajax 请求放在city 页面上,这样只要请求一次即可。
我们在City.vue 文件中加入代码,如下。
<template>
<div>
<city-header></city-header>
<city-search></city-search>
<city-list :cities="cities" :hot="hotCities"></city-list>
<city-alphabet></city-alphabet>
</div>
</template>
<script>
import axios from 'axios'
import CityHeader from './components/Header.vue'
import CitySearch from './components/Search.vue'
import CityList from './components/List.vue'
import CityAlphabet from './components/Alphabet.vue'
export default {
name: 'City',
components: {
CityHeader,
CitySearch,
CityList,
CityAlphabet
},
data () {
cities: {}
hotCities: []
},
methods: {
getCityInfo () {
axios.get('/api/city.json')
.then(this.handleGetCityInfoSucc)
},
handleGetCityInfoSucc (res) {
res = res.data
if (res.ret && res.data) {
const data = res.data
this.cities = data.cities
this.hotCities = data.hotCities
}
}
},
mounted () {
this.getCityInfo()
}
}
</script>
<style lang="stylus" scoped>
</style>
然后去子组件,接收一下父组件传的数据。List.vue 代码如下。
<template>
<div class="list" ref="wrapper">
<div>
<div class="area">
<div class="title border-topbottom">当前城市</div>
<div class="button-list">
<div class="button-wraper">
<div class="button">北京</div>
</div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">热门城市</div>
<div class="button-list">
<div class="button-wraper" v-for="item of hot" :key="item.id">
<div class="button">{{item.name}}</div>
</div>
</div>
</div>
<div class="area" v-for="(item,key) of cities" :key="key">
<div class="title border-topbottom">{{key}}</div>
<div class="item-list">
<div
class="item border-bottom"
v-for="innerItem of item"
:key="innerItem.id"
>
{{innerItem.name}}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Bscroll from 'better-scroll'
export default {
name: 'CityList',
props: {
cities: Object,
hot: Array
},
mounted () {
this.scroll = new Bscroll(this.$refs.wrapper)
}
}
</script>
<style lang="stylus" scoped>
@import '~styles/variables.styl'
.border-topbottom
&:before
border-color: #ccc
&:after
border-color: #ccc
.border-bottom
&:before
border-color: #ccc
.list
position: absolute
top: 1.58rem
left: 0
right: 0
bottom: 0
overflow: hidden
.title
line-height: .54rem
background: #eee
padding-left: .2rem
color: #666
font-size: .26rem
.button-list
overflow: hidden
padding: .1rem .6rem .1rem .1rem
.button-wraper
float: left
width: 33.33%
.button
text-align: center
margin: .1rem
padding: .1rem 0
border: .02rem solid #ccc
border-radius: .06rem
.item-list
.item
line-height: .76rem
padding-left: .2rem
</style>
最后再去更新一下字母表组件。首先把cities 传给alphabet 组件,然后在组件中调整一下,Alphabet.vue 代码如下。
<template>
<ul class="list">
<li
class="item"
v-for="(item,key) of cities"
:key="key"
>
{{key}}
</li>
</ul>
</template>
<script>
export default {
name: 'CityAlphabet',
props: {
cities: Object
}
}
</script>
<style lang="stylus" scoped>
@import '~styles/variables.styl'
.list
display: flex
flex-direction: column
justify-content: center
position: absolute
top: 1.5rem
right: 0
bottom: 0
width: .4rem
.item
line-height: .4rem
text-align: center
color: $bgColor
</style>
好啦。提价并合并即可。