微前端-qiankun

news2025/7/10 0:12:31

概念

使用框架:qiankun

介绍:

qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
qiankun官网:Go
当使用 iframe 整合系统时,假设我们有系统 A, 当我们想把系统 B 引入 A 系统时,只需要 B 系统提供一个 url 给 A 系统引用即可,这里我们把 A 系统叫做父应用,把 B 系统叫做子应用。同样的,微前端也延续了这个概念,微前端在使用起来基本和使用 iframe 一样平滑。

结构:

分为:主应用(父),微应用(子)
图1:
在这里插入图片描述

使用案例:

目标:

点击one按钮,切换到one微应用
点击two按钮,切换到two微应用
并且每个微应用都可以跳转自己的路由
在这里插入图片描述
在这里插入图片描述

步骤:

  1. 创建主应用项目
  2. 创建微应用项目
  3. 将微应用挂到主应用项目中

1. 在主应用中安装qiankun框架

$ yarn add qiankun # 或者 npm i qiankun -S

2. 在 主应用 中注册微应用

main.js:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

import { registerMicroApps, start } from 'qiankun';

registerMicroApps([
  {
    name: "vueChildOne",
    props: { age: 10 }, //给子应用传数据
    entry: "//localhost:3001", //默认会加载这个html,解析里面的js,动态执行(子应用必须支持跨域)里面,是用fetch去请求的数据
    container: "#child-one-content", //挂载到主应用的哪个元素下
    activeRule: "/child-one", //当我劫持到路由地址为//child-one时,我就把http://localhost:3001这个应用挂载到#child-one-content的元素下
  },
  {
    name: 'vueChildTwo',
    entry: '//localhost:3002',
    // entry: { scripts: ['//http://192.168.2.120:3001/main.js'] },
    container: '#child-two-content',
    activeRule: '/child-two',
  },
]);

// start(); // 启动qiankun,这里不在一开始的时候使用

createApp(App).use(ElementPlus).use(router).mount('#app-base')

App.vue

<template>
  <div>
    <div class="bens">
      <el-button type="primary" @click="$router.push('/child-one')">childOne</el-button>
      <el-button type="primary" @click="$router.push('/child-two')">childTwo</el-button>
    </div>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},
};
</script>

<style>
.bens {
  width: 100%;
  display: flex;
  justify-content: center;
  position: absolute;
  top: 15px;
  left: 0;
  z-index: 9999999;
}
#app-base {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

index.html:

// 将id:app 改为 app-base  自定义就行,只要与main.js对应起来,切不与微应用重复
<div id="app-base"></div>

router.js

import { createRouter, createWebHistory } from "vue-router";

// 2. 配置路由
const routes = [
    {
        path: '/child-one',
        component: () => import('@/views/childOne/index.vue'),
    },
    {
        path: '/child-two',
        component: () => import('@/views/childTwo/index.vue'),
    },
];
// 1.返回一个 router 实列,为函数,里面有配置项(对象) history
const router = createRouter({
    history: createWebHistory(),
    routes,
});

// 3导出路由   然后去 main.ts 注册 router.ts
export default router

childOne/index.vue

<template>
  <h2>我是 主应用 one</h2>
  <div id="child-one-content"></div>
</template>

<script>
import { start } from "qiankun";
export default {
  name: "childOne",
  components: {},
  mounted() {
    // 启动微应用
    if (!window.qiankunStarted) {
      window.qiankunStarted = true;
      start();
    }
  },
};
</script>

<style>
</style>

childTwo/index.vue

<template>
  <h2>我是 主应用 two</h2>
  <div id="child-two-content"></div>
</template>

<script>
import { start } from "qiankun";
export default {
  name: "childTwo",
  components: {},
  mounted() {
    // 启动微应用
    if (!window.qiankunStarted) {
      window.qiankunStarted = true;
      start();
    }
  },
};
</script>

<style>
</style>

4. 微应用配置child-one

src下创建public-path.js

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

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
import './public-path' // 引入public-path.js

// createApp(App).mount('#app')

let instance = null;
function render(props = {}) {
  if (instance) return;
  const { container } = props;
  console.log(container);
  instance = createApp(App)
    .use(router)
    .mount(container ? container.querySelector("#app-child-one") : "#app-child-one");
}

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

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 = null;
}

index.html

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app-child-one"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

vue.config.js

