使用qiankun微服务搭建vue3 项目 1
qiankun是对single-spa的扩写,目前支持的是vue2,对于vue3的支持不是很成熟,而且不支持vite
本章介绍大概的搭建思路,具体的搭建套路可以查看文档:
https://qiankun.umijs.org/zh/guide/getting-started
新建一个父级的项目叫base-site:
1. 在main.js中写:
import { createApp } from "vue"; import App from "./App.vue"; import router from "./routers"; import { registerMicroApps, start } from "qiankun"; createApp(App).use(router).mount("#app"); registerMicroApps([ { name: "child-site", // app name registered//子应用的名字,最好和子应用的package.json的name保持一致,方便管理 entry: "http://192.168.8.121:9002",//子应用的地址,这里要允许子应用跨域,不然会报跨域错误,后续会讲解 container: "#yourContainer",//子系统要挂载到父页面的容器节点,类似iframe activeRule: "/child-site",//这里要注意的是qiankun没有自己的路由,如果你是react就要借助react-router,如果你是vue就要借助vue-router去实现匹配 }, ]); //预加载子应用 start();
这是路由部分,本处用的是vue-router V4.X:
import { createRouter, createWebHistory } from "vue-router"; const routes = [ { path: '/other-site', component: () => import('@/views/other-site.vue'), name: 'other-site', }, ]; let router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes, }); export default router
挂载子系统的页面demo:
<template> <div id="yourContainer" /> </template> <script setup lang="ts"></script> <style scoped lang="scss"></style>
然后介绍一下子应用写法,主要就是注意按照官方文档暴露相关的钩子函数。
在子应用的main.js中这么写:
import { createApp } from "vue"; import App from "./App.vue"; let appDom = null; const isQiankun = window.__POWERED_BY_QIANKUN__; function render() { appDom = createApp(App); } /** * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。 */ export async function bootstrap() { console.log("react app bootstraped"); } /** * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法 */ export async function mount(props) { console.log("让我们来看看mount里面有啥", props); if (!appDom) { render(); } console.log("此时的appdom是什么呢", appDom); appDom.mount( props.container ? props.container.querySelector("#child-site_app") : "#child-site_app" ); } /** * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例 */ export async function unmount(props) { console.log("让我们来看看unmount里面有啥", props); if (!appDom) { render(); } appDom.unmount(); appDom = null; } if (!isQiankun) { render(); appDom.mount("#child-site_app"); }
如此一个微服务的前端就搭建好了。效果如下:
这里回到支持跨域的那个问题,如果你是本地开发的话可以在vue.config.js中这么写:
devServer: { headers: { 'Access-Control-Allow-Origin': '*' }, }
如果你发布到生产环境可以在nginx中这么写支持跨域:
server { listen 9002;#子应用的端口 server_name 192.168.8.121;#子应用的IP location / { #允许跨域开始 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET,POST,OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With, If-Modified-Since,Cache-Control,Content-Type,Authorization'; #允许跨域结束 root C:/software/nginx-1.23.1/html/child-site; index index.html index.htm; } }
后面空了会介绍一下父子应用间的通信
积累小的知识,才能成就大的智慧,希望网上少一些复制多一些原创有用的答案