乾坤实战 采坑之旅(主应用的某个路由页面加载微应用)

1.子应用不需要安装乾坤
2.主应用不需要public-path.js
3.start方法应该写在对应的子路由页面 id也应该对应写在挂在页面

if (!window.qiankunStarted) {
      window.qiankunStarted = true;
      start();
    }
    <div id="appContainer" />

此处最重要的一个关键点事需要再路由页面增加
在这里插入图片描述
必须写在下面 我写在上面无效
4.写与子路由对应的两层路径
在这里插入图片描述
5.子路由的创建必须写在render里 我刚开始为了方便写在路由页面 并且路由必须置空失活的时候否则导致回不去主应用
在这里插入图片描述
在这里插入图片描述
6.图片路径的问题
在这里插入图片描述
增加publiePath 我当时增加了 但是一直不生效 最后发现 代码里写的css url 没有~因为是less不加这个这个loader不编译 这个坑我半天
7.nginx配置问题
在这里插入图片描述
在这里插入图片描述
我原本想直接代理到字应用 但是想到不想影响子应用就自己新增加一个路径 此处有个问题就是我们的js和html没在一个目录 所以 代理到了 html代理不到js两个互斥 后来才发现 index可以指定路径 还有就是alias与root的区别就是一个呆代理路径的路径一个不带

上面理解有误并不是 index后面的找到了html界面 而是 根据匹配原则 它又去 匹配 /后面的 内容 找到了html 目前可知 nginx里 / 是优先级最低的 匹配项

同样的问题另外一种解决方案

    location  /nginxui/ {
        root   /html/;    
        #try_files $uri $uri/ /index.html;
        #index  index.html index.htm;
	   try_files $uri $uri/index.html /500.html; 
#	   index index_prod.html; # 不需要, tryfiles 已经指定 }

    }

http://47.93.212.24:8183/nginxui/assets/index-373f168f.js
root 的目录有/则表示根目录下面 没有则表示ngxin的安装目录,try-files $uri表示我此次请求的路径 加上我的root路径
css/js 可以理解为/html//nginxui/assets/index-373f168f.js 而index.html 因为是请求路径只有nginxui所以完整路径就是
/html/nginxui/index.html

处理静态页面集成qiankun
在这里插入图片描述

vue3 vite接入
1.增加插件
在这里插入图片描述
2.public-path
在这里插入图片描述
3.main.ts

import {createApp} from 'vue'
import {createPinia} from 'pinia'
import gettext from './gettext'
import './public-path'
import App from './App.vue'
import {router} from './routes'
import routerEach from './routes/routerEach';
//import 'ant-design-vue/dist/antd.less'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import {useSettingsStore} from '@/pinia'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
debugger
let app:any = null
let _router = null
// 独立运行时
if(!qiankunWindow.__POWERED_BY_QIANKUN__) {

    const pinia = createPinia()

    app = createApp(App)

    pinia.use(piniaPluginPersistedstate)
    app.use(pinia)
    app.use(gettext)
    // after pinia created
    const settings = useSettingsStore()
    gettext.current = settings.language || 'en'
    _router = router('');
    routerEach(_router);
    app.use(_router).mount('#app')

} else {
  // 作为微应用运行
  renderWithQiankun({ // 调用renderWithQiankun
    mount(props) {
      app = createApp(App)
      const pinia = createPinia()
      pinia.use(piniaPluginPersistedstate)
      app.use(pinia)
      app.use(gettext)
      app.config.globalProperties.__POWERED_BY_QIANKUN__ = qiankunWindow.__POWERED_BY_QIANKUN__;
      // after pinia created
      const settings = useSettingsStore()
      gettext.current = settings.language || 'en'
      _router = router(props._parent_base);
      routerEach(_router);
      app.use(_router).mount(props.container ? props.container.querySelector('#app') : '#app')
    },
    bootstrap() {
      console.log('-- bootstrap --')
    },
    update() {
      console.log('-- update --')
    },
    unmount() {
      console.log('-- unmount --', app)
      app?.unmount()
    }
  })
}



// const pinia = createPinia()

// const app = createApp(App)