module.exports = {
    lintOnSave: false,
    devServer: {
        port: "3001",
        headers: {
            "Access-Control-Allow-Origin": "*", //所有人都可以访问我的服务器
        },
    },
    configureWebpack: {
        output: {
            // library: `${name}-[name]`,
            library: `vueChildOne`,
            libraryTarget: "umd", // 把微应用打包成 umd 库格式
            // jsonpFunction: `webpackJsonp_${name}`,
        },
    },
};

router.js

import { createRouter, createWebHashHistory, createWebHistory } from "vue-router";

// 2. 配置路由
const routes = [
    {
        path: '/',
        component: () => import('@/views/home/index.vue'),
    },
    {
        path: '/about',
        component: () => import('@/views/about/index.vue'),
    },

];
// 1.返回一个 router 实列,为函数,里面有配置项(对象) history
const router = createRouter({
    history: createWebHashHistory('/child-one'),
    routes,
});

// 3导出路由   然后去 main.ts 注册 router.ts
export default router

5. 微应用配置child-two

与child-two同理,只要把对应的" child-one " 换成" child-two "即可

demo代码地址

码云地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/406287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL+Navicat安装配置教程(超级详细、保姆级)

MySQLNavicat安装配置教程&#xff08;超级详细、保姆级&#xff09;一、 下载MySQL1. 选择想要安装的版本&#xff0c;点击Download下载二、安装MySQL1. 选择设置类型2. 选择安装的产品和功能3. 先选中“MySQL Server 5.7.31” &#xff0c;之后点击下方的蓝色“Advanced Opti…

Crontab表达式执行定时任务

Cron是一个Linux下的定时执行工具&#xff0c;可用于执行定时任务。 启动、关闭、查看Cron服务的语法&#xff1a; 启动&#xff1a;/sbin/service crond start 查看&#xff1a;/sbin/service crond status 停止&#xff1a;/sbin/service crond stop 重启&#xff1a;/sbin…

微信小程序 h5页面跳转小程序(超详细讲解)

h5跳转小程序 实战项目从无到完整的h5跳转小程序经验&#xff0c;跳转方式分为云函数跳转和开放性标签跳转。 开放性标签是针对微信里面浏览器使用的&#xff0c;而云函数跳转在外部以及微信里面都可以使用。 建议需要的同学先全部浏览一遍本文。内容较长较为啰嗦。 一、不…

jQuery 获取与设置 元素属性【一篇文章轻松拿下】

hello大家好呀&#xff01;此篇文章带领大家熟练掌握 jQuery 的属性方面的操作&#xff0c;包括固有属性的获取与设置&#xff0c;自定义属性的获取与设置等等&#xff0c;走进 jQuery 的更深层次阶段 文章目录&#xff1a; 一&#xff1a;固有属性的设置与获取 prop 1.1 固有…

uniapp 中设置全局页面背景色

uniapp 中设置全局页面背景色 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 未生效 : 在pages.json里面设置单页面背景色,这种是不行的,只能在页面内生效 方法1: pages.json globalStyle 中设置 backgroundColor // pages.json"globalStyle&quo…

Vue路由传参的方法和传递参数为对象时的问题

vue路由传参方法 在编写vue项目时&#xff0c;时常会使用路由在不同页面中传递参数&#xff0c;常见使用方式如下&#xff1a; this.$router.push({path: "/test",query: {a: 1,b: 2} }) 这样我们就传递了两个参数&#xff0c;在 /test 页面 就可以接收这两个参数…

【网络】https协议

&#x1f941;作者&#xff1a; 华丞臧. &#x1f4d5;​​​​专栏&#xff1a;【网络】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449; LeetCode刷题网站 文章…

黑马程序员最新版JavaWeb综合案例(前后端完整版)

JavaWeb 综合案例 学习视频链接: 黑马程序员最新版JavaWeb基础教程&#xff0c;Java web从入门到企业实战完整版 完整代码链接&#xff1a; https://github.com/HaiLei-Fly/JavaWeb-brand 1、功能介绍 案例功能&#xff1a; 用户登录&#xff08;账号密码登录&#xff09;…

基于JavaSpringBoot+Vue+uniapp微信小程序实现在线房屋装修管理系统

博主介绍&#xff1a;✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

分布式Id生成方式

为什么要用分布式ID&#xff1f; 在说分布式ID的具体实现之前&#xff0c;我们来简单分析一下为什么用分布式ID&#xff1f;分布式ID应该满足哪些特征&#xff1f; 1、什么是分布式ID&#xff1f; 拿MySQL数据库举个栗子&#xff1a; 在我们业务数据量不大的时候&#xff0c…

