SingleSpa微前端基本使用以及原理

news2024/12/22 11:59:47

先说说singleSpa的缺点

  • 不够灵活 不能动态加载css文件
  • css不隔离
  • 没有js沙箱的机制 ( 没有全局对象 每次切换的应用 都是同一个window )

但是刚刚接触微前端 可以了解一下微前端的基础使用
qiankun微前端框架已经很成熟 也是基于singleSpa来实现的
点击跳转qiankun的基础使用

大致实现思路 (不了解微前端概念的可以去自行了解)

  • 首先在父应用注册一个应用
  • 当条件满足的时候(匹配路径) 会加载我们另一个子应用的脚本
  • 加载子应用用脚本的话
    – 那在我们子应用打包的时候 , 自身上就有一些类库了
  • 父应用加载到子应用的类库时候 就会调用子应用身上的一些方法了
    – 这个时候 类库就会把子应用整体的dom 放在( 挂载 )到父应用上面去
  • 而且我们要保证子应用自身引用的所有路径 都是相对于自身的绝对路径
    – 不然在父应用里使用子应用的一些操作 调用的是父应用的根路径 就会出问题

首先创建两个应用

一个子应用 各个父应用

在这里插入图片描述

我们需要父应用加载子应用 需要在子应用导出三个方法
bootstrap mount unmount ( SingleSpa的规定 )

vue的项目需要npm安装 Single-spa-vue
react的项目需要npm安装 Single-spa-react

初始化子应用

npm安装single-spa-vue

  • 配置main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'

// 引入singleSpaVue的包
import singleSpaVue from 'single-spa-vue'
Vue.config.productionTip = false


//子应用不能直接挂载
// new Vue({   
//   router,
//   render: h => h(App)
// }).$mount('#app')

// 而是封装成一个对象
const appOptions = {
    el:'#vue',  // 增加一个属性挂在到父应用的 id为vue的标签上
    router,
    render: h => h(App)
}

// 把vue和上面这个对象传入进去  这个singleSpaVue就会返回vueLife
// vueLife是包装好的生命周期  对应的就是bootstrap mount unmount  这三个方法
const vueLife = singleSpaVue({
  Vue,
  appOptions
})

//导出这三个方法  
//协议接入  我定好了这些方法  父应用会调用这些方法
export const bootstrap = vueLife.bootstrap
export const mount = vueLife.mount
export const unmount = vueLife.unmount
  • 我们需要父应用加载子应用 需要打包成一个个的lib去给父应用使用
  • 如何打包呢 在vue.config.js中配置
module.exports = {
  configureWebpack:{
    output:{
       // 给类库取一个名字
      library:'singleVue',
      // 指定模块类型  umd 会把打包后那三个属性挂在window上 
      //比如 window.bootstrap / window.mount / window.oumount
      libraryTarget:'umd' 
    },
    devServer:{
      port:10000 
    }
  }
}

初始化父应用

npm安装single-spa (不要加vue)

  • App.vue中处理结构
<template>
  <div id="app">
    <!-- 路由中没写/vue这个路径  说明路由匹配不到  但是可以去匹配这个路由来加载子应用  -->
    <router-link to="/vue">加载vue子应用</router-link>
    <!-- 这个id = vue就是子应用main.js中el挂载的#vue -->
    <div id="vue"></div>
  </div>
</template>
  • main.js处理
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 固定导出两个方法  注册应用 / 开始应用
import {registerApplication,start} from 'single-spa'
Vue.config.productionTip = false

// 注册应用  参数1 注册一个名字  参数2 一点要是个promise函数
registerApplication('myVueApp',
    async()=>{
      // 如果路径为 /vue  就会调用现在这个方法了   但是这个方法必须要导出子应用下的那三个方法 (不导出会报错) 
      // 但是这个三个方法在哪里呢  请看下面的图片 具体写法先写如下
      // 动态创建script标签 把这个模块引入进来  (加载顺序要先加载公共的  再加载自己的 )
      await loadScript('http://localhost:10000/js/chunk-vendors.js')
      await loadScript('http://localhost:10000/js/app.js')
      // 这样就可以导出window上的lib包了  'singleVue'就是vue.config.js配置的包名 
      return window.singleVue //bootstrap mount onmount
      
    },
    // 参数3 用户切换到/vue路径下 需要加载刚刚定义的子应用
    location=>location.pathname.startsWith('/vue')
)

// 处理上面参数2的promise
async function loadScript(url){
  // js加载是异步的 所以要用promise
  return new Promise((resole,reject)=>{
    let script = document.createElement('script')
    script.src = url
    script.onload = resole // 加载成功
    script.onerror = reject //加载失败
    document.head.appendChild(script) //把script放在html的head标签里 
  })
}

