qiankun 微前端实例化使用

这篇具有很好参考价值的文章主要介绍了qiankun 微前端实例化使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、qiankun使用场景

  1. 简介:qiankun是在single-spa的基础上实现的,可以保证各个项目独立使用,也可以集成使用。各系统之间不受技术栈的限制,集成使用也能保证各样式和全局变量的隔离。

      模块的插拔式使用,当公司项目集是一个大系统下包含多个子系统或者模块时,可以采用这种方式动态部署各个系统。

      亦或者是老项目技术升级和重构,可以通过qiankun按模块进行改造,避免对整个系统产生较大的影响。

      功能和iframe类似,但是由于iframe数据通信难度较大,且有安全和SEO的问题,所以iframe使用体验不佳。

  2. 原理逻辑:

    a. 需要在各个子应用的基础上新增一个主应用,通过主应用监听路由变化。

    b. 当有路由切换时就会触发上述监听函数从而去匹配在主应用中注册的各个子应用路径(activeRule)是否匹配。

    c. 匹配到子应用后就会加载子应用的资源到对应的容器当中去。

二、实现样例

  本样例使用的是Node 16的版本,主应用采用Vue3框架,两个子应用分别使用Vue2和Vue3框架。qiankun版本是2.10.16。

  1. 搭建主应用,利用脚手架创建一个qiankun-main的主应用,同时安装qiankun组件(qiankun只需要在主应用安装,子应用不需要),其中代码中标注重点的内容是配置qiankun的关键步骤

     1.1 打开vue.config.js文件,添加跨域处理,避免跳转时出现跨域问题

qiankun 微前端实例化使用qiankun 微前端实例化使用
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 8085,
    headers: {            // 重点1: 允许跨域访问子应用页面
        'Access-Control-Allow-Origin': '*',
    }
  }
})
vue.config.js

     1.2 主应用中设置子应用接收容器

qiankun 微前端实例化使用qiankun 微前端实例化使用
<template>
  <div class="app">
    <p><router-link to="/">点击跳转到父页面</router-link></p>
    <button @click="login">登陆</button>
    <p><router-link to="/vue3">跳转到Vue3子应用</router-link></p>
    <p><router-link to="/vue2">跳转到Vue2子应用</router-link></p>
    <router-view />
    <div id="vue3"></div>    <!-- 重点2:子应用容器 id -->
    <div id="vue2"></div> <!-- 重点2:子应用容器 id -->
  </div>
</template>

<script>
import actions from '@/shared/actions';

export default {
  name: 'App',
  components: {
  },
  mounted() {
    actions.onGlobalStateChange((state, prevState) => {
      // state: 变更后的状态; prevState: 变更前的状态
      console.log('主应用观察者:token值改为', prevState.token);
      console.log("主应用观察者:登录状态发生改变,改变后的 token 的值为 ", state.token);
    });
  },
  methods: {
    login() {
      console.log('进入登陆事件');
      setTimeout(() => {
        const token = 'token_' + Math.floor(Math.random() * 100000);
        //登陆后随机生成token并设置
        actions.setGlobalState({ token });
        this.$router.push("/vue3");
      }, 300);
    }
  }
}
</script>

<style>
#app {
  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>
App.vue

    1.3 在src根目录下新增public-path文件;同时改造路由,设置返回的base地址

qiankun 微前端实例化使用qiankun 微前端实例化使用
if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
public-path.js
qiankun 微前端实例化使用qiankun 微前端实例化使用
import {
  createRouter,
  createWebHashHistory
} from 'vue-router'
import '../public-path' // 重点3: 引入public-path文件
const router = createRouter({
  base: window.__POWERED_BY_QIANKUN__ ? '/vue3' : '/', // 重点4:qiankun进入子应用时,返回true
  history: createWebHashHistory(), // 重点5
  routes: [{
          path: '/',
          redirect: '/child'
      },
      {
          path: '/child',
          component: () => import('@/components/child')
      }
  ]
})
export default router
router/index.js

    1.4 注册和引入子应用

qiankun 微前端实例化使用qiankun 微前端实例化使用
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { registerMicroApps, start, setDefaultMountApp } from 'qiankun'