Zotero 超好用插件的下载链接及配置方法(PDF-translate/ZotFile/茉莉花/Zotero Scihub)

目录前言插件安装方法插件一&#xff1a;文献翻译插件&#xff08;pdf-translate&#xff09;插件二&#xff1a;文献附件管理&#xff08;ZotFile&#xff09;插件三&#xff1a;中文文献插件&#xff08;茉莉花&#xff09;插件四&#xff1a;Sci-Hub 自动下载文献&#xff0…

vue3项目实战中的接口调用方法(一)async/await用法 对axios二次封装 实现异步请求

vue3 async和await联合调用接口 &#x1f525;一文搞定&#x1f525;点击进入vue专栏&#x1f525;async/await定义async/await用法&#x1f525;async/await的基本用法async/await的使用场景async/await实战&#x1f525;&#x1f525;处理一个异步请求处理多个异步请求summar…

从函数计算到 Serverless 架构

作者&#xff1a;秋雨陈 前言 随着 Serverless 架构不断发展&#xff0c;各云厂商和开源社区都已经布局 Serverless 领域&#xff0c;一方面表现在云厂商推出传统服务/业务的 Serverless 化版本&#xff0c;或者 Serverless 计算平台&#xff1b;另一方面表现在开源社区中 Se…

远程构建(命令、脚本构建)jenkins

在对应项目&#xff0c;开启远程构建开关添加API token系统设置调整用户权限获取crumbcurl调用构建 1、进入对应项目的设置页面&#xff1a;开启远程构建开关 2、 添加 API token&#xff1a;进入对应用户的设置页面 3、系统设置调整权限&#xff0c;如图 4、由于jenkins的安全…

使用element-ui中的el-upload自定义上传

题引&#xff1a; 日常开发系统的时候&#xff0c;我们都会有上传文件的功能。但是用原生的文件上传是很繁琐的&#xff0c;那么我们都会选择使用UI组件库&#xff0c;如element-plus、ant-design等。这些UI组件库是非常容易上手且实用的&#xff0c;但是万恶的需求是奇怪多变…

vue项目引入百度地图BMapGL和BMap实例,以及辅助工具BMapGLLib 的引入,BMapGL鼠标绘制功能

记录一下vue项目使用百度地图所用的api和踩过的坑&#xff0c;减少以后引用少走弯路。旨在记录&#xff0c;第一次开贴&#xff0c;不足之处请多多指教。废话不多说&#xff0c;开撸&#xff01; 1、引用百度地图 这里账号密钥不多说&#xff0c;上链接&#xff0c;自己注册。…

【kubernetes】k8s集群搭建(完整详解)

目录 一、准备工作 二、配置 1、修改主机名 2、修改hosts文件 3、关闭防火墙和SELinux 4、关闭swap 5、修改网卡配置 6、系统模块配置 7、免密登录 8、安装k8s和docker 9、查看k8s集群需要的镜像版本 10、初始化Master节点 11、node配置 12、拉取Nginx镜像进行配置…

【uniapp小程序】视图容器cover-view

&#x1f352;观众老爷们好呀&#xff0c;这里是前端小刘不怕牛牛频道&#xff0c;小程序系列又更新新文章啦&#xff0c;今天的内容是uniapp小程序的视图容器&#xff0c;cover-view &#x1f352;准备好了吗&#xff1f;那我们就发车啦&#xff0c;赶紧拿起小本本把笔记做起来…

10Wqps 超高并发 API网关 架构演进之路

说在前面 在尼恩的&#xff08;50&#xff09;读者社群中&#xff0c;经常遇到一个 API网关 架构方面的问题&#xff1a; (1) 尼恩老师&#xff0c;最近公司我们在规划业务出口网关(目的&#xff0c;整合规范外部调用&#xff0c;如短信平台 mqtt 等) 我在做整理技术方案&…

智能车竞赛:Infineon TC264单片机使用总结快速入门

本文主要是为了备赛第十八届全国大学生智能车竞赛&#xff0c;基于逐飞开源库和芯片数据手册的一些学习总结&#xff0c;使用英飞凌官方的AURIX Development Studio开发环境。 正如STM32的开发方式有标准库和HAL库&#xff0c;Infineon单片机也有官方库&#xff0c;而逐飞开源…