How to Seamlessly Integrate Legacy Backends with Vue and Qiankun Micro‑Frontend

This article presents a comprehensive case study on unifying multiple legacy backend systems by building a modern Vue‑based front‑end, combining native iframe integration with the qiankun micro‑frontend framework to achieve a single entry point, smooth migration, reduced costs, and an evolvable architecture for enterprise applications.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
How to Seamlessly Integrate Legacy Backends with Vue and Qiankun Micro‑Frontend

Project Background and Core Goals

During enterprise digital transformation, many organizations still operate several independent legacy backend systems built with Spring Boot MVC (non‑SPA). These systems suffer from five major pain points: fragmented user experience, high maintenance cost, resource duplication, difficult expansion, and low switching performance. The project targets three core objectives: unified experience (single sign‑on across all systems), controllable cost (minimal refactoring of old systems), and evolvable architecture (prepare for full micro‑frontend adoption).

Technical Stack Selection

Front‑end framework: Vue – lightweight, mature ecosystem, familiar to the team.

Routing: Vue Router + native Location API – Vue Router handles main‑app routes, Location API resolves legacy URL redirection race conditions.

State management: Vuex – shares state across components, supports complex permission and navigation state.

UI library: Element UI plus a custom component library – reduces development cost while ensuring UI consistency.

Legacy integration: iframe – zero‑modification embedding of old systems.

New system expansion: qiankun micro‑frontend – enables multiple technology‑stack sub‑apps and future independent deployment.

HTTP client: Axios – unified request handling, interceptors for permission checks and error handling.

Performance monitoring: web‑vitals – tracks CLS, LCP, FID and other core metrics.

Overall Architecture: "Unified Entry + Layered Integration"

The solution adopts a layered architecture consisting of:

Unified entry layer: a Vue main application serving as the sole access point, providing navigation, login, and permission control.

System integration layer:

Legacy systems are embedded via iframe without code changes.

New features are developed directly in the Vue main app, reusing base capabilities.

Future systems are added as qiankun micro‑apps (React, Vue, etc.).

Base capability layer: encapsulated services for permission verification, API requests, performance logging, and cross‑origin handling, shared by all integrated systems.

Design Principles

Synchronous first: critical flows such as navigation and permission checks run synchronously to avoid race conditions.

Security and reliability: strict permission validation and error handling prevent unauthorized access.

High cohesion, low coupling: modular separation of navigation, iframe integration, monitoring, etc.

Observability: built‑in performance logs and error monitoring enable rapid issue localization.

Core Functional Modules

Unified Navigation & Layout

The UI follows a classic back‑office layout: a top navigation bar combined with either a full‑screen home view or a left‑side menu + content area for business pages, with menu items rendered dynamically based on user permissions.

Iframe Integration Module

Permission pre‑check: calls a permission API before loading the target page; redirects to a warning page if unauthorized.

Dynamic URL construction: builds the iframe src from system code and resource ID, handling same‑origin and cross‑origin cases (cross‑origin opens a new tab).

Back‑button handling: maintains a custom historyStack to preserve iframe navigation history.

Cross‑origin strategy: uses a unified domain for controllable pages; non‑controllable pages open in a new tab.

Performance logging: records full‑link timings (DNS, TCP, DOM rendering) and logs them for optimization.

// iframe load event
handleIframeLoad() {
  try {
    if (this.$refs.contentIframe && this.$refs.contentIframe.contentWindow.location.href) {
      const iframeWindow = this.$refs.contentIframe.contentWindow;
      const iframePerf = iframeWindow.performance;
      const timing = iframePerf.getEntriesByType('navigation')[0];
      const perf = window.performance;
      const nowTime = perf.now();
      console.log('iframe start time:', nowTime - timing.duration);
      const paintTime = iframePerf.getEntriesByType('paint');
      let whiteTime = "unknown";
      if (paintTime && paintTime.length) {
        whiteTime = paintTime[0].startTime + "ms";
      }
      console.log(`iframe total load: ${timing.loadEventEnd - timing.startTime}ms
white time: ${whiteTime}
DOM interactive: ${timing.domInteractive - timing.startTime}ms
render time: ${timing.loadEventEnd - timing.responseEnd}ms`);
    }
  } catch (error) {
    console.log(error);
  }
}

