ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于qiankun与vue-cli的使用和构建过程

2022-06-17 08:00:20  阅读:185  来源: 互联网

标签:vue sub router qiankun instance props import cli


2022年了,我还在研究qiankun,都被用烂了。看到招聘要求上一栏写着会qiankun,我默默的学起来。

这里主应用和子应用都是用vue-cli4X框架,期间遇到了一些坑也都解决了。

第一步安装qiankun

yarn add qiankun # 或者 npm i qiankun -S

main为主应用,sub-app1,sub-app2为微应用,如下图。

 

 

第二步,在主应用入口文件注册微应用

/qiankun-vue/main/main.js

 

 

import './public-path.js'
import { createApp } from 'vue'
import router from './router'
import store from './store'
import App from './App.vue'
const app = createApp(App);
app.use(store)
app.use(router)
app.mount('#app')
function genActiveRule(routerPrefix) {
  return location => location.pathname.startsWith(routerPrefix);
}

import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
    {
        name: 'sub-app1',
          entry: '//localhost:3012', // 运行微应用的地址
          container: '#container', // 展示的DOM容器 id
          activeRule: genActiveRule('/sub-app1'), // 跳转路径
    },{
        name: 'sub-app2',
        entry: '//localhost:3013',
        container: '#container',
        activeRule: genActiveRule('/sub-app2'),
    },
],
{
    beforeLoad: [
      app => {
        console.log('before load', app);
      },
    ],
    beforeMount: [
      app => {
        console.log('before mount', app);
      },
    ],
    afterMount: [
      app => {
        console.log('after mount', app);
      },
    ],
    afterUnmount: [
      app => {
        console.log('after unload', app);
       // app.render({appContent: '', loading: false});
      },
    ],
  }
  );
// 启动 qiankun
start();

第三步,配置主应用路由

/qiankun-vue/main/...router/index.js

import { createRouter,createWebHistory }  from 'vue-router';
const Home = () => import(/*WebpackChunkName*/'@/views/Home.vue')
const About = () => import(/*WebpackChunkName*/'@/views/About.vue')
const routes = [
    {path:'/',name:'home',component: Home},
    {path:'/about',name:'about',component: About},
    {path:'/sub:catchAll(.*)',name:'Child',component:()=>import(/*webpackChunkName:'Empty.vue'*/'@/views/Empty.vue')} //这里遇到一个坑,就是找不到/sub-app1 /sub-app2路由路径,我就在此设置默认路径
]; const router = createRouter({ history: createWebHistory(), routes, }) export default router

/qiankun-vue/main/App.vue

<template>
<nav>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <!--需要与main.js配置的跳转路由一致-->
      <router-link to="/sub-app1">sub-app1</router-link> |
      <router-link to="/sub-app2">sub-app2</router-link>
    </nav>
    <router-view/>
    <!--微应用在此展示-->
    <div id="container"></div>
  <img alt="Vue logo" src="./assets/logo.png">

</template>

第四步,就需要在微应用上做对接了,只在主应用上配置了,微应用不配置也跑不起来

/qiankun-vue/sub-app1/main.js

import './public-path.js'
import { createApp } from 'vue'
import App from './App.vue'
import routes from './router'
import { createRouter, createWebHistory } from 'vue-router';
import store from './store'

let router = null;
let instance = null;
let history = null;

function render(props = {}) {
    const { container } = props;
    history = createWebHistory(window.__POWERED_BY_QIANKUN__ ? '/sub-app1' : '/');
    router = createRouter({
        history,
        routes: routes,
    });
    instance = createApp(App);
    instance.use(router);
    instance.use(store);
    instance.mount(container ? container.querySelector('#app') : '#app');
}

if (!window.__POWERED_BY_QIANKUN__) {
    render();
}

export async function bootstrap() {
    console.log('%c%s', 'color: green;', 'vue3.0 app bootstraped');
}

function storeTest(props) {
    props.onGlobalStateChange &&
    props.onGlobalStateChange(
        (value, prev) => console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev),
        true,
    );
    props.setGlobalState &&
    props.setGlobalState({

    });
}

export async function mount(props) {
    storeTest(props);
    render(props);
    instance.config.globalProperties.$onGlobalStateChange = props.onGlobalStateChange;
    instance.config.globalProperties.$setGlobalState = props.setGlobalState;
}

export async function unmount() {
    instance.unmount();
    instance._container.innerHTML = '';
    instance = null;
    router = null;
    history.destroy();
}

在/sub-app1根目录下新建一个public-path.js文件

if (window.__POWERED_BY_QIANKUN__) {
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
  }

然后配置vue.config.js

const { defineConfig } = require('@vue/cli-service')
const path = require('path')
const packageName = require('./package').name;

function resolve(dir){
  return  path.join(__dirname,dir)
}
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave:false,
  publicPath: '//localhost:3012',
  devServer:{
    port:3012,
    client:{
      overlay: {
        warnings: false,
        errors: true
      },
    },
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  configureWebpack: {
    resolve: {
      alias: {
        '@': resolve('src')
      }
    },
    output: {
      library: `sub-app1`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      chunkLoadingGlobal: `webpackJsonp_${packageName}`,
    },
  }
})

第五步配置sub-app2的微任务

/sub-app2/main.js

import './public-path.js' import { createApp } from 'vue' import App from './App.vue' import routes from './router' import { createRouter, createWebHistory } from 'vue-router'; import store from './store'
let router = null; let instance = null; let history = null;
function render(props = {}) {     const { container } = props;     history = createWebHistory(window.__POWERED_BY_QIANKUN__ ? '/sub-app2' : '/');     router = createRouter({         history,         routes: routes,     });     instance = createApp(App);     instance.use(router);     instance.use(store);     instance.mount(container ? container.querySelector('#app') : '#app'); }
if (!window.__POWERED_BY_QIANKUN__) {     render(); }
export async function bootstrap() {     console.log('%c%s', 'color: green;', 'sub-app2 page'); }
function storeTest(props) {     props.onGlobalStateChange &&     props.onGlobalStateChange(         (value, prev) => console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev),         true,     );     props.setGlobalState &&     props.setGlobalState({         ignore: props.name,         user: {             name: props.name,         },     }); }
export async function mount(props) {     storeTest(props);     render(props);     instance.config.globalProperties.$onGlobalStateChange = props.onGlobalStateChange;     instance.config.globalProperties.$setGlobalState = props.setGlobalState; }
export async function unmount() {     instance.unmount();     instance._container.innerHTML = '';     instance = null;     router = null;     history.destroy(); }

新键public-path.js,同sub-app1方法一样,再重复一次,我直接放代码了。

vue.config.js

const { defineConfig } = require('@vue/cli-service')
const path = require('path')
const packageName = require('./package').name;

function resolve(dir){
  return  path.join(__dirname,dir)
}
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave:false,
  publicPath: '//localhost:3013',
  devServer:{
    port:3013,
    client:{
      overlay: {
        warnings: false,
        errors: true
      },
    },
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  configureWebpack: {
    resolve: {
      alias: {
        '@': resolve('src')
      }
    },
    output: {
      library: `sub-app2`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      chunkLoadingGlobal: `webpackJsonp_${packageName}`,
    },
  }
})

最后就可以跑起来啦

 

 

标签:vue,sub,router,qiankun,instance,props,import,cli
来源: https://www.cnblogs.com/echoyu/p/16384329.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有