// 开启应用
start()


new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

在这里插入图片描述

  • 这样就开启了基础的嵌入子应用
    在这里插入图片描述
  • 点击按钮后 ( 但是还有问题 )
  • css没有隔离 ( 使用到了子应用的css 导致标签就居中了 )
  • 点击子应用的路由 跳转会错误
    – 路径上的/vue会消失( 点击子应用的路由 但是跳转的是父应用的路由 )
    – 需要在子应用中虚拟一个路径
    在这里插入图片描述

给子路由配置基础路径

  • 子应用的router/index中
const router = new VueRouter({
  mode: 'history',
  // base: process.env.BASE_URL, //删除原本的
  //点击子应用的路由的时候 需要通过/vue去加载
  base: '/vue', 
  routes
})
  • 但是还有个问题 每次点击子路由的时候 加载的是父应用上的路由
    – 我们需要操作子应用的时候 匹配的是子应用自身的路径
    – 解决方法 : 我们请求的每一个路由 都要加载的是自身的根路径才行
    -在子应用的main.js中配置
    主要看if(window.singleSpaNavigate){}后面的新增代码
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import singleSpaVue from 'single-spa-vue'
Vue.config.productionTip = false


const appOptions = {
    el:'#vue',  
    router,
    render: h => h(App)
}

const vueLife = singleSpaVue({
  Vue,
  appOptions 
})

//加上了如下的判断
//如果父应用引用我的时候
if(window.singleSpaNavigate){
  // 动态的设置一个属性 打包的时候加上一个目录 目录就是自身的根路径
  // 这样的时候我们发请求的时候 都会把这个路径拼到最前面 变成一个绝对路径
  __webpack_public_path__ = 'http://localhost:10000/'
}
//我们还需要让子应用独立运行 (如果父应用没有引用我的时候)
if(!window.singleSpaNavigate){
  // 子应用独立运行的话 就是正常初始化vue了  这个挂载父应用的el就可以删除
  delete appOptions.el
  //可以正常初始化vue了  
  new Vue(appOptions).$mount('#app')
}

export const bootstrap = vueLife.bootstrap
export const mount = vueLife.mount
export const unmount = vueLife.unmount

现在的话已经基础的实现了父应用嵌套子应用

并且子应用也可以独立运行了

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

6.同步异步、正则表达式

JS执行机制 js的特点&#xff1a;单线程&#xff0c;同一时间只能做一件事 可以通过多核CPU解决这个问题&#xff0c;允许js脚本创建多个线程&#xff0c;于是js出现了同步和异步 同步 程序执行的时候按照顺序依次执行 异步 程序执行的时候&#xff0c;会跳过某个步骤继续…

装饰者模式-C#实现

可以使用装饰者模式来动态地给一个对象添加额外的职责。 装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任&#xff0c;装饰者模式相比生成子类可以更灵活地增加功能。 在装饰者模式中各个角色有&#xff1a; 抽象构件&#xff08;Phone&#xff09;角色&#…

【NR 定位】3GPP NR Positioning 5G定位标准解读(十三)-DL-AoD定位

前言 3GPP NR Positioning 5G定位标准&#xff1a;3GPP TS 38.305 V18 3GPP 标准网址&#xff1a;Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;一&#xff09;-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;…

STM32点亮LED灯与蜂鸣器发声

STM32之GPIO GPIO在输出模式时可以控制端口输出高低电平&#xff0c;用以驱动Led蜂鸣器等外设&#xff0c;以及模拟通信协议输出时序等。 输入模式时可以读取端口的高低电平或电压&#xff0c;用于读取按键输入&#xff0c;外接模块电平信号输入&#xff0c;ADC电压采集灯 GP…

EM算法详解

EM(Expectation-Maximum)算法也称期望最大化算法,曾入选“数据挖掘十大算法”中,可见EM算法在机器学习、数据挖掘中的影响力。EM算法是最常见的隐变量估计方法,在机器学习中有极为广泛的用途,例如常被用来学习高斯混合模型(Gaussian mixture model,简称GMM)的参数;隐…

3D产品配置器帮助您更快进入市场的 5 种方式

如果您的电子商务商店可以从产品配置器的使用中受益&#xff08;而且大多数都可以&#xff09;&#xff0c;您还应该知道&#xff0c;此功能还可以帮助您的公司采用更具创新性的产品开发姿态。 更简单地说&#xff1a;它可以帮助您更快地构建更好的产品。 继续阅读以了解3D 产…

