MicroApp樣例搭建【Vue】
阿新 • • 發佈:2022-03-02
樣例程式碼可以點選這裡下載,搭建流程如下
專案建立
專案由 vue 的官方腳手架建立,基專案 base 和子專案 app_first、app_second
vue create base
vue create app_first
vue create app_second
基專案修改
新增本地執行配置檔案 vue.config.js
module.exports = {
devServer: {
host: 'localhost'
, port: 3000
}
}
安裝 micro-app 外掛
npm install @micro-zoe/micro-app --save
新增 micro/index.js
檔案
import microApp from '@micro-zoe/micro-app'
import * as config from './config'
// 啟用 micro
microApp.start({
preFetchApps: config.MICRO_APPS //載入子專案
, globalAssets: config.GLOBAL_ASSETS // 載入全域性資源
})
新增 micro/config.js
檔案
// 子應用字首 export const CHILD_PREFIX = 'app' // 子應用地址 export const MICRO_APPS = [ { name: 'first-child', url: `http://localhost:3001/` } , { name: 'second-child', url: `http://localhost:3002/` } ] // 全域性資源 export const GLOBAL_ASSETS = { js: [] , css: [] }
修改入口檔案 main.js
,引入 micro-app 配置
import './micro'
...
修改 App.vue
檔案
<template> <div> <!--路由連結--> ... </div> <div> <micro-app v-if="isChild" v-bind="micro" destory @datachange='handleDataChange'></micro-app> <router-view v-else></router-view> </div> </template> <script> import { MICRO_APPS, CHILD_PREFIX } from './micro/config.js' export default { ... , data(){ return { ... , isChild: false // 是否是子模組 , micro: { url: '' // 子應用地址,不包含路由地址 , key: '' // Vue 標籤的 key 值,用於不同子模組間的切換時,元件重新渲染 , name: '' // 子模組名稱,值唯一 , data: {} // 需要傳入子模組的資料 , baseroute: '' // 子模組路由地址 } } } , watch: { $route (val){ // 監聽路由變化,改變子模組渲染 this.changeChild(val) } } , created () { this.changeChild(this.$route) } , methods: { ... , getAppUrl (name) { // 獲取子模組 url 和 name return MICRO_APPS.find(app => app.name === name) || {} } , changeChild (route) { // 修改子檢視顯示 let path = route.path.toLowerCase() , paths = path.split('/') // 判斷是否為子模組,子模組有固定的字首 this.isChild = paths.length > 2 && paths[1] === CHILD_PREFIX if (this.isChild) { let app = this.getAppUrl(paths[2]) this.micro = { ...app , data: { name: route.name } // 根據路由和子專案跳轉方式,傳入對應引數 , key: `${app.name}` , baseroute: `/${CHILD_PREFIX}/${paths[2]}` } } } , handleDataChange (event) { // 獲取子路由傳遞的資訊 let data = event.detail.data if(data.route) this.$router.push({ name: data.route.name }) } } } </script>
修改路由檔案 router/index.js
...
import { CHILD_PREFIX } from '@/micro/config.js'
const routes = [
...
, { // app_first 專案路由
path: `/${CHILD_PREFIX}/first-child`
, name: 'FirstChild'
, children: [
{
path: 'home'
, name: 'FirstHome'
}
, {
path: 'about'
, name: 'FirstAbout'
}
]
}
, { // app_second 專案路由
path: `/${CHILD_PREFIX}/second-child`
, name: 'SecondChild'
, children: [
{
path: 'home'
, name: 'SecondHome'
}
, {
path: 'about'
, name: 'SecondAbout'
}
]
}
]
...
子專案修改
新增本地執行配置檔案 vue.config.js
,設定允許跨域訪問
module.exports = {
devServer: {
host: 'localhost'
, port: 3001
, headers: { // 設定本地執行的跨域許可權
'Access-Control-Allow-Origin': '*',
}
}
}
新增 micro/index.js
檔案
// 設定 webpack 的公共路徑
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__ || '/'
入口檔案修改 mian.js
import './micro'
...
let app
/**
* 掛載函式
*/
function mount () {
app = new Vue({
el: '#app'
, router
, render: function (h) { return h(App) }
})
}
/**
* 解除安裝函式
*/
function unmount () {
app.$destroy()
app.$el.innerHTML = ''
app = null
}
// 微前端環境下,註冊mount和unmount方法
if (window.__MICRO_APP_ENVIRONMENT__)
window[`micro-app-${window.__MICRO_APP_NAME__}`] = { mount, unmount }
else
mount()
修改 App.vue
檔案
<template>
<div id="app">
<div id="nav">
<router-link :to="`${prefix}/home`">Home</router-link> |
<router-link :to="`${prefix}/about`">About</router-link> |
<button @click="goto('SecondHome')">SecondHome</button> |
<button @click="goto('SecondAbout')">SecondAbout</button>
</div>
<router-view />
</div>
</template>
<script>
export default {
...
, methods: {
...
, dataListener (data) {
// 不判斷時會報一個“冗餘導航【NavigationDuplicated】”的異常
if (data.name !== this.$route.name)
this.$router.push({ name: data.name })
}
, goto (name) {
// 向基專案傳送資料
window.microApp.dispatch({ route: { name } })
}
}
, created () {
// 繫結資料【data屬性】監聽事件
window.microApp && window.microApp.addDataListener(this.dataListener)
}
, destroyed () {
// 移除資料【data屬性】監聽事件
window.microApp && window.microApp.removeDataListener(this.dataListener)
}
}
</script>
修改路由檔案 router/index.js
...
const routes = [
{
path: window.__MICRO_APP_BASE_ROUTE__ || '/' // 根據專案執行的不同環境,設定路徑的字首
, name: 'Home'
, redirect: { name: 'FirstHome' }
, component: () => import('../views/Empty.vue') // Empty.vue 是一個只包含 router-view的頁面,用於渲染 children
, children: [
...
]
}
]
...
專案啟動
分別進入專案資料夾,在 CMD 下執行 npm run serve
,啟動專案,訪問 localhost:3000
檢視完整的專案,也可以開啟 localhost:3001
或者 localhost:3002
訪問單個子專案
一些問題處理
-
公共模組程式碼
可以將公共程式碼單獨建立一個倉庫,在各個專案中以子模組的形式引入到專案中
-
Nginx 部署
微前端在部署到多個地址時,可以通過 nginx 的反向代理,把子專案的地址代理到主專案地址下,這樣可以是主專案和子專案使用相同的 storage 儲存
server {
listen 3000;
server_name localhost;
location / {
root D:/base/dist/;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# 代理子專案
location /first_child/ {
proxy_pass http://localhost:3001/;
}
}
# 子專案訪問埠
server {
listen 3001;
server_name localhost;
# 設定跨域訪問許可權
add_header Access-Control-Allow-Origin *;
location / {
root D:/first_child/dist/;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
原文連結:MicroApp樣例搭建【Vue】