路由骨架屏

行政区划选择器懒加载
变量名称修改
master
toesbieya 6 years ago
parent 347b610ae8
commit b8ed38e6d7
  1. 6
      vue/src/assets/styles/index.scss
  2. 6
      vue/src/assets/styles/variables.scss
  3. 4
      vue/src/components/RegionSelector/index.vue
  4. 71
      vue/src/components/Skeleton/PageSkeleton.vue
  5. 2
      vue/src/components/Skeleton/index.vue
  6. 0
      vue/src/components/Skeleton/style.scss
  7. 4
      vue/src/layout/components/Header.vue
  8. 18
      vue/src/layout/components/Main.vue
  9. 4
      vue/src/layout/components/Navbar/index.vue
  10. 6
      vue/src/layout/components/Sidebar/style.scss
  11. 2
      vue/src/layout/components/TagsView/style.scss
  12. 13
      vue/src/layout/index.vue
  13. 5
      vue/src/router/authority/modules/message.js
  14. 5
      vue/src/router/authority/modules/purchase.js
  15. 5
      vue/src/router/authority/modules/sell.js
  16. 3
      vue/src/router/authority/modules/stock.js
  17. 17
      vue/src/router/authority/modules/system.js
  18. 27
      vue/src/router/constant/modules/example.js
  19. 3
      vue/src/router/index.js
  20. 11
      vue/src/router/util.js
  21. 5
      vue/src/store/modules/app.js
  22. 6
      vue/src/views/stock/current/index.vue

