MicroApp樣例搭建【Vue】

樣例代碼可以點擊這里下載臼寄,搭建流程如下

項目創(chuàng)建

項目由 vue 的官方腳手架創(chuàng)建登钥,基項目 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: {}  // 需要傳入子模塊的數(shù)據
            , baseroute: '' // 子模塊路由地址
            }
    }
    }
    , watch: {
        $route (val){
            // 監(jiān)聽路由變化,改變子模塊渲染
            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 } // 根據路由和子項目跳轉方式斗这,傳入對應參數(shù)
                    , 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

/**
 * 掛載函數(shù)
 */
function mount () {
    app = new Vue({
        el: '#app'
        , router
        , render: function (h) { return h(App) }
    })
}

/**
 * 卸載函數(shù)
 */
function unmount () {
    app.$destroy()
    app.$el.innerHTML = ''
    app = null
}

// 微前端環(huán)境下啤斗,注冊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) {
            // 向基項目發(fā)送數(shù)據
            window.microApp.dispatch({ route: { name } })
        }
    }
    , created () {
        // 綁定數(shù)據【data屬性】監(jiān)聽事件
        window.microApp && window.microApp.addDataListener(this.dataListener)
    }
    , destroyed () {
        // 移除數(shù)據【data屬性】監(jiān)聽事件
        window.microApp && window.microApp.removeDataListener(this.dataListener)
    }
}
</script>

修改路由文件 router/index.js

...

const routes = [
    {
        path: window.__MICRO_APP_BASE_ROUTE__ || '/' // 根據項目運行的不同環(huán)境表箭,設置路徑的前綴
        , 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 訪問單個子項目

GIF 2022-2-11 10-53-03

一些問題處理

  • 公共模塊代碼
    可以將公共代碼單獨創(chuàng)建一個倉庫极舔,在各個項目中以子模塊的形式引入到項目中

  • 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】

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末盯桦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子渤刃,更是在濱河造成了極大的恐慌拥峦,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卖子,死亡現(xiàn)場離奇詭異事镣,居然都是意外死亡,警方通過查閱死者的電腦和手機揪胃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門璃哟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喊递,你說我怎么就攤上這事随闪。” “怎么了骚勘?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵铐伴,是天一觀的道長。 經常有香客問我俏讹,道長当宴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任泽疆,我火速辦了婚禮户矢,結果婚禮上,老公的妹妹穿的比我還像新娘殉疼。我一直安慰自己梯浪,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布瓢娜。 她就那樣靜靜地躺著挂洛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪眠砾。 梳的紋絲不亂的頭發(fā)上虏劲,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音,去河邊找鬼柒巫。 笑死励堡,一個胖子當著我的面吹牛,可吹牛的內容都是我干的吻育。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼淤井,長吁一口氣:“原來是場噩夢啊……” “哼布疼!你這毒婦竟也來了?” 一聲冷哼從身側響起币狠,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤游两,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后漩绵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贱案,經...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年止吐,在試婚紗的時候發(fā)現(xiàn)自己被綠了宝踪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡碍扔,死狀恐怖瘩燥,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情不同,我是刑警寧澤厉膀,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站二拐,受9級特大地震影響服鹅,放射性物質發(fā)生泄漏。R本人自食惡果不足惜百新,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一企软、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧饭望,春花似錦澜倦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至巷挥,卻和暖如春桩卵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工雏节, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胜嗓,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓钩乍,卻偏偏與公主長得像辞州,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子寥粹,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容