1、先从页面分析,系统从登陆需要login.vue页面,再到系统内部的主页面main.vue,其次就是主页面内的子页面。
login.vue页面
<template>
<div class="login">
<div class="main blur">
<ul>
<li>
<img src="@/assets/img/logo1.png" alt="">
</li>
<li>
<input type="text" v-model="username" class="username" placeholder="User name" autocomplete="new-password"/>
</li>
<li>
<input type="password" v-model="password" class="password" placeholder="Password" autocomplete="new-password"/>
</li>
<li>
<p>forgot password ?</p>
</li>
<li class="btn">
<a-button type="primary" block @click="login">
Sign in
</a-button>
</li>
</ul>
</div>
</div>
</template>
<script>
import { Login } from '@/api/index'
import { message } from 'ant-design-vue'
export default {
name: 'Login',
components: {},
data () {
return {
username: '',
password: ''
}
},
mounted () {
window.addEventListener('keydown', (e) => {
if (e.keyCode === 13) {
this.login()
}
})
},
methods: {
login () {
if (this.username && this.password) {
Login({
username: this.username,
password: this.password
}).then(res => {
message.success(res.msg)
if (res.data.token) {
this.$storejs.set('token', res.data.token)
}
this.$router.push('/main/home')
}).catch(err => {
console.log(err)
})
}
}
}
}
</script>
main.vue主页面
<template>
<div class="home">
<a-layout id="components-layout-demo-side" style="min-height: 100vh">
<a-layout-sider v-model="collapsed" :trigger="null" collapsible>
<img src="@/assets/img/logo.png" alt="" :class="['logo', collapsed?'':'logoImg']">
<menu-tree :treeData="treeData" defaultSelectItemKey="home"></menu-tree>
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0">
<a-icon
class="trigger"
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="() => (collapsed = !collapsed)"
/>
</a-layout-header>
<a-layout-content style="margin: 0 16px">
<a-breadcrumb style="margin: 16px 0">
<a-breadcrumb-item>User</a-breadcrumb-item>
<a-breadcrumb-item>Bill</a-breadcrumb-item>
</a-breadcrumb>
<div class="content">
<router-view></router-view>
</div>
</a-layout-content>
<a-layout-footer style="text-align: center">
满地都是六便士,他却抬头看见了月亮,他不理睬六便士,却伸手追寻触碰月光
</a-layout-footer>
</a-layout>
</a-layout>
</div>
</template>
<script>
export default {
name: 'Layout',
data () {
return {
treeData: [],
collapsed: false
}
},
created () {
this.getMenuList()
},
methods: {
getMenuList () {
this.treeData = this.$router.options.routes[1].children
}
}
}
</script>
menu-tree组件页面
<template>
<div class="menu">
<a-menu theme="dark" :default-selected-keys="[defaultSelectItemKey]" mode="inline">
<template v-for="treeItem in treeData">
<a-sub-menu :key="treeItem.path" v-if="treeItem.children && treeItem.children.length">
<span slot="title">
<a-icon :type="treeItem.meta.icon" />
<span>{{treeItem.meta.title}}</span>
</span>
<menu-tree :treeData="treeItem.children" class="menu_children"></menu-tree>
</a-sub-menu>
<a-menu-item :key="treeItem.path" v-else>
<router-link :to="{ path: `/main/${treeItem.path}` }">
<a-icon :type="treeItem.meta.icon" />
<span>{{treeItem.meta.title}}</span>
</router-link>
</a-menu-item>
</template>
</a-menu>
</div>
</template>
<script>
export default {
name: 'menu-tree',
props: {
treeData: {
type: Array,
default: () => []
},
defaultSelectItemKey: {
type: String,
default: () => ['']
}
},
}
</script>
2、从路由分析,/login和/main路由属于平级,main.vue页面内的菜单列表的路由属于/main下的子路由,展示的菜单列表也是这一部分路由
/router/index.js
import routerObj from './routesImport'
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
redirect: '/login'
},
{
path: '/main',
name: 'main',
component: () => import('../views/LayOut/index.vue'),
children: [
{
path: 'home',
name: 'home',
component: routerObj.Home,
meta: {
title: '首页',
icon: 'home',
auth: true
}
},
{
path: 'users',
name: 'users',
component: routerObj.Users,
meta: {
title: '用户管理',
icon: 'user',
auth: true
}
},
{
path: 'setting',
name: 'setting',
component: routerObj.Setting,
meta: {
title: '系统设置',
icon: 'setting',
auth: true
}
}
]
},
{
path: '/login',
name: 'login',
component: routerObj.Login
},
{
path: '*',
hidden: true,
component: () => routerObj.NotFound
}
]
})
export default router
/router/routesImport.js路由导入处理
const context = require.context('@/views/', true, /index.vue$/)
const routerObj = {}
context.keys().forEach((item) => {
const name = context(item).default.name
routerObj[name] = context(item).default
})
export default routerObj
3、vue渲染方式分析,App.vue下的router-view是用来装对应路由的容器,是最大的主容器,负责展示登录页面和系统内部主页面,main.vue页面分左右两侧,点击左侧的菜单对应展示右边内容。菜单列表所属于/main路由下,所以点击菜单列表时,切换的是/main下的子路由,右边是/main下子路由切换时展示的对应内容,和App.vue同理,所以右侧需要一个容器router-view用来展示/main下子路由的内容