FPGA Vivado环境下实现D触发器

题目要求&#xff1a;使用Verilog HDL语言设计一个D触发器。请提交程序源代码和Word格式的作业文档&#xff0c;作业文档中应给出程序源代码及RTL分析原理图。 D触发器的工作原理&#xff1a; 初始状态下&#xff0c;触发器处于复位状态&#xff0c;输出为复位信号的稳定状态…

springboot266基于Web的农产品直卖平台的设计与实现

农产品直卖平台的设计与实现 摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#x…

2024 前端javaScript+ES6

JavaScript 基础 1、基本数据类型&#xff1a; 1.1 基本数据类型&#xff1a; Number&#xff08;数值&#xff09;&#xff1a;表示数字&#xff0c;包括整数和浮点数。例如&#xff1a;5、3.14。 String&#xff08;字符串&#xff09;&#xff1a;表示文本数据&#xff…

Docker容器化技术(互联机制实现便捷互访)

容器的互联是一种让多个容器中的应用进行快速交互的方式。它会在源和接收容器之间创建连接关系&#xff0c;接收容器可以通过容器名快速访问到源容器&#xff0c;而不用指定具体的IP地址。 1.自定义容器命名 连接系统依据容器的名称来执行。因此&#xff0c;首先需要自定义一…

【数据挖掘】实验2:R入门2

实验2&#xff1a;R入门2 一&#xff1a;实验目的与要求 1&#xff1a;熟悉和掌握R数据类型。 2&#xff1a;熟悉和掌握R语言的数据读写。 二&#xff1a;实验内容 1&#xff1a;R数据类型 【基本赋值】 Eg.1代码&#xff1a; x <- 8 x Eg.2代码&#xff1a; a city …

谷歌破解 OpenAI 模型关键信息;微软更改默认浏览器,不再主推 Edge 丨 RTE 开发者日报 Vol.163

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

fate隐私求交案例

intersect组件是解决纵向联邦学习中的隐私求交问题 fate隐私求交的方式有三种&#xff1a;raw,rsa,dh。raw方式不安全&#xff0c;rsa和dh方式是安全的&#xff0c;dh是基于对称加密的安全交集 rsa是基于RSA(非对称加密)的安全交集&#xff0c;&#xff0c;dh方法也用于安全的…

Uni-app跟学笔记(一):新建项目、运行、tabbar、全局配置

文章目录 1&#xff09;新建项目2&#xff09;项目运行3&#xff09;项目结构4&#xff09;开发规范5&#xff09;globalStyle全局外观配置6&#xff09;pages页面配置7&#xff09;tabbar8&#xff09;Condition 本博客为 uni-app 此门课的跟学笔记&#xff0c;目的是便于个人…

如何在安卓端的SAP里配置打印机

1、转到 SPAD 事务&#xff08;“假脱机管理”屏幕&#xff09;。单击“设备/服务器”选项卡&#xff0c;输入输出设备的名称&#xff0c;然后点击显示按钮。 2、如果打印机已配置&#xff0c;它将显示设备属性、输出设备属性和纸盒信息的所有详细信息。如果输入新的打印机名称…

基于ssm的志愿者招募系统的设计与实现(程序+文档+数据库)

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…

Java学习笔记------常用API(二)

Object 无有参构造 public Object() 空参构造 成员方法&#xff1a; public String toString() 返回对象的字符串表示 public boolean equals(object obj) 比较两个对象是否相等 Object默认用号比较地址值&#xff0c;需要重写才能比较属性值 protected O…

基于java+springboot+vue实现的自习室管理和预约系统(文末源码+Lw)23-177

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装自习室管理和预约系统软件来发挥其高效地信息处理的作用&a…

vue脚手架创建项目失败,报错淘宝镜像地址证书过期问题解决

场景&#xff1a; 使用vue-cli脚手架创建vue新项目时&#xff0c;控制台报错&#xff0c;创建失败 控制台报错&#xff1a;ERROR Failed to get response from https://registry.npm.taobao.org/binary-mirror-config 尝试过的方式&#xff1a; 清除npm缓存或删除npm-cache文…

YashanDB亮相2024年中国石油石化信息通信技术交流大会

3月6日-8日&#xff0c;2024年中国石油石化信息通信技术交流大会在成都举办。YashanDB携智慧油气化数据管理解决方案亮相本次展会&#xff0c;展示最新的研发成果和场景应用。 当前&#xff0c;石油石化行业数字化转型不断深化&#xff0c;随之而来的是海量数据的计算与交互&a…