因行情内卷严重,还是得要学习一下微前端,期待V3降临yyds~
直接开篇先创建2个Vue项目
// 主项目
vue create qiankun_main
// 子项目
vue create qiankun_child
? Please pick a preset:
Default ([Vue 2] babel, eslint) // 我比较不喜欢eslint所以你懂得
Default (Vue 3 Preview) ([Vue 3] babel, eslint) // Vue3的目前我还没测试,以后有机会写下
> Manually select features // 手动配置部分自带依赖
? Please pick a preset: Manually select features
? Check the features needed for your project:
(*) Choose Vue version
(*) Babel
( ) TypeScript // 单纯我不会ts!不要内卷我!
( ) Progressive Web App (PWA) Support
(*) Router
(*) Vuex
(*) CSS Pre-processors
>( ) Linter / Formatter // 我不爱eslint,可能因为我菜
( ) Unit Testing
( ) E2E Testing
? Choose a version of Vue.js that you want to start the project with
> 2.x
3.x (Preview)
// 因为前面设置了Router,所以问要不要history,本次只做hash所以No!
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) n
// 因为前面设置了CSS Pre-processors,我是用sass的!真香 ~
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default):
Sass/SCSS (with dart-sass)
> Sass/SCSS (with node-sass) // 这个快,所以选这个~
Less
Stylus
// 自己配置yyds
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
> In dedicated config files // 单独保存在各自的配置文件中
In package.json // 保存在package.json文件中
// 是否记住当前配置方便下一次直接使用创建项目
? Save this as a preset for future projects? (y/N) y // 记住,方便操作再次操作
? Save preset as: vue-qiankun-preset // 为这个配置命名
/* 漫长的等待 */
$ cd qiankun_main
$ npm run serve
// 子项目安装,用到了前一次的配置
? Please pick a preset:
> vue-qiankun-preset ([Vue 2] node-sass, babel, router, vuex) // 咱们前一次的配置
Default ([Vue 2] babel, eslint)
Default (Vue 3 Preview) ([Vue 3] babel, eslint)
Manually select features
复制代码
qiankun配置(本地主应用hash版)
// 安装qiankun(只需要主应用安装)
$ yarn add qiankun # or npm i qiankun -S # or cnpm i qiankun -S
// 确保依赖包的完整
$ npm install # or cnpm install
复制代码
qiankun.js – 封装js
import {
registerMicroApps,
start
} from 'qiankun';
const getActiveRule = (hash) => (location) => location.hash.startsWith(hash);
// 注册微应用
registerMicroApps([{
name: 'child', // 注册名
entry: '//localhost:8082', // 子应用端口(本地)
container: '#app', // 当前服务的APP.VUE ID
activeRule: getActiveRule('#/child'), // 子应用根路由 hash(官方推荐history)
// 这里也可以直接写 activeRule: '#/child',但是如果主应用是 history 模式或者主应用部署在非根目录,这样写不会生效
props: { // 传入子应用的值
/**
* 个人习惯:传data 子应用取data
*/
data: {
say: '我是父应用来的招呼'
}
}
}, ]);
// 启动我们可爱的微服务
start();
复制代码
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './qiankun' // 引用封装JS
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
复制代码
qiankun配置(本地子应用hash版 – 稍微比主应用麻烦点)
#### 子应用 qiankun_child
/* main.js */
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false;
let instance = null;
// 动态路由配置
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
// 非qiankun环境直接渲染
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 父应用已经到了子应用时的生命周期(简单来说:父应用的路由目前等于子应用的activeRule) TODO:activeRule #/child = /child
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
// 父应用已经到了子应用具体配置的路由时的生命周期(简单来说:路由地址对应的是子应用的路由地址,前置为父应用的activeRule) TODO:activeRule #/child = /child/子应用路由
export async function mount(props) {
store.commit("setQiankun", props);
console.log('[vue] props from main framework', props);
render(props);
}
// 父应用离开子应用时的生命周期(简单来说:路由不拼子应用里的)
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
function render(props = {}) {
const { container } = props;
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
复制代码
vue.config.js – 需要自己创建
let v = '1.0.0'; // 版本号
module.exports = {
configureWebpack: {
output: { // 输出重构 打包编译后的 文件名称 【模块名称.版本号.js】
library: `${v}-[name]`,
libraryTarget: 'umd', // 把子应用打包成 umd 库格式
jsonpFunction: `webpackJsonp_${v}`,
},
},
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
}
}
}
复制代码
router/index.js 配置路由
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const apiName = window.__POWERED_BY_QIANKUN__ ? '/child' : '';
const routes = [
{
path: `${apiName}/index`,
name: 'index',
component: () => import('@/views/system/home')
}
]
const router = new VueRouter({
routes
})
export default router
复制代码
store/index.js 配置VUEX
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
qiankun: null
},
mutations: {
setQiankun(state,v){
state.qiankun = Object.assign({},v);
}
},
actions: {
},
modules: {
}
})
复制代码
home.vue
<template>
<div>
<div>子页面</div>
<div>{{props}}</div>
</div>
</template>
<script>
export default {
created(){
this.props = this.$store.state.qiankun.data.say;
},
data(){
return{
props: ''
}
}
}
</script>
<style lang="scss">
</style>
复制代码
效果图
主应用
主应用中输入子应用路由
下一篇应该一边学习一边更新部署服务后的配置hash版
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END