前言
之前写的那个qiankun是有问题的,所以重新写了一下,最近才发现好久没写文章总结了,这段时间我会基于qiankun项目,写一个完整的项目步骤,(1)想写qiankun介绍,不过好像挺多类似的文章,就不急着写了,后续补上
一, 準備
1. vue-cli版本
2. vue, qiankun , vuerouter
二. 創建項目
1.首先通过vue creat文件名,创建两个项目,作为主应用和子应用,这里使用qiankun-test,qiankun-testchild1作为示例.
其他选项一直回车即可,创建好项目之后,当前文件下就会出现两个项目包,如下
我們將qiankun-test作為主項目,開始使用qiankun
2. 主项目中,需要使用qiankun来加载子应用,所以,需要在主项目中install qiankun,子项目不需要,然后再安装一个vue-router,这个是需要的
3. 接下来就是需要在主项目中使用qiankun了,进入到主项目的main.js中,先引入qiankun,引入三个参数:分别是registerMicroApps,setDefaultMountApp,start,其中setDefaultMountApp默认子应用这个参数,引不引入都可以.
apps数组用来存放加载子应用的信息,包含入口,连接,传参等等,registerMicroApps可以设置各子应用启动前后,状态变化的函数及自定义操作,start用于启动qiankun
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import { registerMicroApps,setDefaultMountApp, start } from "qiankun"
Vue.config.productionTip = false
Vue.use(ElementUI);
let apps = [
{
name: "qiankun-testchild1", // 這個是子項目的名稱
entry: '//localhost:9725', // 這個是子項目的入口鏈接
container: "#subapp", // 這個是主應用中子應用盒子, id
activeRule: "/qiankun-testchild1", // 這個是子應用路徑規則
props: { // 这个是传给子应用的参数信息
name: "kuitos"
}
}
]
registerMicroApps(apps,
{
beforeLoad: [
app => {
console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
},
],
beforeMount: [
app => {
console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
},
],
afterUnmount: [
app => {
console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
},
],
},);
// 设置默认子应用,与 genActiveRule中的参数保持一致
// setDefaultMountApp("/app1");
// 启动
start();
new Vue({
router,
render: h => h(App)
}).$mount("#app");
4. 接下来在app.vue中,放置子应用盒子,id与main.js里container的id一样,
5.然后在src目录下,创建router文件夹,导出router供main.js引用
import Vue from 'vue'
import VueRouter from 'vue-router'
import HelloWorld from '../components/HelloWorld.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'HelloWord',
component: HelloWorld
}
]
const router = new VueRouter({
mode: 'history',
// base: '/qiankun-testchild1', // 这个base,是默认路径,如果不将其注释,会将首页与子应用共同显示router-view中.
routes
})
export default router
6. 然后再在src下创建shared文件夹,提供给多应用之间通信,
import { initGlobalState } from "qiankun";
const initialState = {};
const actions = initGlobalState(initialState);
export default actions;
7. 创建并添加好actions之后,就可以在主应用中,使用actions去建立通信了,比如,在主应用的helloWorld,中,先引入actions,然后通过actions.onGlobalStateChange来监听数据变化,通过setGlobalState来改变数据
8.到此,主应用就简单的完成了,那么接下来就要来改造一下子应用.
9. 首先,在子应用的根目录下,创建一个vue.config.js文件,这个文件可以用来修改添加webpack配置,这块不明白的话,后续再讲一下,配置如下:主要解决跨域,和子应用died问题
const path = require('path');
const packageName = require('./package').name;
function resolve(dir) {
return path.join(__dirname, dir);
}
const port = 9725; // dev port
module.exports = {
publicPath:`//localhost:${port}`, // 這個是子應用的訪問路徑
outputDir: 'dist',
assetsDir: 'static',
filenameHashing: true,
devServer: {
// host: '0.0.0.0',
hot: true, // 這個是重點, 需要添加進去, 否則, 子應用會died
historyApiFallback: true,//添加 重点
port,
overlay: {
warnings: false,
errors: true,
},
headers: {
'Access-Control-Allow-Origin': '*', // 這個是跨域
},
},
configureWebpack: {
resolve: {
alias: {
'@': resolve('src'),
},
},
output: { // 這一塊配置子應用打包配置, 不配置也會died,
library: `${packageName}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
},
};
10. 接下来,就需要修改一下public文件夹下,html中根元素的id,不能与主应用id相同
11.然后,需要在子应用的main.js中注入qiankun的生命周期,
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import actions from "../src/shared/action";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
Vue.config.productionTip = false;
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
let instance = null;
function render(props={}) {
if (props) {
// 注入 actions 实例
actions.setActions(props);
}
const { container } = props;
console.log(container,props,888)
instance = new Vue({
router,
render: h => h(App)
}).$mount(container ? container.querySelector("#app2") : "#app2");
}
12. 同樣, main.js中會引入router 和actions, 所以, 需要在src目錄下分別添加 shared文件夾和router文件夾
// shared ==>action.js
```
function emptyAction() {
// 警告:提示当前使用的是空 Action
console.warn("Current execute action is empty!");
}
class Actions {
// 默认值为空 Action
actions = {
onGlobalStateChange: emptyAction,
setGlobalState: emptyAction
};
/**
* 设置 actions
*/
setActions(actions) {
this.actions = actions;
}
/**
* 映射
*/
onGlobalStateChange(...args) {
return this.actions.onGlobalStateChange(...args);
}
/**
* 映射
*/
setGlobalState(...args) {
return this.actions.setGlobalState(...args);
}
}
const actions = new Actions();
export default actions;
```
// router==> index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
]
const router = new VueRouter({
base: '/',
mode: 'history',
routes,
});
export default router
13. 然後, 在需要的地方, 使用action監聽修改
14. 在路由跳轉上, 使用的是history模式跳轉,
15. 到这里,一个简单的qiankun示例就基本上实现了,跟着步骤一步步做,就能成功启动并使用,给出下效果截图,
16. 最後附上這階段的代碼連接
github.com/hejiyun/qia…
結語
时间从来不语,却回答了所有问题,各位,前路漫漫,沿途亦是风景.且行且珍惜.
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!