数据形式:
{
"ret": true,
"data": {
"sightName": "迪士尼小镇",
"bannerImg": "http://img1.qunarzz.com/sight/p0/1707/82/821428e3bbf93bbaa3.water.jpg_600x330_2385695d.jpg",
"galleryImgs": ["http://img1.qunarzz.com/sight/p0/1707/c2/c2be8d6326cdea1a3.water.jpg_r_800x800_97e80887.jpg", "http://img1.qunarzz.com/sight/p0/1707/c4/c48e92049336b8ffa3.water.jpg_r_800x800_42a54b54.jpg"],
"categoryList": [{
"title": "成人票",
"children": [{
"title": "成人三人团票",
"children": [{
"title": "成人三人团票-亲情套餐"
}]
}, {
"title": "成人五人团票"
}]
}, {
"title": "学生票"
}, {
"title": "儿童票"
}, {
"title": "特惠票"
}]
}
}
在Detail.vue中借助ajax请求: 借用生命周期钩子来实现。
methods: {
getDetailInfo () {
axios.get('/api/detail.json')
}
},
mounted() {
this.getDetailInfo()
}
使用ajax请求要记得引入axios。此外,我们每次请求不同的详情页的时候,希望将对应的id带给后端,以此来获取不同详情页面的数据。 而这个id是动态路由的一个参数,在路由定义中是这样的:
path: '/detail/:id',
name: 'Detail',
component: Detail
上面的这个动态路由会把对应的id存放在id的这个变量当中,在页面上就可以这样写:axios.get('/api/detail.json?id=' + this.$route.params.id)
, 但是这样写太麻烦,换一种写法:
axios.get('/api/detail.json', {
params: {
id: this.$route.params.id
}
})
当ajax数据获取完毕之后就可以then了:
methods: {
getDetailInfo () {
axios.get('/api/detail.json', {
params: {
id: this.$route.params.id
}
}).then(this.handleGetDataSucc)
},
handleGetDataSucc (res) {
var res = res.data
if (res.ret && res.data) {
const data = res.data
this.sightName = data.sightName
this.bannerImg = data.bannerImg
this.galleryImgs = data.galleryImgs
this.list = data.categoryList
}
}
}
res就是获取到的数据,然后将这些获得的数据以属性的形式分别传递给子组件。
<div>
<detail-banner
:sightName="sightName"
:bannerImg="bannerImg"
:bannerImgs="galleryImgs"
>detail-banner>
<detail-header>detail-header>
<div class="content">
<detail-list :list="list">detail-list>
div>
div>
子组件接收数据:
Banner.vue中接收:
props: {
sightName: String,
bannerImg: String,
bannerImgs: Array
}
数据替换:
<div>
<div class="banner" @click="handleBannerClick">
<img class="banner-img" :src="bannerImg" alt="">
<div class="banner-info">
<div class="banner-title">
{{ this.sightName }}
div>
<div class="banner-number">
<span class="iconfont banner-icon">span>
{{ this.bannerImgs.length }}
div>
div>
div>
<common-gallery
:imgs="bannerImgs"
v-show="showGallery"
@close="handleBannerGallery"
>common-gallery>
div>
完成上面的数据替换,依然能够呈现出想要的效果。
但是,在页面上点击详情页的时候会发现,当我点击第一个详情页的时候它发了id为0001的ajax数据,而请求第二个详情页的时候并没有发送id为0002的ajax数据,原因是Detail页面使用keep-alive做了缓存,所以mounted只会执行一次,跟之前的页面一样,如果想要请求不同页面的时候都发送一个ajax请求的话,就要配合activated的生命周期钩子,但是这里,我们采用一种新的方式: 在我们的根组件App.vue中原本是这样的:
<keep-alive>
<router-view/>
keep-alive>
表示所有路由的页面都做了一个缓存,如果我不想让详情页面做缓存,就可以这样做:
<keep-alive exclude="Detail">
<router-view/>
keep-alive>
其中Detail是详情页的名字,表示除了Detail页面都会缓存,只有Detail页面不会被缓存了,那么这个时候在请求不同详情页面的时候mounted钩子都会被执行。
每个组件中的name的作用是什么?
1. 递归组件需要使用
2. 相对某个页面取消缓存的时候需要使用
3. 网页中Vue开发调试工具会显示一个个组件的名字,就是这个name
一个小bug: 点击后面的详情页时会发现跳转过来的页面不是从顶部开始显示的,拖动效果在多个页面之间会互相影响。解决方法:Vue Router官网有一个滚动行为,在我们项目的路由部分添加以下内容:
scrollBehavior (to, from, savedPosition) {
return {
x: 0,
y: 0
}
}
表示每次做路由切换的时候都让显示的页面从(0,0)出开始显示,页面切换的时候始终从最顶部开始显示。