首页 > 其他分享 >qiankun 微前端使用方式

qiankun 微前端使用方式

时间:2024-06-12 20:55:53浏览次数:20  
标签:vue const render 方式 app qiankun import 前端 store

概论

主要是有一个微前端的主权项目,实现对微服务的调用,类似iframe显示,父应用和子应用可以通过一些数据通信方式实现数据通信。

代码

  • 微前端注册
import Vue from 'vue'
import App from './App.vue'
import { registerMicroApps, start, setDefaultMountApp } from 'qiankun'
import microApps from './micro-app'
import 'nprogress/nprogress.css'

Vue.config.productionTip = false

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

// 定义loader方法,loading改变时,将变量赋值给App.vue的data中的isLoading
function loader (loading) {
  if (instance && instance.$children) {
    // instance.$children[0] 是App.vue,此时直接改动App.vue的isLoading
    instance.$children[0].isLoading = loading
  }
}

// 给子应用配置加上loader方法
const apps = microApps.map(item => {
  return {
    ...item,
    loader
  }
})

registerMicroApps(apps, {
  beforeLoad: app => {
    console.log('before load app.name====>>>>>', app.name)
  },
  beforeMount: [
    app => {
      console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name)
    }
  ],
  afterMount: [
    app => {
      console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name)
    }
  ],
  afterUnmount: [
    app => {
      console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name)
    }
  ]
})
setDefaultMountApp('/sub-vue')
start()

  • 微前端微应用数组
import store from './store'

const microApps = [
  {
    name: 'sub-vue',
    entry: process.env.VUE_APP_SUB_VUE,
    activeRule: '/sub-vue'
  },
  {
    name: 'sub-react',
    entry: process.env.VUE_APP_SUB_REACT,
    activeRule: '/sub-react'
  },
  {
    name: 'sub-html',
    entry: process.env.VUE_APP_SUB_HTML,
    activeRule: '/sub-html'
  }
]

const apps = microApps.map(item => {
  return {
    ...item,
    container: '#subapp-viewport', // 子应用挂载的div
    props: {
      routerBase: item.activeRule, // 下发基础路由
      getGlobalState: store.getGlobalState // 下发getGlobalState方法
    }
  }
})

export default apps

数据通信的主要方式就是全局state了

props: {
      routerBase: item.activeRule, // 下发基础路由
      getGlobalState: store.getGlobalState // 下发getGlobalState方法
    }
  • 子应用 sub-vue 代码
import './public-path'
import Vue from 'vue'
import App from './App.vue'
import routes from './router'
import { store as commonStore } from 'common'
import store from './store'
import VueRouter from 'vue-router'

Vue.config.productionTip = false
let instance = null

function render (props = {}) {
  const { container, routerBase } = props
  const router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? routerBase : process.env.BASE_URL,
    mode: 'history',
    routes
  })

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

if (!window.__POWERED_BY_QIANKUN__) {
  // 这里是子应用独立运行的环境,实现子应用的登录逻辑

  // 独立运行时,也注册一个名为global的store module
  commonStore.globalRegister(store)
  // 模拟登录后,存储用户信息到global module
  const userInfo = { name: '我是独立运行时名字叫张三' } // 假设登录后取到的用户信息
  store.commit('global/setGlobalState', { user: userInfo })

  render()
}

export async function bootstrap () {
  console.log('[vue] vue app bootstraped')
}

export async function mount (props) {
  console.log('[vue] props from main framework', props)

  commonStore.globalRegister(store, props)

  render(props)
}

export async function unmount () {
  instance.$destroy()
  instance.$el.innerHTML = ''
  instance = null
}

有一个全局的状态判断是否是微前端中运行

window.__POWERED_BY_QIANKUN__

render 方法中可以获取到全局的数据,然后写入本子应用中

function render (props = {}) {
  const { container, routerBase } = props
  const router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? routerBase : process.env.BASE_URL,
    mode: 'history',
    routes
  })

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

以下代码主要是把全局store注册到子应用关联到子应用的store中,方便调用

if (!window.__POWERED_BY_QIANKUN__) {
  // 这里是子应用独立运行的环境,实现子应用的登录逻辑

  // 独立运行时,也注册一个名为global的store module
  commonStore.globalRegister(store)
  // 模拟登录后,存储用户信息到global module
  const userInfo = { name: '我是独立运行时名字叫张三' } // 假设登录后取到的用户信息
  store.commit('global/setGlobalState', { user: userInfo })

  render()
}

html子应用的应用方式

