做移动端时,如果需要给用户呈现良好的体验,以下两点时必须的?
注:第②点是依赖第①点来实现的
一、使用keep-alive增加缓存
我没在App.vue里面写keep-alive,因为系统的入口在main.vue,下面时main.vue中的内容
注意:下面代码中的css,.main-container 中设置的高度很关键
<template>
<div class="page-main main-container">
<template v-if="isRouterAlive">
<keep-alive>
<router-view v-if='$route.meta.keepAlive' />
</keep-alive>
<router-view v-if='!$route.meta.keepAlive' />
</template>
<!-- 此项目不需要导航 导航高度为50px -->
<!-- <van-tabbar v-model="active">
<van-tabbar-item icon="home-o">标签</van-tabbar-item>
<van-tabbar-item icon="search">标签</van-tabbar-item>
<van-tabbar-item icon="friends-o">标签</van-tabbar-item>
<van-tabbar-item icon="setting-o">标签</van-tabbar-item>
</van-tabbar> -->
</div>
</template>
<script>
export default {
data() {
return {
isRouterAlive: true
};
},
provide() {
return {
reload: this.reload
};
},
methods: {
reload() {
this.isRouterAlive = false;
this.$nextTick(() => {
this.isRouterAlive = true;
});
}
}
}
</script>
<style lang="less">
.main-container {
height: 100vh;
// height: calc(~"100vh - 50px"); 此项目不需要导航 导航高度为50px
overflow-y: auto;
}
</style>
?配置router,
注意:meta里设置的属性很关键
export default [
{
path: '/',
component: () => import('@/views/main'),
name: 'main',
redirect: {
name: 'transfer' // home //按理说应该为home,但是本系统有单点登录,所以需要一个中转站
},
meta: {
name: "layout"
},
children: [
{
path: 'resourceMgmt-instModel',
component: () => import('@/views/modules/resourceMgmt/instModel'),
name: 'resourceMgmt-instModel',
meta: {
title: "标题",
keepAlive: true,
scrollTop: 0
},
},
{
path: 'resourceMgmt-instList',
component: () => import('@/views/modules/resourceMgmt/instList'),
name: 'resourceMgmt-instList',
meta: {
title: "标题",
keepAlive: true,
scrollTop: 0
},
},
{
path: 'resourceMgmt-instDetails',
component: () => import('@/views/modules/resourceMgmt/instDetails'),
name: 'resourceMgmt-instDetails',
},
{
path: 'resourceMgmt-instRelate',
component: () => import('@/views/modules/resourceMgmt/instRelate'),
name: 'resourceMgmt-instRelate',
meta: {
title: "标题",
keepAlive: true,
scrollTop: 0
},
},
]
},
]
二、保留scrollTop的滑动位置
在项目中的全局路由拦截器中添加下面的代码,
(我是在router文件夹下面的index.js文件里写的,如下图所示)
router.beforeEach(async (to, from, next) => {
if (fnCurrentRouteIsPageRoute(to, pageRoutes)) {
return next()
}
if (!getToken()) {
return next({
name: 'transfer',
})
}
if (from.meta.keepAlive) {
const $container = document.querySelector('.main-container'); // 列表的外层容器
const scrollTop = $container ? $container.scrollTop : 0;
from.meta.scrollTop = scrollTop;
}
next()
})
router.afterEach(to => {
window.document.title = window.SITE_CONFIG['documentTitle']
//这里的代码对instList.vue文件没用,所以在instList.vue的混入文件中,另有处理
const $container = document.querySelector('.main-container');
if (to.meta.keepAlive && $container) {
$container.scrollTop = to.meta.scrollTop || 0;
}
})
用到vant2中的list组件的页面(instList.vue)需要做单独处理(不知道为啥router.afterEach中写的代码对用到list组件的文件不起作用)
下面是属于instList.vue的部分代码(完成代码请看我的另一篇博客:vue+vant2—篇1—如何使用list组件(下拉刷新,上滑分页加载)_有蝉的博客-CSDN博客)
beforeRouteEnter(to, from, next) {
next((vm) => {
if (from.name == "resourceMgmt-instModel"||from.path == "/") {
vm.$data.dataForm = vm.$options.data().dataForm
vm.dataForm.modelId = vm.$route.query.modelId
vm.onSearch();
}
});
},
activated() {
if (this.$route.meta.keepAlive) {
const scrollTop = this.$route.meta.scrollTop;
const $container = document.querySelector('.main-container');
$container.scrollTop = scrollTop;
}
},
这样就可以了。
|