
在第一章的基础上, 搭建基座应用的布局, 先后搭建左侧栏、顶部栏、内容栏、底部栏。
Element UIelement uiyarn add element-ui@2.4.5 -s
因为安装的是 vue2.x, 所以 element ui 不需要安装最新的版本
因为后期可能会有很多的插件依赖需要安装, 所以抽离出plugins 文件来放置插件, 同时也方便后期基座提取公共依赖。
新建plugins/element.js
新建plugins/index.js
plugins/element.js中引入element uiimport Vue from "vue"; import Element from "element-ui"; import "element-ui/lib/theme-chalk/index.css"; // Vue.use(Element) Vue.use(Element, { size: "mini", // set element-ui default size // locale: enLang // 如果使用中文,无需设置,请删除 });
plugins/index.jsimport "./element";
├─components
│ └─Layout
│ ├─index.vue
│ └─components
│ ├─LayoutAside.vue
│ ├─LayoutAsideMenuItem.vue
│ ├─LayoutHeader.vue
│ ├─LayoutMain.vue
│ ├─LayoutFooter.vue
│ └─index.js
将布局单独抽离, 新建layout/index.js文件, 可以直接放在src目录下,或components目录下。这里选择components目录下。
Layout/components/LayoutAside.vue 左侧栏<!-- 左侧栏 -->
<template>
<div class="layout-aside">
<div class="layout-aside-logo">
<img class="logo" src="@/assets/logo.png" alt="" />
<span class="name" v-if="!isCollapse">强盛集团</span>
</div>
<el-scrollbar class="layout-aside-scrollbar">
<el-menu
:class="['layout-aside-menu']"
:default-active="defaultActive"
router
unique-opened
:collapse="isCollapse"
background-color="#2c3e50"
text-color="#ecf0f1"
active-text-color="#1890ff"
>
<layout-aside-menu-item
v-for="item in menuRoutes"
:item="item"
:key="item.path"
/>
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import LayoutAsideMenuItem from "./LayoutAsideMenuItem.vue";
import { routes } from "@/router/index";
import { mapGetters } from "vuex";
export default {
name: "LayoutAside",
components: { LayoutAsideMenuItem },
computed: {
defaultActive() {
return "/system/"; // 默认打开的页面
},
},
data() {
return {
menuRoutes: routes,
};
},
};
</script>
<style lang="less" scoped>
.layout-aside {
height: 100vh;
user-select: none;
background-color: #2c3e50;
.layout-aside-logo {
display: flex;
align-items: center;
justify-content: center;
height: 60px;
line-height: 60px;
padding: 0 20px;
color: #fff;
font-size: 25px;
font-weight: 700;
.logo {
width: 30px;
height: 26px;
margin-right: 3px;
}
.name {
line-height: 26px;
color: rgba(0, 113, 188, 1);
}
.layout-aside-scrollbar {
height: calc(100vh - 60px);
overflow-x: hidden;
padding-left: 5px;
.layout-aside-menu {
border-right: none;
&:not(.el-menu--collapse) {
width: 220px;
}
}
}
}
}
.el-scrollbar__wrap {
overflow-x: hidden !important;
}
</style>
Layout/components/LayoutAsideMenuItem.vue 左侧栏<!-- 左侧栏 - Item -->
<template>
<li class="layout-aside-menu-item">
<el-submenu v-if="item.children" :index="item.path">
<template slot="title">
<span slot="title">{{ item.meta && item.meta.title }}</span>
</template>
<layout-aside-menu-item
v-for="subItem in item.children"
:item="subItem"
:key="subItem.path"
>
</layout-aside-menu-item>
</el-submenu>
<el-menu-item v-else :route="item.path" :index="item.path">
<span slot="title">{{ item.meta && item.meta.title }}</span>
</el-menu-item>
</li>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "LayoutAsideMenuItem",
props: ["item"],
data() {
return {};
},
methods: {},
created() {},
mounted() {},
};
</script>
<style lang="scss" scoped></style>
暂时先不管 icon, 后面逐步完善。
Layout/components/LayoutHeader.vue 头部栏<!-- 头部栏 -->
<template>
<div class="">
<nav>
<router-link to="/">基座首页</router-link> |
<router-link to="/about">基座关于页</router-link> |
<router-link to="/vue/">微应用首页</router-link> |
<router-link to="/vue/about">微应用关于页</router-link>
</nav>
</div>
</template>
<script>
export default {
name: "",
data() {
return {};
},
methods: {},
created() {},
mounted() {},
};
</script>
<style lang="less" scoped>
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
头部区域暂时先防置之前的 nav
Layout/components/LayoutMain.vue 内容区<!-- 内容区 -->
<template>
<div class="">
内容区
<router-view></router-view>
<div id="Appmicro"></div>
</div>
</template>
<script>
export default {
name: "",
data() {
return {};
},
methods: {},
created() {},
mounted() {},
};
</script>
<style lang="less" scoped></style>
内容区防置了router-view标签 和 id为Appmicro的元素, 而这个元素将用来注入微应用
Layout/components/LayoutFooter.vue 底部栏<!-- 底部栏 -->
<template>
<div class="">底部栏</div>
</template>
<script>
export default {
name: "",
data() {
return {};
},
methods: {},
created() {},
mounted() {},
};
</script>
<style lang="less" scoped></style>
Layout/components/index.js, 用来作为 layout 组件的入口文件export { default as LayoutAside } from "./LayoutAside"; export { default as LayoutHeader } from "./LayoutHeader"; export { default as LayoutMain } from "./LayoutMain"; export { default as LayoutFooter } from "./LayoutFooter";
Layout/index.vue, Layout 布局的统一入口<!-- 布局 -->
<template>
<section class="layout">
<layout-aside></layout-aside>
<section class="layout-container">
<layout-header></layout-header>
<layout-main></layout-main>
<layout-footer></layout-footer>
</section>
</section>
</template>
<script>
import {
LayoutAside,
LayoutHeader,
LayoutMain,
LayoutFooter,
} from "./components";
export default {
name: "Layout",
components: { LayoutAside, LayoutHeader, LayoutMain, LayoutFooter },
data() {
return {};
},
methods: {},
created() {},
mounted() {},
};
</script>
<style lang="less" scoped>
.layout {
width: 100vw;
height: 100vh;
display: flex;
.layout-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
}
}
</style>
App.vue<template>
<div id="app">
<router-view />
</div>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
将 nav 移到了头部栏中, 此时就可以去掉 nav 部分的 html 和 css
此时你会发现除了基座的部分内容可见, 其余的路径都会报错, 接下来去改造下路由
layout不可见是因为没有用到, 所以只需要在 router 中, 给 routes 添加一层布局import Vue from "vue"; import Layout from "@/components/Layout"; import VueRouter from "vue-router"; import HomeView from "../views/HomeView.vue"; Vue.use(VueRouter); export const routes = [ { path: "/", name: "home", component: Layout, redirect: "/", meta: { title: "基座" }, children: [ { path: "/", name: "home", meta: { title: "基座首页" }, component: HomeView, }, { path: "/about", name: "about", meta: { title: "基座关于" }, component: () => import(/* webpackChunkName: "about" */ "../views/AboutView.vue"), }, ], }, ]; const router = new VueRouter({ mode: "history", base: process.env.BASE_URL, routes, }); export default router;
此时基座的两个页面已经可以正常访问, 但点击头部栏的微应用页面导航则报错
那我们先来将微应用的路由添加进去吧
router/modules/system, 创建系统路由// 系统菜单 import Layout from "@/components/Layout"; const appRouter = { path: "/system", component: Layout, name: "System", meta: { title: "微应用", icon: "table", }, children: [ { path: "/system/", name: "Home", meta: { title: "微应用首页", icon: "menuSon" }, }, { path: "/system/about", name: "About", meta: { title: "微应用关于", icon: "menuSon" }, }, ], }; export default appRouter;
router/index.js// 1. 引入 import SystemRoute from "./modules/system"; export const routes = [{}, ...SystemRoute];
此时点击微应用路径还是报错状态, 还需要修改register-apps.js的微应用配置
register-apps.jsregisterMicroApps( [ { name: "system", entry: "//localhost:1100", // 默认vue启动的入口是1100端口 activeRule: "/system", // 当路径是 /vue的时候启动 container: "#Appmicro", // 应用挂载的位置 loader, props: {}, }, ], { beforeLoad() { console.log("before load"); }, beforeMount() { console.log("before mount"); }, afterMount() { console.log("after mount"); }, beforeUnmount() { console.log("before unmount"); }, afterUnmount() { console.log("after unmount"); }, } );
修改了container 挂载节点, 和name、activeRule、字段,由vue改为了system, 为了方便后序改造系统配置模块
router/index.js, 需要把基路径也改一下const router = new VueRouter({ mode: 'history', base: window.__POWERED_BY_QIANKUN__ ? "/system/" : "/", routes })
至此, 布局之左侧栏完成, 然后比较简单, 正好可以从入门开始, 完整获得微前端的入门级体验。
实际很多项目也是从0开始,优先开发业务功能,逐步完成代码规范、提交规范。
而本专栏就是打算将Vue2.x的老项目完成技术架构升级,从而达到技术栈更新、迁移、重构、重写等架构演进。