城市选择页面路由配置
页面跳转
src\pages\home\components\Header.vue中 router-link to="/city"
实现点击右上角页面跳转
1 2 3 4 5 6 <router-link to ="/city" > <div class ="header-right" > {{ this.city }} <span class ="iconfont arrow-cron" >  </span > </div > </router-link >
这里router-link会使字体颜色发生变化,这是因为router-link在div外层加了个a标签,我们可以给header-right加一个颜色color:#fff
src\pages\city\components\Header.vue代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <template > <div class ="header" > 城市选择 <router-link to ="/" > <div class ="iconfont header-back" >  </div > </router-link > </div > </template > <script > export default { name: "CityHeader" };</script > <style lang ="stylus" scoped > @import '~styles/varibles.styl' ; .header position : relative overflow :hidden height : $headerHeight line-height :$headerHeight text-align :center color :#fff background :$bgColor font-size :.32rem .header-back top :0 left :0 position :absolute width 0.64rem text-align :center font-size :.4rem color :#fff </style >
src\pages\city\City.vue引入使用上面的组件
1 2 3 4 5 6 7 8 9 10 11 12 13 <template > <div > <city-header > </city-header > </div > </template > <script > import CityHeader from "./components/Header"; export default { name : "City" , components: { CityHeader, } , }
搜索框布局
src\pages\city\components\Search.vue代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <template > <div class ="search"> <input v-model="keyword" class ="search-input" type ="text" placeholder="输入城市名或拼音" /> </template > <script> export default { name : "CitySearch", }</script> <style lang="stylus" scoped> @import '~styles/varibles.styl' ; .search height:0.72 rem padding:0 .1 rem background:$bgColor .search -input box -sizing:border-box width :100 % height: 0.62 rem padding:0 .1 rem line -height :.62 rem text -align :center border-radius: 0.06 rem color:#666 .search -content z-index :1 overflow :hidden position:absolute top: 1.58 rem right:0 left:0 bottom:0 background:#eee .search -item line -height :.62 rem padding-left :.2 rem color:#666 background:#fff </style>
列表布局
部分代码样式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <template> <div class ="list" ref ="wrapper" > <div > <div class ="area" > <div class ="title border-topbottom" >当前城市</div > <div class ="buttom-list" > <div class ="buttom-wrapper" > <div class ="button" >北京</div > </div > </div > </div > <div class ="area" > <div class ="title border-topbottom" >热门城市</div > <div class ="buttom-list" > <div class ="buttom-wrapper" 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" :ref ="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> <style lang="stylus" scoped> @import '~styles/varibles.styl'; .header display:flex line-height: $headerHeight background: $bgColor color: .header-left width .64 rem float:left .back -icon text -align:center font-size:.4 rem .header-input flex:1 line-height:.64 rem height: .64 rem margin-top: .12 rem margin-left: .2 rem padding-left:.2 rem background: border-radius: .1 rem color: .header-right width: 1.24 rem float:right text -align:center color: .arrow-icon margin-left :-.04 rem font-size :.24 rem </style>
问题:列表布局中.list加了一个绝对定位和overflow:hidden这会导致页面是无法拖动的
解决:我们可以使用一个第三方的包Better-scroll
Github地址
安装
1 npm install better-scroll --save
使用(符合这个dom结构)
BetterScroll的最常见应用场景是列表滚动。让我们看看它的HTML:
1 2 3 4 5 6 7 8 <div class ="wrapper" > <ul class ="content" > <li > ...</li > <li > ...</li > ... </ul >
具体使用
1 import Bscroll from "better-scroll" ;
1 2 3 4 5 6 <div class ="list" ref ="wrapper"> //ref 帮助我们获取该dom元素 //生命周期函数,载入后 mounted() { this.scroll = new Bscroll(this.$refs.wrapper ); },
效果:上拉与下拉能够实现,并且有弹性动画效果,非常流畅
字母表布局
创建组件src\pages\city\components\Alphabet.vue
部分代码样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <template > <ul class ="list" > <li class ="item" > {{ item }} </li > </ul > </template > <script > export default { name: "CityAlphabet", } </script > <style lang ="stylus" scoped > @import '~styles/varibles.styl'; .list display:flex flex-direction :column justify-content :center position:absolute top 1.58rem right 0 bottom:0 width 0.4rem .item text-align:center line-height :.4rem color:$bgColor </style >
城市列表页面动态数据渲染 利用ajax获取数据
准备好的本地模拟数据
ajax请求一般我们会放在最外层组件中获取,这样一次就能够获取到所有组件需要的内容
src\pages\city\City.vue这里我们在City.vue中发送
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <template > <div > <city-header > </city-header > <city-search :cities ="cities" > </city-search > <city-list :cities ="cities" :hot ="hotCities" :letter ="letter" > </city-list > <city-alphabet :cities ="cities" @change ="handLetterChange" > </city-alphabet > </div > </template > <script > import axios from "axios" ;import CityHeader from "./components/Header" ;import CitySearch from "./components/Search" ;import CityList from "./components/List" ;import CityAlphabet from "./components/Alphabet" ;export default { name: "City" , components: { CityHeader, CitySearch, CityList, CityAlphabet }, methods: { getCityInfo ( ) { axios.get("/api/city.json" ).then(this .handleGetCityIngoSucc); }, handleGetCityIngoSucc (res ) { res = res.data; if (res.ret && res.data) { const data = res.data; this .cities = data.cities; this .hotCities = data.hotCities; } }, handLetterChange (letter ) { this .letter = letter; } }, data ( ) { return { cities: {}, hotCities: [], letter: "" }; }, mounted ( ) { this .getCityInfo(); } };</script >
父组件向子组件传数据
例:
1 <city-list :cities="cities" :hot="hotCities" :letter="letter" ></city-list>
子组件通过props接收
1 2 3 4 5 6 7 export default { name: "CityList" , props: { hot: Array, cities: Object, letter: String },
v-for渲染数据
循环数组
1 2 3 <div class ="buttom-wrapper" v-for ="item of hot" :key="item.id" > <div class ="button" >{{ item .name }}</div > </div >
循环对象(这里我们使用了二次循环)
1 2 3 4 5 6 7 8 9 10 11 12 <div class ="area" v-for ="(item, key) of cities" :key="key" :ref ="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 >