@ -84,16 +84,16 @@ a:hover {
}
.max-view-height {
height: calc(100vh - #{$pageViewMargin * 2});
height: calc(100vh - #{$page-view-margin * 2});
}
.has-header {
.max-view-height {
height: calc(100vh - #{$navHeight} - #{$pageViewMargin * 2});
height: calc(100vh - #{$nav-height} - #{$page-view-margin * 2});
}
&.has-tags-view .max-view-height {
height: calc(100vh - #{$navHeight} - #{$tagsViewHeight} - #{$pageViewMargin * 2});
height: calc(100vh - #{$nav-height} - #{$tags-view-height} - #{$page-view-margin * 2});
}
}

@ -47,12 +47,12 @@ $sub-menu-hover: #001528;
//侧边栏宽度
$side-bar-width: 210px;
//头部导航栏高度
$navHeight: 50px;
$nav-height: 50px;
//头部多页签栏高度
$tagsViewHeight: 40px;
$tags-view-height: 40px;
//路由页面的margin
$pageViewMargin: 15px;
$page-view-margin: 15px;
//引入element的scss时需要覆盖字体路径
$--font-path: '~element-ui/lib/theme-chalk/fonts';

@ -1,6 +1,6 @@
<script>
import Tree from './Tree'
import Tab from './Tab'
const Tree = () => import('./Tree').then(_ => _.default)
const Tab = () => import('./Tab').then(_ => _.default)
export default {
name: "RegionSelector",

@ -0,0 +1,71 @@
<script type="text/jsx">
//https://antdv.com/components/skeleton-cn/
import QSkeleton from './index'
export default {
name: "PageSkeleton",
functional: true,
render() {
const single = (
<div class="page-skeleton">
<div class="page-skeleton__header">
<QSkeleton type="circle"/>
</div>
<div class="page-skeleton__content">
<QSkeleton tag="h3"/>
<ul class="page-skeleton__paragraph">{new Array(3).fill(<QSkeleton/>)}</ul>
</div>
</div>
)
return <div class="page-skeleton-wrapper">{new Array(4).fill(single)}</div>
}
}
</script>
<style lang="scss">
.page-skeleton-wrapper {
margin: $page-view-margin;
}
.page-skeleton {
width: 100%;
display: table;
& + & {
margin-top: 20px;
}
&__header,
&__content {
display: table-cell;
}
&__header {
padding-top: 2px;
padding-right: 16px;
vertical-align: top;
}
&__content {
width: 100%;
> .q-skeleton {
width: 50%;
}
.page-skeleton__paragraph {
margin-top: 28px;
padding: 0;
.q-skeleton:last-child:not(:first-child):not(:nth-child(2)) {
width: 61%;
}
.q-skeleton + .q-skeleton {
margin-top: 16px;
}
}
}
}
</style>

@ -44,4 +44,4 @@
}
</script>
<style lang="scss" src="./QSkeleton.scss"></style>
<style lang="scss" src="./style.scss"></style>

@ -69,12 +69,12 @@
</script>
<style lang="scss">
.has-tags-view .header-container {
height: calc(#{$navHeight} + #{$tagsViewHeight});
height: calc(#{$nav-height} + #{$tags-view-height});
}
.header-container {
position: relative;
height: $navHeight;
height: $nav-height;
transition: height .3s ease-in-out;
flex-shrink: 0;

@ -9,10 +9,11 @@
</transition>
</div>
</el-scrollbar>
<!--跨域iframe无法调整高度只能使用原生滚动条-->
<iframe
v-for="src in iframeList"
v-show="showIframe&&src===currentIframe"
v-show="showIframe && src === currentIframe"
:id="src"
:key="src"
:src="src"
@ -20,6 +21,7 @@
height="100%"
width="100%"
/>
<el-backtop v-if="showBackToTop" target=".app-main .el-scrollbar__wrap" :visibility-height="400"/>
</main>
</template>
@ -32,6 +34,12 @@
export default {
name: 'AppMain',
computed: {
...mapState('app', {
scrollTop: state => state.scrollTop,
}),
...mapState('setting', {
showBackToTop: state => state.showBackToTop
}),
...mapState('tagsView', {
cachedViews: state => state.cachedViews,
transitionName: state => state.transitionName
@ -40,12 +48,6 @@
showIframe: state => state.show,
currentIframe: state => state.current,
iframeList: state => state.list
}),
...mapState('app', {
scrollTop: state => state.scrollTop
}),
...mapState('setting', {
showBackToTop: state => state.showBackToTop
})
},
watch: {
@ -74,7 +76,7 @@
height: 100%;
.page-view {
margin: $pageViewMargin;
margin: $page-view-margin;
}
> .el-scrollbar__bar.is-horizontal {

@ -99,7 +99,7 @@
<style lang="scss">
.navbar {
height: $navHeight;
height: $nav-height;
overflow: hidden;
position: relative;
background: #fff;
@ -114,7 +114,7 @@
.right-menu {
float: right;
height: 100%;
line-height: $navHeight;
line-height: $nav-height;
&:focus {
outline: none;

@ -36,8 +36,8 @@ $iconSize: 17px;
.sidebar-logo-container {
position: relative;
width: 100%;
height: $navHeight;
line-height: $navHeight;
height: $nav-height;
line-height: $nav-height;
text-align: center;
& .sidebar-logo-link {
@ -56,7 +56,7 @@ $iconSize: 17px;
margin: 0;
color: #fff;
font-weight: 600;
line-height: $navHeight;
line-height: $nav-height;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;

@ -1,5 +1,5 @@
.tags-view-container {
height: $tagsViewHeight;
height: $tags-view-height;
background: #f0f0f0;
border-bottom: 1px solid #d8dce5;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);

@ -1,16 +1,14 @@
<template>
<section class="el-container app-wrapper">
<v-sidebar/>
<section class="el-container main-container" :class="{'has-header':hasHeader,'has-tags-view':useTagsView}">
<v-header/>
<v-main/>
</section>
<!--移动端侧边栏展开时的遮罩-->
<div
v-show="showSidebarMask"
class="drawer-bg"
@click.stop.prevent="$store.commit('setting/sidebarCollapse',true)"
/>
<div v-show="showSidebarMask" class="drawer-bg" @click.stop.prevent="collapseSidebar"/>
</section>
</template>
@ -52,6 +50,11 @@
showOfflineTip(v) {
v ? this.$bottomTip('与服务器失去连接') : this.$bottomTip.close()
}
},
methods: {
collapseSidebar() {
this.$store.commit('setting/sidebarCollapse', true)
}
}
}
</script>

@ -1,5 +1,6 @@
/*路由表:消息中心*/
import Layout from '@/layout'
import {lazyLoadView} from "@/router/util"
const router = {
path: '/message',
@ -10,13 +11,13 @@ const router = {
{
path: 'manage',
name: 'messageManagement',
component: () => import('@/views/message/manage'),
component: () => lazyLoadView(import('@/views/message/manage')),
meta: {title: '消息管理'}
},
{
path: 'user',
name: 'userMessage',
component: () => import('@/views/message/user'),
component: () => lazyLoadView(import('@/views/message/user')),
meta: {title: '个人消息', noAuth: true, noCache: true}
}
]

@ -1,5 +1,6 @@
/*路由表:采购管理*/
import Layout from '@/layout'
import {lazyLoadView} from "@/router/util"
const router = {
path: '/purchase',
@ -10,13 +11,13 @@ const router = {
{
path: 'order',
name: 'purchaseOrder',
component: () => import('@/views/purchase/order'),
component: () => lazyLoadView(import('@/views/purchase/order')),
meta: {title: '采购订单'}
},
{
path: 'inbound',
name: 'purchaseInbound',
component: () => import('@/views/purchase/inbound'),
component: () => lazyLoadView(import('@/views/purchase/inbound')),
meta: {title: '采购入库'}
}
]

@ -1,5 +1,6 @@
/*路由表:销售管理*/
import Layout from '@/layout'
import {lazyLoadView} from "@/router/util"
const router = {
path: '/sell',
@ -10,13 +11,13 @@ const router = {
{
path: 'order',
name: 'sellOrder',
component: () => import('@/views/sell/order'),
component: () => lazyLoadView(import('@/views/sell/order')),
meta: {title: '销售订单'}
},
{
path: 'outbound',
name: 'sellOutbound',
component: () => import('@/views/sell/outbound'),
component: () => lazyLoadView(import('@/views/sell/outbound')),
meta: {title: '销售出库'}
}
]

@ -1,5 +1,6 @@
/*路由表:库存管理*/
import Layout from '@/layout'
import {lazyLoadView} from "@/router/util"
const router = {
path: '/stock',
@ -10,7 +11,7 @@ const router = {
{
path: 'current',
name: 'currentStock',
component: () => import('@/views/stock/current'),
component: () => lazyLoadView(import('@/views/stock/current')),
meta: {title: '当前库存'}
}
]

@ -1,5 +1,6 @@
/*路由表:系统管理*/
import Layout from '@/layout'
import {lazyLoadView} from "@/router/util"
const router = {
path: '/system',
@ -10,50 +11,50 @@ const router = {
{
path: 'department',
name: 'departmentManagement',
component: () => import('@/views/system/department'),
component: () => lazyLoadView(import('@/views/system/department')),
meta: {title: '部门管理'}
},
{
path: 'role',
name: 'roleManagement',
component: () => import('@/views/system/role'),
component: () => lazyLoadView(import('@/views/system/role')),
meta: {title: '角色管理'}
},
{
path: 'user',
name: 'userManagement',
component: () => import('@/views/system/user'),
component: () => lazyLoadView(import('@/views/system/user')),
meta: {title: '用户管理'}
},
{
path: 'category',
name: 'categorySetting',
component: () => import('@/views/system/category'),
component: () => lazyLoadView(import('@/views/system/category')),
meta: {title: '商品分类'}
},
{
path: 'customer',
name: 'customerManagement',
component: () => import('@/views/system/customer'),
component: () => lazyLoadView(import('@/views/system/customer')),
meta: {title: '客户管理'}
},
{
path: 'supplier',
name: 'supplierManagement',
component: () => import('@/views/system/supplier'),
component: () => lazyLoadView(import('@/views/system/supplier')),
meta: {title: '供应商管理'}
},
{
path: 'resource',
name: 'resourceManagement',
component: () => import('@/views/system/resource'),
component: () => lazyLoadView(import('@/views/system/resource')),
hidden: true,
meta: {title: '接口设置'}
},
{
path: 'monitor',
name: 'systemMonitor',
component: () => import('@/views/system/monitor'),
component: () => lazyLoadView(import('@/views/system/monitor')),
hidden: true,
meta: {title: '系统监控'}
}

@ -1,5 +1,6 @@
/*路由表:演示用例*/
import Layout from '@/layout'
import {lazyLoadView} from "@/router/util"
const router = {
path: '/example',
@ -7,15 +8,15 @@ const router = {
meta: {title: '演示用例', icon: 'show', noCache: true},
children: [
{
path: 'style-page',
path: 'stylePage',
name: 'stylePage',
component: () => import('@/views/example/stylePage'),
component: () => lazyLoadView(import('@/views/example/stylePage')),
meta: {title: '样 式'}
},
{
path: 'icons',
name: 'icons',
component: () => import('@/views/example/icons'),
component: () => lazyLoadView(import('@/views/example/icons')),
meta: {title: '图 标'}
},
{
@ -31,13 +32,13 @@ const router = {
{
path: 'fluid',
name: 'fluid',
component: () => import('@/views/example/cool/fluid'),
component: () => lazyLoadView(import('@/views/example/cool/fluid')),
meta: {title: '流体动画'}
},
{
path: 'l2d',
name: 'l2d',
component: () => import('@/views/example/cool/l2d'),
component: () => lazyLoadView(import('@/views/example/cool/l2d')),
meta: {title: '看板娘'}
},
]
@ -50,45 +51,45 @@ const router = {
{
path: 'uploadExample',
name: 'uploadExample',
component: () => import('@/views/example/components/uploadExample'),
component: () => lazyLoadView(import('@/views/example/components/uploadExample')),
meta: {title: '上传文件'}
},
{
path: 'picturePreviewExample',
name: 'picturePreviewExample',
component: () => import('@/views/example/components/picturePreviewExample'),
component: () => lazyLoadView(import('@/views/example/components/picturePreviewExample')),
meta: {title: '图片预览'}
},
{
path: 'skeletonExample',
name: 'skeletonExample',
component: () => import('@/views/example/components/skeletonExample'),
component: () => lazyLoadView(import('@/views/example/components/skeletonExample')),
meta: {title: '骨架屏'}
},
{
path: 'rippleExample',
name: 'rippleExample',
component: () => import('@/views/example/components/rippleExample'),
component: () => lazyLoadView(import('@/views/example/components/rippleExample')),
meta: {title: '波纹'}
},
{
path: 'signatureExample',
name: 'signatureExample',
component: () => import('@/views/example/components/signatureExample'),
component: () => lazyLoadView(import('@/views/example/components/signatureExample')),
meta: {title: '手写签名'}
},
{
path: 'regionSelectorExample',
name: 'regionSelectorExample',
component: () => import('@/views/example/components/regionSelectorExample'),
component: () => lazyLoadView(import('@/views/example/components/regionSelectorExample')),
meta: {title: '行政区划选择'}
}
]
},
{
path: 'developing-test',
path: 'developingTest',
name: 'developingTest',
component: () => import('@/views/example/developingTest'),
component: () => lazyLoadView(import('@/views/example/developingTest')),
meta: {title: '开发测试'}
}
]

@ -13,6 +13,7 @@
* */
import Vue from 'vue'
import Router from 'vue-router'
import store from "@/store"
import NProgress from 'nprogress'
import {isUserExist} from "@/utils/sessionStorage"
import {auth, needAuth} from "@/utils/auth"
@ -20,7 +21,6 @@ import {getPageTitle, transformWhiteList, metaExtend} from './util'
import {routerMode} from '@/config'
import constantRoutes from '@/router/constant'
import authorityRoutes from '@/router/authority'
import store from "@/store"
Vue.use(Router)
@ -64,7 +64,6 @@ router.beforeEach(async (to, from, next) => {
iframeControl(to)
return next()
}
//用户无权限访问时的动作
next({path: '/403'})
})

@ -1,6 +1,7 @@
import {pathToRegexp} from 'path-to-regexp'
import {isEmpty} from "@/utils"
import {title} from "@/config"
import PageSkeleton from "@/components/Skeleton/PageSkeleton"
//拼接页面标题
export function getPageTitle(pageTitle) {
@ -28,3 +29,13 @@ export function metaExtend(routes, meta) {
}
})
}
export function lazyLoadView(component) {
const AsyncHandler = () => ({component, loading: PageSkeleton})
return Promise.resolve({
functional: true,
render(h, {data, children}) {
return h(AsyncHandler, data, children)
}
})
}

@ -7,12 +7,15 @@ const localSettings = getLocalPersonalSettings()
const state = {
//区分pc和移动端(mobile)
device: isMobile() ? 'mobile' : 'pc',
//登陆页背景动画
loginBackgroundAnimation: 'firework',
//路由页面滚动高度
scrollTop: 0,
//右侧块是否含有头部
hasHeader: !!!localSettings.headerAutoHidden,
hasHeader: !!!localSettings.headerAutoHidden
}
const mutations = createMutations(state)

@ -1,6 +1,6 @@
<template>
<el-row>
<el-card class="card-container max-view-height" style="width: 250px;float: left;margin-right: 15px">
<el-row type="flex">
<el-card class="card-container max-view-height" style="width: 250px;margin-right: 15px">
<el-input
v-model="temp.filter"
size="small"
@ -12,7 +12,7 @@
<category-tree ref="tree" :filter-node-method="filterNode" @node-click="nodeClick"/>
</el-card>
<el-card>
<el-card style="width: calc(100% - 250px)">
<search-form>
<search-form-item label="商品分类:">
<el-input :value="temp.cname" maxlength="100" clearable @clear="clearCidSearch"/>

Loading…
Cancel
Save