// pinia.use(piniaPluginPersistedstate)
// app.use(pinia)
// app.use(gettext)
// // after pinia created
// const settings = useSettingsStore()
// gettext.current = settings.language || 'en'

// app.use(router).mount('#app')

export default app

4.router.js

import {createRouter, createWebHashHistory, createWebHistory} from 'vue-router'
import {qiankunWindow} from 'vite-plugin-qiankun/dist/helper';
import gettext from '../gettext'
// import {useUserStore} from '@/pinia'

import {
    CloudOutlined,
    CodeOutlined,
    FileOutlined,
    HomeOutlined,
    InfoCircleOutlined,
    UserOutlined,
    FileTextOutlined,
    SettingOutlined,
    SafetyCertificateOutlined
} from '@ant-design/icons-vue'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

const {$gettext} = gettext

export const routes = [
    {
        path: '/',
        name: () => $gettext('Home'),
        component: () => import('@/layouts/BaseLayout.vue'),
        redirect: '/dashboard',
        children: [
            {
                path: 'dashboard',
                component: () => import('@/views/dashboard/DashBoard.vue'),
                name: () => $gettext('Dashboard'),
                meta: {
                    // hiddenHeaderContent: true,
                    icon: HomeOutlined
                }
            },
            {
                path: 'user',
                name: () => $gettext('Manage Users'),
                component: () => import('@/views/user/User.vue'),
                meta: {
                    icon: UserOutlined
                }
            },
            {
                path: 'domain',
                name: () => $gettext('Manage Sites'),
                component: () => import('@/layouts/BaseRouterView.vue'),
                meta: {
                    icon: CloudOutlined
                },
                redirect: '/domain/list',
                children: [{
                    path: 'list',
                    name: () => $gettext('Sites List'),
                    component: () => import('@/views/domain/DomainList.vue')
                }, {
                    path: 'add',
                    name: () => $gettext('Add Site'),
                    component: () => import('@/views/domain/DomainAdd.vue')
                }, {
                    path: ':name',
                    name: () => $gettext('Edit Site'),
                    component: () => import('@/views/domain/DomainEdit.vue'),
                    meta: {
                        hiddenInSidebar: true
                    }
                }]
            },
            {
                path: 'config',
                name: () => $gettext('Manage Configs'),
                component: () => import('@/views/config/Config.vue'),
                meta: {
                    icon: FileOutlined,
                    hideChildren: true
                }
            },
            {
                path: 'config/:name+/edit',
                name: () => $gettext('Edit Configuration'),
                component: () => import('@/views/config/ConfigEdit.vue'),
                meta: {
                    hiddenInSidebar: true
                }
            }
            // {
            //     path: 'cert',
            //     name: () => $gettext('Certification'),
            //     component: () => import('@/views/cert/Cert.vue'),
            //     meta: {
            //         icon: SafetyCertificateOutlined
            //     }
            // },
            // {
            //     path: 'terminal',
            //     name: () => $gettext('Terminal'),
            //     component: () => import('@/views/pty/Terminal.vue'),
            //     meta: {
            //         icon: CodeOutlined
            //     }
            // },
            // {
            //     path: 'nginx_log',
            //     name: () => $gettext('Nginx Log'),
            //     meta: {
            //         icon: FileTextOutlined
            //     },
            //     children: [{
            //         path: 'access',
            //         name: () => $gettext('Access Logs'),
            //         component: () => import('@/views/nginx_log/NginxLog.vue')
            //     }, {
            //         path: 'error',
            //         name: () => $gettext('Error Logs'),
            //         component: () => import('@/views/nginx_log/NginxLog.vue')
            //     }, {
            //         path: 'site',
            //         name: () => $gettext('Site Logs'),
            //         component: () => import('@/views/nginx_log/NginxLog.vue'),
            //         meta: {
            //             hiddenInSidebar: true
            //         }
            //     }]
            // },
            // {
            //     path: 'preference',
            //     name: () => $gettext('Preference'),
            //     component: () => import('@/views/preference/Preference.vue'),
            //     meta: {
            //         icon: SettingOutlined
            //     }
            // },
            // {
            //     path: 'system',
            //     name: () => $gettext('System'),
            //     redirect: 'system/about',
            //     meta: {
            //         icon: InfoCircleOutlined
            //     },
            //     children: [{
            //         path: 'about',
            //         name: () => $gettext('About'),
            //         component: () => import('@/views/system/About.vue')
            //     }, {
            //         path: 'upgrade',
            //         name: () => $gettext('Upgrade'),
            //         component: () => import('@/views/system/Upgrade.vue')
            //     }]
            // }
        ]
    },
    {
        path: '/install',
        name: () => $gettext('Install'),
        component: () => import('@/views/other/Install.vue'),
        meta: {noAuth: true}
    },
    {
        path: '/login',
        name: () => $gettext('Login'),
        component: () => import('@/views/other/Login.vue'),
        meta: {noAuth: true}
    },
    {
        path: '/:pathMatch(.*)*',
        name: () => $gettext('Not Found'),
        component: () => import('@/views/other/Error.vue'),
        meta: {noAuth: true, status_code: 404, error: () => $gettext('Not Found')}
    }
]
const router = (parentBase:string) => {
    /**
     * 区别作为微应用运行和独立运行时的路由base
     * 1. 当作为微应用运行时:路由前缀为 ${parentBase}${packagejson.name}`
     *      - parentBase是从主应用中传过来的参数
     *      - packagejson.name是在package.json文件中定义的固定变量,是为了方便使用和便于区分,这个应该大家都能够理解
     * 2. 独立运行时:路由前缀为/app2
     */
    const base = qiankunWindow.__POWERED_BY_QIANKUN__ ? `${parentBase ?? '/'}${__package_name__}` : '';
    return createRouter({
      history: createWebHistory(base),
      // @ts-ignore
      routes: routes,
      scrollBehavior(to, from, savedPosition) {
        if (savedPosition) {
          return savedPosition;
        } else {
          return { top: 0 };
        }
      },
    });
  };

  export { router };