入口html

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sub-html子应用开发环境</title>
    <style>
      .container{
        padding: 20px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      纯原生HTML子应用, 当前处于 <code id="current-env">独立运行</code> 环境。
    </div>


    <!-- 开发环境的相对路径引用方式 -->
    <script src="./js/main.js"></script>

    <!-- 由于没有webpack自动构建,线上path需要根据部署路径手动更换,本项目把html文件分开管理,线上环境的html放在 public 文件夹 -->
    <!-- <script src="/subapp/sub-html/js/main.js"></script> -->
  </body>
</html>

main.js

const render = (options) => {
  // options是基座下发的参数,可以保存到全局的状态管理或其他地方,用于后面与基座进行通信
  
  // 可通过 options.getGlobalState() 获取基座下发的数据
  // options.setGlobalState({user: {name: ''}}) 改变全局的数据
  // options.onGlobalStateChange 监听全局数据的变化

  
  document.querySelector('#current-env').innerHTML = 'qiankun'
  const globalState = options.getGlobalState()

  // 展示基座下发的状态
  const node = document.createElement('div')
  node.innerHTML = `基座下发的globalState: <code>${JSON.stringify(globalState)}</code>。<a target="_blank" href="${window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__}">打开独立运行环境</a>`

  document.querySelector('.container').appendChild(node)

  return Promise.resolve();
};

(global => {
  global['prehtml'] = {
    bootstrap: () => {
      console.log('purehtml bootstrap');
      return Promise.resolve();
    },
    mount: (options) => {
      console.log('purehtml mount', options);
      return render(options);
    },
    unmount: () => {
      console.log('purehtml unmount');
      return Promise.resolve();
    },
  };
})(window);

window.prehtml.mount 应该是个全局的方法,微前端中会自动被触发,然后就会运行到render函数了

标签:vue,const,render,方式,app,qiankun,import,前端,store
From: https://www.cnblogs.com/jocongmin/p/18244685

相关文章

  • 38.前端基础
    【一】前端和后端介绍1)概念前端:与用户进行交互,让用户输入数据以及展示响应数据的媒介后端:在整个应用背后,不直接与用户打交道,对用户输入的数据进行校验和加密等逻辑的位置2)介绍HTML:网页的骨架,没任何样式CSS:给骨架添加样式JavaScript:控制页面的动态效果3)前端框架BOOTSTRAP......
  • web安全-前端层面
    参考资料引荐https://blog.csdn.net/hack0919/article/details/130929154XSS简介跨站脚本攻击(Cross-SiteScripting,简称XSS)当用户将恶意代码注入网页时,其他用户在浏览网页时就会受到影响攻击主要方向主要用于盗取cookie凭据,钓鱼攻击,流量指向等攻击类型反射型xss......
  • 浪潮服务器做 RAID 的方式
    一次充实的装系统体验,非常感谢耐心的浪潮售后技术,没有他就没有这篇博文由于按Ctrl+H和Ctrl+R进不去RAID,网上也没有合适的教程于是使用工程师最有效的手段打电话摇人首先把产品的序列号准备好浪潮服务器客服:400-860-0011关注微信公众号:浪潮信息专家服务和售后技术商......
  • 记录--前端实现文件预览(word、excel、pdf、ppt、xmind、 音视频、图片、文本) 国际化
    ......
  • 学习分享-Tomcat 的线程池在工作方式上与普通的 Java 线程池的区别
    前言最近在学习过程中遇到在某个场景下:修改某条数据时,给该线程上分布式写锁,然后引入延迟队列处理其他请求;这个方案有一定的缺点,因为在用到消息队列时,不存在占用过多线程从而导致OOM的问题,消费者组只会安排固定的几个线程去拉取消息,如果碰到上面那种拿不到锁的情况,阻塞等待......
  • 【Jenkins+K8s】持续集成与交付 (二十):K8s集群通过Deployment方式部署安装Jenkins
    ......
  • 六月前端及踩坑记录
    六月记录vuehtml根据字符换行vue中ant组件allowClear不生效vuehtml根据字符换行<spanv-html="changeWrap(data)"></span>//分号换行changeWrap(content){content=content.replace(/;/g,";</br>");content=content.......
  • 前端JSZip结合file-saver下载文件打包导出压缩文件
    需求场景:前端拿到下载文件的url,请求并将文件进行分类压缩生成压缩包导出前端导出文件的优点:减轻服务器负担:后端生成压缩文件可能会占用服务器资源和时间。如果压缩的内容很大,可能会导致服务器压力增加,影响其他用户的访问速度。将这些任务转移到前端可以减轻服务器负担,提高......
  • html2canvas前端生成PDF开箱即用
    目录1.下载html2canvas、jspdf2.创建工具类exportPdf文件3.页面中使用需求:将页面展示的所有信息都导出一个pdf文件 实现前端生成PDF只要3步 1.下载html2canvas、[email protected]@2.5.12.创建工具类exportPdfjs文件复制即用//导出页......
  • Selenium的三种等待方式
    目录Selenium的三种等待方式1、强制等待2、隐式等待3、显性等待Selenium的三种等待方式        什么是等待机制?    等待就是当系统运行时,如果页面渲染的速度跟不上程序执行的速度,这时就需要人为的去限制计算机的执行速度。例如在WebUI自动化测试的时......