Closed
Description
App.vue基本上是参考vux demo做的示例:
<template>
<div id="app">
<vue-topprogress ref="topProgress"></vue-topprogress>
<!-- 备选方案:参考vux文档 -->
<!--<loading v-model="isLoading"></loading>-->
<!-- main content -->
<view-box ref="viewBox" body-padding-top="46px" body-padding-bottom="55px">
<x-header class="border-1px app-header-bar" :left-options="leftOptions" :title="appTitle" @on-click-back="onHeaderBarTapBck">
</x-header>
<transition :name="transitionName">
<navigation>
<!-- <keep-alive> -->
<router-view class="child-view"></router-view>
<!-- </keep-alive> -->
</navigation>
</transition>
<tabbar class="vux-demo-tabbar" icon-class="vux-center" slot="bottom">
<tabbar-item :link="{path:'/Info', replace: true}" :selected="path === '/Info'" @click.native="onHomeBarClick">
<i class="iconfont icon-vue" slot="icon"></i>
<span slot="label">主页</span>
</tabbar-item>
<tabbar-item :link="{path:'/Demo'}" :selected="isDemo" @click.native="onDemoBarClick">
<span class="demo-icon-22" slot="icon" style="font-size:22px;line-height: 26px;">🌰</span>
<span slot="label"><span v-if="componentName" class="vux-demo-tabbar-component">{{componentName}}</span><span v-else>栗子</span></span>
</tabbar-item>
</tabbar>
</view-box>
</div>
</template>
<script type="text/ecmascript-6">
import {
vueTopprogress
} from 'vue-top-progress'
import {
mapState,
mapMutations
} from 'vuex'
import {
Loading,
XHeader,
Tabbar,
TabbarItem,
Icon,
ViewBox
} from 'vux'
export default {
name: 'app',
components: {
vueTopprogress,
Loading,
XHeader,
Tabbar,
TabbarItem,
Icon,
ViewBox
},
data() {
return {
transitionName: 'slide-left'
}
},
computed: {
backState() {
return this.$store.state['pageStack'].backState
},
...mapState({
route: state => state.route,
path: state => state.route.path
}),
...mapState([
'isLoading',
'appTitle',
'appTitleBarBackBtnVisible'
]),
isDemo() {
return /Components|Demo/.test(this.path)
},
componentName() {
if (/Components|Demo\/./.test(this.path)) {
return this.appTitle
}
},
leftOptions() {
return {
showBack: !/.[/Info]./.test(this.path) || /.[/Demo]./.test(this.path),
backText: '',
preventGoBack: true
}
}
},
watch: {
backState(state) {
if (state) {
this.transitionName = 'slide-right'
} else {
this.transitionName = 'slide-left'
}
},
isLoading(val) {
if (val) {
this.$refs.topProgress.start()
} else {
this.$refs.topProgress.done()
}
},
path(path) {
if (/Info/.test(this.path)) {
this.$vp.psModifyBackState(true)
} else if (/Demo/.test(this.path)) {
// TODO 将scroll上移
}
}
},
methods: {
...mapMutations([
'updateBackStatus',
'updateLoadingStatus'
]),
onHomeBarClick() {
if (this.backState) {
this.transitionName = 'slide-right'
} else {
this.transitionName = 'slide-left'
}
},
onHeaderBarTapBck() {
this.$vp.psGoBack()
},
onDemoBarClick() {
this.updateBackStatus(false)
}
},
created() {
this.$navigation.on('refresh', () => {
this.$refs.topProgress.done()
})
}
}
</script>
<style lang="less" scoped>
#app {
// 参考:https://vux.li/#/zh-CN/components?id=viewbox
height: 100%;
.child-view {
width: 100%;
top: 46px;
}
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active {
will-change: transform;
transition: all 500ms;
height: 100%;
top: 46px;
position: absolute;
backface-visibility: hidden;
perspective: 1000;
}
.slide-right-enter {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
.slide-right-leave-active {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
.slide-left-enter {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
.slide-left-leave-active {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
.vux-header {
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 100;
}
.iconfont {
color: rgb(77,49,74);
}
}
</style>
Metadata
Metadata
Assignees
Labels
No labels