createApp(App).use(router).mount('#app')

registerMicroApps([
  {
    name: "vue3 app",
    entry: "//localhost:8086", // 重点8:对应重点6
    container: '#vue3',         // 重点9:对应重点2
    activeRule: '/#/vue3',        // 重点10:对应重点4
    props: {
        appContent: '我是主应用传给vue的值'
    }
  },
  {
    name: "vue2 app",
    entry: "//localhost:8087", // 重点8:对应重点6
    container: '#vue2',         // 重点9:对应重点2
    activeRule: '/#/vue2',        // 重点10:对应重点4
    props: {
        appContent: '我是主应用传给Vue2的值'
    }
  }
])
setDefaultMountApp("/")  // 重点11:启动默认的子模块
// 启动
start()
main.js

  2. 搭建子应用1, 同样利用脚手架创建一个qiankun-vue3-child,项目使用Vue3作为基础框架

    2.1 同样在src目录下创建public-path.js文件

qiankun 微前端实例化使用qiankun 微前端实例化使用
if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
public-path.js

    2.2 改造router/index.js文件, 确认在qiankun模式下的路由基础路径

qiankun 微前端实例化使用qiankun 微前端实例化使用
import {
  createRouter,
  createWebHashHistory
} from 'vue-router'
import '../public-path' // 重点3: 引入public-path文件
const router = createRouter({
  base: window.__POWERED_BY_QIANKUN__ ? '/vue3' : '/', // 重点4:qiankun进入子应用时,返回true
  history: createWebHashHistory(), // 重点5
  routes: [
  ]
})
export default router
router/index.js

    2.3 修改入口函数main.js,导入钩子函数

qiankun 微前端实例化使用qiankun 微前端实例化使用
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import actions from './micros/actions'

let instance = null

function render(props = {}) {
  // qiankun模式下实现父子应用之间通信
  if (props) {
    actions.setActions(props);
  }

  const { container } = props
  // 为了避免根id#app与其他DOM冲突,需要限制查找范围
  instance = createApp(App).use(router).mount(container ? container.querySelector('#child-app') : '#child-app')
}

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() {
  if (instance) {
    console.log(instance, instance.unmount);
    // instance.unmount();
    instance = null
  }
}

// createApp(App).use(router).mount('#child-app')
main.js

    2.4 修改打包配置文件vue.config.js,设置服务端口以及打包模式

qiankun 微前端实例化使用qiankun 微前端实例化使用
const { defineConfig } = require('@vue/cli-service')
const { name } = require('./package');
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 8086,            // 重点6
    headers: {            // 重点7:同重点1,允许子应用跨域
        'Access-Control-Allow-Origin': '*',
    },
  },
  // 自定义webpack配置
  configureWebpack: {
      output: {
          library: `${name}-[name]`,
          libraryTarget: 'umd',        // 把子应用打包成 umd 库格式
          // jsonpFunction: `webpackJsonp_${name}`,
      },
  },
})
vue.config.js

  3. 搭建子应用2,步骤与第2步类似,只是使用Vue2作为基础框架

三、功能演示

qiankun 微前端实例化使用

 四、常见问题

  1. 子应用部署在同一个服务器同一个端口的不同路径下如何配置?

    基本和部署在不同服务器的类似,只是将注册子应用的entry的服务器端口号换成某个路径,同时将打包的publicPath改为该路径

qiankun 微前端实例化使用qiankun 微前端实例化使用
// 主应用入口文件中注册子应用
registerMicroApps([
  {
    name: "vue3_app",
    entry: "/entry_vue3", // 对应之前的 //localhost:8086
    container: '#vue3',    
    activeRule: '/#/vue3',     
    props: {
        appContent: '我是主应用传给vue的值'
    }
  }
])

// 子应用的 router/indexedDB.js
const router = createRouter({
  base: window.__POWERED_BY_QIANKUN__ ? '/vue3' : '/entry_vue3', // 设置路由路径
  history: createWebHashHistory(),
  routes: [
  ]
})