Micro‑frontend Preparation with qiankun

To overcome iframe limitations (debug difficulty, duplicated dependencies, fragmented layout), the project registers sub‑apps via registerMicroApps and starts qiankun. Example registration:

registerMicroApps({
  name: 'hot-monitor',
  entry: 'http://abc.com/admin-hot-minotor/index.html#',
  container: '#micro-app-container',
  activeRule: location => location.hash.startsWith('#/qiankun/hot-monitor'),
  props: {
    routerBase: '/qiankun/hot-monitor',
    pathObj: { hotRedPath: 'hotred' }
  }
});
console.log('registerApps');
start();

The sub‑app itself does not import qiankun; it only implements lifecycle hooks ( bootstrap, mount, unmount) and adapts the environment based on the props it receives.

// sub‑app main.js
let vueInstance = null;
function render(props = {}) {
  const { container, routerBase } = props;
  if (routerBase) {
    window.__SUBAPP_BASE_PATH__ = routerBase;
  }
  const router = createRouter();
  vueInstance = new Vue({ router, i18n, render: h => h(App) })
    .$mount(container ? container.querySelector('#app') : '#app');
}
export async function mount(props) { render(props); }
export async function unmount() { vueInstance.$destroy(); vueInstance = null; }

Router Design and Legacy URL Redirection

The router distinguishes three categories: main‑app routes, iframe routes, and qiankun micro‑app routes, preventing conflicts. Legacy URLs are redirected using window.location.replace to avoid asynchronous race conditions.

export default new Router({
  base: "/xxx/",
  routes: [
    { path: "/", redirect: "/index" },
    { path: "/index", component: () => import("../common/Home.vue") },
    // iframe route
    { path: "/main", component: () => import("../common/OutFrame.vue"),
      children: [{ path: "/frame/:params", component: () => import("../pages/frame/index.vue") }] },
    // qiankun micro‑app route
    { path: "/qiankun/*", component: () => import("../common/OutFrame.vue") }
  ]
});

Fine‑grained Permission Control

To close the security gap of legacy systems, a synchronous permission check is performed before loading any page. If the user lacks permission, they are redirected to a warning page.

async handleUrl(systemCode, name, id) {
  if (!id) { this.$message.error("Resource ID cannot be empty"); return; }
  const hasPermission = await this.userValidateResourcesId(systemCode, id, name);
  if (!hasPermission) {
    this.$router.push(`/jumpView?systemCode=${systemCode}&showInfo=${encodeURIComponent(name)}`);
    return;
  }
  this.buildIframeUrl(systemCode, id);
}

Full‑Link Performance Monitoring

Web‑vitals is integrated in the main app to capture CLS, LCP, and FID. Iframe performance (total load time, white‑screen time, DOM interactive) is logged in the iframe load handler shown earlier. This data drives performance bottleneck identification and optimization.

import { onCLS, onLCP, onFID } from 'web-vitals';
onCLS(record => console.log('Main app CLS:', record.value));
onLCP(record => console.log('Main app LCP:', record.value));
// iframe metrics are logged inside handleIframeLoad()

System Benefits

User experience: a single entry point eliminates frequent system switching.

Development efficiency: new features are built on the Vue base; shared capabilities (auth, monitoring) achieve 100% reuse.

Security: page‑level permission checks reach 100% coverage, preventing unauthorized access.

Business extensibility: new modules can be added as qiankun micro‑apps or Vue components without deploying separate services.

Future Roadmap

Fully migrate iframe‑based legacy systems to qiankun micro‑apps for independent development, deployment, and upgrades.

Establish a unified component library covering forms, tables, dialogs, etc., to further improve UI consistency and developer productivity.

Upgrade the permission model to RBAC with data‑level granularity and enhance observability with automatic front‑end error alerts and remote log correlation.

Project Value and Industry Reference

The hybrid approach of "iframe zero‑modification integration + qiankun forward‑looking layout" successfully resolves the fragmentation of multiple legacy back‑ends, delivering unified experience, cost reduction, and an evolvable architecture. It offers a practical reference for enterprises seeking incremental digital transformation without the risk of a full rewrite.

img
img
img
img
micro-frontendPerformance MonitoringVueFrontend ArchitectureqiankunPermission ControlIframe Integration
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.