for
=
"item of hot"
:key=
"item.id"
@click
=
"handleCityClick(item.name)"
>
methods: {
handleCityClick (city) {
this
.$store.dispatch(
'changeCity'
, city)
alert(city)
}
},
/src/store/index.js
export
default
new
Vuex.Store({
state: {
city:
'南京'
},
actions: {
changeCity (ctx, city) {
console.log(city)
ctx.commit(
'toChangeCity'
, city)
}
},
mutations: {
toChangeCity (state, city) {
state.city = city
}
}
})
vuex还支持字段映射
import
{ mapState } from
'vuex'
computed: {
...mapState([
'city'
])
}
or
import
{ mapMutations } from
'vuex'
handleCityClick (city) {
...
this
.toChangeCity(city)
},
...mapMutations([
'toChangeCity'
])
通过js来打开路由页面
this
.$router.push(
'/'
)
使用keep-alive优化性能
创建分支 city-keepalive-
14
修改App.vue
此时又需要处理数据动态改变时页面需要重新请求数据,例如当前城市改变时,需求加载当前城市的信息
使用keep-alive后,mounted周期函数只会被调用一次,但是activated周期函数会每次都会被调用。所以...
在Home.vue中使用vuex,并在computed计算属性中映射一个city对象,同时定义一个属性lastCity标记上一个城市。
然后在activated周期函数中判断当前选择城市和上一个城市是否相等,不相等则将当前城市作为参数重新请求一次ajax。
import
{ mapState } from
'vuex'
data () {
return
{
lastCity:
''
,
}
},
computed: {
...mapState([
'city'
])
},
methods: {
getHomeInfo () {
axios.get(
'/api/index.json?city='
+
this
.city)
.then(
this
.getHomeInfoSucc)
}
},
mounted () {
this
.lastCity =
this
.city
console.log(
'mounted'
)
this
.getHomeInfo()
},
activated () {
if
(
this
.lastCity !==
this
.city) {
this
.lastCity =
this
.city
this
.getHomeInfo()
}
console.log(
'activated'
)
}
另外也可以使用来排除一部分页面,使其不使用缓存,例如城市详情页,修改App.vue
"Detail"
>
特别注意: exclude会导致页面中不再回调activated (), 但是会调用created (),所以一些需要重新初始化的方法或者属性需要在created () 调用。
例如:src/pages/detail/components/Header.vue
七、城市详情页面
Banner
创建分支detail-banner-
15
将li标签换成router-link:
解决router-link默认会改成标签颜色问题
注意需要同时在router-link标签上增加tag属性,指定需要渲染成li标签,同时指定to属性。
"li"
v-
for
=
"item of list"
:key=
"item.id"
:to=
"'/detail/' + item.id"
>
...
注册动态路由,获取路由参数
{
path:
'/detail/:id'
,
name:
'Detail'
,
component: Detail
}
参考 http:
创建DetailBanner组件
渐变效果
background-image: ar-gradient(top, rgba(
0
,
0
,
0
,
0
), rgba(
0
,
0
,
0
,
0.8
))
共用组件画廊
swiper 中文网
http:
代码见 /src/common/gallary/Gallary.vue
Header渐隐渐显效果
创建分支 detail-header-
16
特别注意:获取滚动条滚动的垂直距离scrollTop的兼容问题
通过绑定:style的opacity属性来动态改变透明度
"div"
to=
"/"
class
=
"header-abs"
v-show=
"showAbs"
:style=
"opacityAbsStyle"
>
class
=
"iconfont back-icon-back"
>
class
=
"header-fixed"
v-show=
"!showAbs"
:style=
"opacityFixedStyle"
>
"/"
>
class
=
"iconfont header-fixed-back"
>
景点详情
data () {
return
{
showAbs:
true
,
opacityAbsStyle: {
opacity:
1
},
opacityFixedStyle: {
opacity:
0
}
}
},
methods: {
handleScroll () {
const
scrollTop = (window.parent.document.documentElement.scrollTop || window.parent.document.body.scrollTop)
|| (document.body.scrollTop + document.documentElement.scrollTop)
|| (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop ||
0
)
if
(top >
40
) {
let opacity = top /
130
opacity = opacity >
1
?
1
: opacity
this
.opacityFixedStyle = {
opacity
}
this
.showAbs =
false
}
else
{
this
.showAbs =
true
let opacity = top /
40
opacity = opacity >
1
?
1
: opacity
this
.opacityAbsStyle = {
opacity: (
1
- opacity)
}
}
}
},
activated () {
window.addEventListener(
'scroll'
,
this
.handleScroll)
}
对全局事件解绑
处理上一节window.addEventListener
activated () {
window.addEventListener(
'scroll'
,
this
.handleScroll)
}
解绑事件:
deactivated () {
window.removeEventListener(
'scroll'
,
this
.handleScroll)
}
使用递归组件实现详情页列表
创建分支 detail-list-
17
json数据
list: [{
title:
'成人票'
,
children: [{
title:
'成人三管联票'
,
children: [{
title:
'成人三管联票 - 某一连锁店销售'
}]
}, {
title:
'成人五管联票'
}]
}, {
title:
'学生票'
}, {
title:
'儿童票'
}, {
title:
'特惠票'
}]
递归调用detail-list组件(List.vue)
class
=
"item"
v-
for
=
"(item,index) of list"
:key=
"index"
>
class
=
"item-title border-bottom"
>
class
=
"item-title-icon"
>
{{item.title}}
if
=
"item.children"
class
=
"item-children"
>
"item.children"
>
ajax获取数据
创建分支 detail-ajax-
18
注意一下,使用属性绑定时加上冒号
class
=
"banner-img"
:src=
"bannerImg"
>
显示文本,使用{{属性xxx}}即可
class
=
"banner-title"
>{{
this
.sightName}}
使用计算属性控制是否显示一个列表部分(避免按空数组初始化,导致有数据变化时的当前显示的索引为列表的最后一个)
"swiperOption"
v-
if
=
"isShowGallary"
>
···
computed: {
isShowGallary () {
return
this
.imgs.length >
0
}
}
路由行为
打开新页面显示到顶部,不能受到上一页上下滚动的距离影响
https:
修改router/index.js
export
default
new
Router({
routes: [{
path:
'/'
,
name:
'HelloWorld'
,
component: Home
}],
scrollBehavior: function (to, from, savedPosition) {
return
savedPosition || { x:
0
, y:
0
}
}
})
更多关于路由介绍
https:
在项目中使用基本动画
创建分支 detail-animation-
19
代码在src/common/fade/FadeAnimation.vue (淡入淡出效果)
export
default
{
name:
'FadeAnimation'
}
应用在在src/pages/detail/components/Banner.vue中
"bannerImgs"
v-show=
"showGallary"
>
开发结束,非常感谢您阅读此文!
个人网站 tech.jiangjiesheng.cn
QQ:
596957738
微信:
596957738
EMail: dev
@jiangjiesheng
.com