// 打包文件vue.config.js中添加默认路径
module.exports = defineConfig({
  publicPath: devFlag ? '/' : '/entry_vue3',
  transpileDependencies: true,
  devServer: {
    port: 8087,            // 重点6
    headers: {            // 重点7:同重点1,允许子应用跨域
        'Access-Control-Allow-Origin': '*',
    },
  },
  // 自定义webpack配置  重点12
  configureWebpack: {
      output: {
          library: `${name}-[name]`,
          libraryTarget: 'umd',        // 把子应用打包成 umd 库格式
          // jsonpFunction: `webpackJsonp_${name}`,
      },
  },
})
同服务器同端口部署配置

  2. 主子应用之间通信?

    2.1 使用qiankun框架提供的 initGlobalState 实现的,主要有下面三个函数:

      onGlobalStateChange(callback, Immediately)在当前应用监听全局状态变化;

      setGlobalState(state)按照一级属性进行状态设置,微应用只能修改一级属性;

      offGlobalStateChange()移除当前的状态监听,微应用在unmount时默认调用;

    2.2 使用方式,效果可见上面的案列图中对token的打印信息

      a. 主应用的src目录下新增shared/actions.js文件。

qiankun 微前端实例化使用qiankun 微前端实例化使用
import { initGlobalState } from "qiankun";

const initialState = {
  token: 'no token'
};
const actions = initGlobalState(initialState);

export default actions;
actions.js

      b. 比如在主应用的App.vue中使用并且实现登陆后生成token以及跳转到vue3子应用

qiankun 微前端实例化使用qiankun 微前端实例化使用
import actions from '@/shared/actions';

export default {
  name: 'App',
  components: {
  },
  mounted() {
    actions.onGlobalStateChange((state, prevState) => {
      // state: 变更后的状态; prevState: 变更前的状态
      console.log('主应用观察者:token值改为', prevState.token);
      console.log("主应用观察者:登录状态发生改变,改变后的 token 的值为 ", state.token);
    });
  },
  methods: {
    login() {
      console.log('进入登陆事件');
      setTimeout(() => {
        const token = 'token_' + Math.floor(Math.random() * 100000);
        //登陆后随机生成token并设置
        actions.setGlobalState({ token });
        this.$router.push("/vue3");
      }, 300);
    }
  }
}
App.vue

      c. 子应用中使用时首先在根目录下创建一个micros/actions.js文件

qiankun 微前端实例化使用qiankun 微前端实例化使用
function emptyAction() {
  // 确保单独部署时不会报错
  console.warn('当前无可执行的Action');
}

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;
actions.js

      d. 子应用的APP.vue页面中监听主应用中数据的变化以及子应用主动修改数据观察主应用是否能接收到

qiankun 微前端实例化使用qiankun 微前端实例化使用
import actions from '@/micros/actions.js';

export default {
  name: 'App',
  components: {
  },
  mounted() {
    actions.onGlobalStateChange(state => {
      console.log('子应用Vue的观察函数:', state);
    }, true)
  },
  methods: {
    changeToken() {
      actions.setGlobalState({ token: 'Vue3_' + Math.floor(Math.random() * 100000) })
    }
  }
}
App.vue

  3. 各个应用之间如何提取一些公共的资源或者模块?

    可以将公共模块提取成一个公共组件发布到npm,然后由各个应用按需安装。

  4. 各个系统如何做到只登陆一次?

    可以参考单点登陆实现,简单逻辑就是比如:

    a. 有一个地址sso.com做为控制中心,然后a.com、b.com为子模块。

    b. 当访问a.com时无权限时路由会携带参数“a.com”自动跳转到登陆页面,输入用户名密码信息后,经过sso.com验证通过生成ticket并返回给页面同时跳转到a.com并下发ticket。

    c. a.com请求获取到ticket后访问sso.com的服务器进行验证是否有效,有效则允许登陆,这样就完成了一次登陆。

    d. 如果在已登录的状态下跳转到b.com,则省略第二步的登陆验证直接将ticket携带到b.com,然后再访问sso.com进行有消息验证。

 

注意:主应用注册的activeRule为/vue3时跳转到子应用不生效可能是因为浏览器路由跳转时自动加上/#/,所以在activeRule也需要修改为/#/vue3才可以跳转文章来源地址https://www.toymoban.com/news/detail-760452.html