// const router = createRouter({
//     history: createWebHashHistory(),
//     // @ts-ignore
//     routes: routes
// })

// NProgress.configure({showSpinner: false})

// router.beforeEach((to, from, next) => {
//     // @ts-ignore
//     document.title = to.name?.() + ' | Nginx UI'

//     NProgress.start()

//     const user = useUserStore()
//     const {is_login} = user

//     if (to.meta.noAuth || is_login) {
//         next()
//     } else {
//         next({path: '/login', query: {next: to.fullPath}})
//     }

// })

// router.afterEach(() => {
//     NProgress.done()
// })

export default router

5.routeEach.js


import NProgress from 'nprogress';
// import { router } from '.';
import {
    Router
  } from "vue-router";
import 'nprogress/nprogress.css';
import {useUserStore} from '@/pinia'


NProgress.configure({ showSpinner: false });

const routerEach = (router:Router) => {
    NProgress.configure({showSpinner: false})

    router.beforeEach((to, from, next) => {
        // @ts-ignore
        document.title = to.name?.() + ' | Nginx UI'

        NProgress.start()

        const user = useUserStore()
        const {is_login} = user

        if (to.meta.noAuth || is_login) {
            next()
        } else {
            next({path: '/login', query: {next: to.fullPath}})
        }

    })

    router.afterEach(() => {
        NProgress.done()
    })
};
export default routerEach;

在这里插入图片描述
在这里插入图片描述
关于vue3 使用vue-router4得bug 路由总是会被重新执行两次
解决方案 在这里插入图片描述
关于这两个得区别做如下赘述
1.在这里插入图片描述
在这里插入图片描述
关于webpack5升级后不支持
一开始我在github找,试了很久没试到 然后看报错的地方的源码应该是暴露周期没暴露出去,然后修改output文件各种修改,最后理解了library的作用,library是暴露entry里导出的文件,然后查到entry
在这里插入图片描述

保留一个entry好了

遇到问题应该一步一步 得理解这个配置的作用是什么 找到源头 不应看网上的 一个一个试

elementu-plus和element-ui样式冲突解决方案

1、使用change-prefix-loader替换js中的class前缀
2、使用postcss-change-css-prefix替换css样式前缀

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值