到了这里,关于qiankun 微前端实例化使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微前端框架qiankun剖析

    要了解qiankun的实现机制,那我们不得不从其底层依赖的single-spa说起。随着微前端的发展,我们看到在这个领域之中出现了各式各样的工具包和框架来帮助我们方便快捷的实现自己的微前端应用。在发展早期,single-spa可以说是独树一帜,为我们提供了一种简便的微前端路由工

    2024年02月05日
    浏览(29)
  • 微前端--qiankun原理概述

    demo放最后了。。。 一》微前端概述         微前端概念是从微服务概念扩展而来的,摒弃大型单体方式,将前端整体分解为小而简单的块,这些块可以独立开发、测试和部署,同时仍然聚合为一个产品出现在客户面前。可以理解微前端是一种将多个可独立交付的小型前端

    2023年04月14日
    浏览(21)
  • 【微前端】qiankun

    专栏: 【微前端】什么是微前端 【微前端】qiankun 【微前端】qiankun + vite + vue3 qiankun 是一种前端微服务架构,旨在解决大型复杂应用的拆分和管理问题。 qiankun 的设计思路是基于“微服务”架构和“大前端”思想的,通过拆分前端应用、动态加载、状态共享、兼容性和稳定性

    2024年02月10日
    浏览(31)
  • 微前端----qiankun

    1.qiankun是什么?它解决了哪些问题? qiankun 是一个基于 single-spa 的微前端实现库,换句话说就是对single-spa进行了封装得到qiankun。 qiankun就是将一个大应用拆分成好多小项目,qiankun解决了我们协同开发的一些问题,其次更方便于我们进行更新代码 。 2.qiankun的实现原理及过程

    2024年02月12日
    浏览(24)
  • 微前端框架篇一,了解qiankun

    微前端是一种将复杂单体应用拆分为多个小型独立前端应用,然后将这些小应用按需加载并集成到主应用的技术方案。 每个子应用都有自己的 JavaScript 和 CSS 代码。 单页Web应用(single page web application,SPA),就是只有一张Web页面的应用。所有页面都来回在这张页面上切换。

    2024年01月22日
    浏览(27)
  • vue项目集成乾坤(qiankun)微前端

    npm i qiankun -S qiankun文档官方地址:https://qiankun.umijs.org/zh/guide 新建一个.vue文件 配置路由地址

    2024年02月05日
    浏览(33)
  • 微前端:qiankun的五种通信方式

    今天盘点一下 qiankun 父子应用的通信方式都有哪些,我发现了 5 种。 1、localStorage/sessionStorage 2、通过路由参数共享 3、官方提供的 props 4、官方提供的 actions 5、使用vuex或redux管理状态,通过shared分享 接下来我们一个一个进行说明 有人说这个方案必须主应用和子应用是同一个

    2024年03月21日
    浏览(34)
  • 【qiankun】前端微服务架构踩坑记录

    目录 前言 1.Cannot GET /cooperation/board 场景: 分析 解决 2.Invalid options in vue.config.js:\\\"css.requireModuleExtension\\\" is not allowed 原因 解决 3.less版本升级导致除法写法未转换 原因 解决 4.主子应用样式隔离 场景 解决 5.在webpack5中配置output报错 报错如下  原因  解决 6.微应用部署后报错 场景

    2024年02月15日
    浏览(24)
  • 微前端架构-qiankun在vue3的应用

    本文章介绍了qiankun在vue3的应用,其中子应用有vue2、vue3、react、angular qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 其他几款([single-spa]、[micro-app]、[百度emp]]) 使用 iframe 整合系统时,假设我们有系统 A, 当

    2023年04月08日
    浏览(27)
  • 基于vue3+webpack5+qiankun实现微前端

    一 主应用改造(又称基座改造) 1 在主应用中安装qiankun(npm i qiankun -S)  2 在src下新建micro-app.js文件,用于存放所有子应用。  3 改造vue.config.js,允许跨域访问子应用页面  4 改造main.js   5 在App.vue中写响应跳转子应用(根据自己的项目找对应位置写,不局限于App.vue)   需要注

    2024年02月13日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包