micro-app在vue-element-admin中一些使用研究

news2024/11/25 7:10:42

1、简述

本文承接上一篇micro-app在vue-element-admi中的搭建,对micro-app在vue-element-admin中的一些平时开发中常用的功能做了一些研究。本文代码

2、路由

关于路由,这边从两方面进行研究,一方面是对菜单的配置,另一方面是页面之间的跳转。下面分别介绍一下:

2-1、路由菜单配置

关于路由的配置,之前搭建vue-element-admin项目时,将子应用嵌入到基座时已经对路由的配置进行了搭建,子应用1为例具体如下:
在这里插入图片描述
如果是配置菜单的话,以上配置就可以了。配置代码如下:
micro-app-element\vue-element-base\src\router\modules\first-child.js

// 子应用1路由菜单
import Layout from '@/layout'
import { CHILD_PREFIX } from '@/micro/config'


const appFirstRouter = {
  path: `/${CHILD_PREFIX}/first-child`,
  component: Layout,
  redirect: `/${CHILD_PREFIX}/first-child`,
  name: 'FirstChild',
  meta: {
    title: '子应用模块',
    icon: 'nested'
  },
  children: [
    {
      path: 'menu1',
      name: 'Menu1',
      meta: { title: '子应用菜单1' }
    },
    {
      path: 'menu2',
      name: 'Menu2',
      meta: { title: '子应用菜单2' }
    }
  ]
}
export default appFirstRouter

micro-app-element\vue-element-first\src\router\modules\nested.js

/** When your routing table is too long, you can split it into small modules **/


import Layout from '@/layout'


console.log(' window.__MICRO_APP_BASE_ROUTE__', window.__MICRO_APP_BASE_ROUTE__)
const nestedRouter = {
  path: window.__MICRO_APP_BASE_ROUTE__ || '/nested',
  component: Layout,
  // redirect: '/nested/menu1/menu1-1',
  name: 'Nested',
  meta: {
    title: '子应用',
    icon: 'nested'
  },
  children: [
    {
      path: 'menu1',
      component: () => import('@/views/nested/menu1/index'), // Parent router-view
      name: 'Menu1',
      meta: { title: '子应用菜单11' }
    },
    {
      path: 'menu2',
      name: 'Menu2',
      component: () => import('@/views/nested/menu2/index'),
      meta: { title: '子应用菜单22' }
    }
  ]
}


export default nestedRouter

2-2、页面之间跳转

我们代码开发中,有很多场景都是一个菜单中有一个标签或按钮,点击可以直接跳转到另一个菜单。因为之前都是在同一个应用里,跳转肯定是没问题的。但是使用微前端后,可能会从基座菜单跳转到子应用菜单,也可能会从子应用菜单跳转到基座菜单,还有可能是子应用直接互相跳转,下面对这些跳转都做了尝试

2-2-1、子应用之间的互相跳转

举例:从子应用1的菜单1跳转到子应用2的菜单1,实现效果如下图所示:
子应用之间跳转
对于应用之间的跳转,有如下两个地方要修改:
(1)基座:在一开始搭建路由的时候,在基座中调用了子应用,如果要实现应用之间互相跳转,基座部分需要获取子路由传递的信息,具体实现如下:
在这里插入图片描述
micro-app-element\vue-element-base\src\layout\components\AppMain.vue

<micro-app
  v-if="isChild"
  v-bind="micro"
  destory
  @datachange="handleDataChange"
/>
/**
* 获取子路由传递的信息
* */
handleDataChange(event) {
  const data = event.detail.data
  if (data.route) this.$router.push({ name: data.route.name })
},

(2)子应用点击部分的设置
在这里插入图片描述
micro-app-element\vue-element-first\src\views\nested\menu1\index.vue

<div style="height: 50px;">
  <el-button type="primary" @click="jumpApp2('DynamicTable')">我想从子应用1菜单1跳转到子应用2菜单1</el-button>
</div>
methods: {
  /**
   * 点击跳转到页面
   * @param name
   */
  jumpApp2(name) {
    // 向基项目发送数据
    window.microApp && window.microApp.dispatch({ route: { name }})
  }
}

2-2-2、子应用跳转到基座

举例:从子应用1的菜单2跳转到基座图标页,实现效果如下图所示:
在这里插入图片描述
有了2-2-1的基础后,接下来的操作就方便很多,不需要再去修改基座了,之间在子应用里面实现跳转即可
在这里插入图片描述
micro-app-element\vue-element-first\src\views\nested\menu2\index.vue

<template>
  <div style="padding:30px;">
    我是子应用菜单2
    <div style="height: 50px;">
      <el-button type="primary" @click="jumpAppBase('Icons')">我想从子应用1菜单2跳转到基座图标页</el-button>
    </div>
    <el-alert :closable="false" title="menu 2" />
  </div>
</template>
<script>
export default {
  name: 'Menu2',
  methods: {
    /**
       * 点击跳转到页面
       * @param name
       */
    jumpAppBase(name) {
      // 向基项目发送数据
      window.microApp && window.microApp.dispatch({ route: { name }})
    }
  }
}
</script>

2-2-3、基座跳转到子应用

举例:从基座引导页跳转到子应用1菜单2,实现效果如下图所示:
在这里插入图片描述
基座跳转到子应用与上面2-2-1和2-2-2方法不同,需要注意
首先从官网中可以看出,跳转的时候路由方式不一样,url也有所不用,如果是哈希需要加“#”,如果不知道自己的路由方式,可以在router/index.js下去找mode,默认是哈希。我这边就是哈希

在这里插入图片描述
接下来按照官网介绍进行配置即可
在这里插入图片描述
在这里插入图片描述
micro-app-element\vue-element-base\src\views\guide\index.vue

<template>
  <div class="app-container">
    <aside>
      {{ $t('guide.description') }}
      <a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.</a>
    </aside>
    <el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">
      {{ $t('guide.button') }}
    </el-button>
    <div style="height: 50px;">
      <el-button type="primary" @click="jumpApp1()">我想从基座跳转到子应用1菜单2</el-button>
    </div>
  </div>
</template>


<script>
import Driver from 'driver.js' // import driver.js
import 'driver.js/dist/driver.min.css' // import driver.js css
import steps from './steps'
import { CHILD_PREFIX } from '../../micro/config'


export default {
  name: 'Guide',
  data() {
    return {
      driver: null
    }
  },
  mounted() {
    this.driver = new Driver()
  },
  methods: {
    guide() {
      this.driver.defineSteps(steps)
      this.driver.start()
    },
    /**
     * 基座跳转到子应用
     */
    jumpApp1() {
      window.history.pushState(null, '', `/#/${CHILD_PREFIX}/first-child/menu2`)
      // 主动触发一次popstate事件
      window.dispatchEvent(new PopStateEvent('popstate', { state: null }))
    }
  }
}
</script>

3、数据通信

关于这个数据通信,官网里讲了如下四点,感觉看着蛮不舒服的。其实按我们正常的思维,传值与取值是一起使用的
(1)子应用获取来自基座应用的数据
(2)子应用向基座应用发送数据
(3)基座应用向子应用发送数据
(4)基座应用获取来自子应用的数据
所以将以上(1)(3)和(2)(4)合并起来作为两点进行研究

3-1、基座发送数据,子应用获取数据

基座向子应用传值有两种方式:

3-1-1、data属性发送数据

在这里插入图片描述
基座发送数据:

<micro-app
  v-if="isChild"
  v-bind="micro"
  destory
  :data="dataForChild"
  @datachange="handleDataChange"
/>

dataForChild: { type: 'data属性发送数据给子应用' },

子应用获取数据:

created() {
  const data = window.microApp.getData() // 返回基座下发的data数据
  console.log('子应用获取父应用数据', data)
},

3-1-2、基座手动发送数据

在这里插入图片描述
基座

import microApp from '@micro-zoe/micro-app'
microApp.setData('first-child', { type: '基座手动发送新的数据' })

子应用

<template>
  <div style="padding:30px;">
    我是子应用菜单2
    <div style="height: 50px;">
      <el-button type="primary" @click="jumpAppBase('Icons')">我想从子应用1菜单2跳转到基座图标页</el-button>
    </div>
    <el-alert :closable="false" title="menu 2" />
  </div>
</template>
<script>
export default {
  name: 'Menu2',
  created() {
    // const data = window.microApp.getData() // 返回基座下发的data数据
    // console.log('子应用获取父应用数据', data)
    /** 绑定数据【data属性】监听事件 */
    window.microApp && window.microApp.addDataListener(this.dataListener, true)
  },
  destroyed() {
    /** 移除数据【data属性】监听事件 */
    window.microApp && window.microApp.removeDataListener(this.dataListener)
  },
  methods: {
    dataListener(data) {
      console.log('来自基座应用的数据', data)
    },
    /**
       * 点击跳转到页面
       * @param name
       */
    jumpAppBase(name) {
      // 向基项目发送数据
      window.microApp && window.microApp.dispatch({ route: { name }})
    }
  }
}
</script>

3-2、子应用发送数据,基座获取数据

关于子应用发送数据,基座获取数据的,我们在前面写跳转的时候就遇到了
在这里插入图片描述
子应用

// 向基项目发送数据
  window.microApp && window.microApp.dispatch({ route: { name }})

基座

<micro-app
  v-if="isChild"
  v-bind="micro"
  destory
  :data="dataForChild"
  @datachange="handleDataChange"
/>
/**
* 获取子路由传递的信息
* */
handleDataChange(event) {
  const data = event.detail.data
  if (data.route) this.$router.push({ name: data.route.name })
},

4、隔离

4-1、样式隔离

micro-app有默认的样式隔离,我简单试了一下
(1)修改子应用的颜色,子应用发生变化,但是不会影响到基座的样式
在这里插入图片描述
(2)修改基座颜色,基座会发生变化,不会影响到子应用
在这里插入图片描述

4-2、元素隔离

micro-app也有默认的元素隔离,元素不会逃离元素边界,子应用只能对自身的元素进行增、删、改、查的操作。

5、资源共享

官网描述:当多个子应用拥有相同的js或css资源时,可以指定这些资源在多个子应用之间共享,在子应用加载时直接从缓存中提取数据,从而提高渲染效率和性能。我大概可以理解为在基座中配置资源共享,这样子应用就可以直接用这个资源了。那我好奇要是子应用单独运行呢?这个资源还存在吗?或者是就直接没有这些共享的资源了?
因此自己亲自试了一下,将子应用1引入的样式注释掉,在基座中引入,基座是没看出来有什么问题,但是子应用1因为失去了样式就变的乱七八糟,关于这一点网上也没有找到太多的内容

在这里插入图片描述
在这里插入图片描述
但是在下面6、组件共享实现后,可以用同一方式实现样式共享,具体可看6中介绍。

6、组件共享

在目前微前端搭建的基础上,可以发现一些问题,公共组件。如果一个组件在基座和子应用中都需要用到,目前的状态是每个项目都写一遍,这样很麻烦。所以要想个办法实现组件共享
关于共享,我这边看到一个 monorepo(单一代码库) ,差不多意思是单个代码库里包含了许多项目的代码,但是后面没用该方法,所以也不知道好不好实现。
我这边用的是后台大佬分享的这篇文章中的方法三,大体参考,但是实际还需要修改一番,接下来看看我的实现步骤:
注:我这边把通用组件都放在基座base中,如果你想单独建一个项目来放通用组件也行,具体看个人想法。

6-1、项目目录结构

如下图所示目录结构。基座和子应用都放在一个大的文件夹micro-app-element下,假装base中的组件是通用组件,我现在在子应用1vue-element-first中进行一些操作,来实现组件的共享
在这里插入图片描述

6-2、修改vue.config.js

参考文章中是修改webpack.js配置。我们项目是vue-element-admin。webpack的相关配置我这边找到是在vue.config.js中配置的,所以路径相关在vue.config.js中配置即可。
在这里插入图片描述

// 注:根据自己的项目结果及项目名称修改

console.log('__dirname', __dirname, typeof __dirname, path.join(path.parse(__dirname).dir, 'vue-element-base/src'), '\r\n', path.parse(__dirname))
// 注:只需要添加baseComponent那一行即可,如果想调用子应用2,可以在或其它可以在重新配置一条

resolve: {
  alias: {
    '@': resolve('src'),
    'baseComponent': path.join(path.parse(__dirname).dir, 'vue-element-base/src')
  }
}

6-3、配置路由共享组件

这边在子应用1的路由中随便改一下首页的路径,让子应用1去访问基座中的首页页面
在这里插入图片描述

{
  path: '/',
  component: Layout,
  redirect: '/dashboard',
  children: [
    {
      path: 'dashboard',
      // component: () => import('@/views/dashboard/index'),
      component: () => import('baseComponent/views/dashboard/index'),
      name: 'Dashboard',
      meta: { title: 'dashboard', icon: 'dashboard', affix: true }
    }
  ]
},

然后因为三个应用内容都差不多,去基座改一下首页
在这里插入图片描述
接下来看效果:
在这里插入图片描述

6-4、import导入共享组件

在6-3中尝试了在路由中直接修改路径共享到基座菜单的方法,接下来在尝试一下在页面中通过import导入基座组件的方法吧。同样在基座中随便找了个组件Dropzone,照着抄抄就好了
在这里插入图片描述
micro-app-element\vue-element-first\src\views\nested\menu1\index.vue

<template>
  <div style="padding:30px;">
    <div style="height: 50px;">
      <el-button type="primary" @click="jumpApp2('DynamicTable')">我想从子应用1菜单1跳转到子应用2菜单1</el-button>
    </div>
    <el-alert :closable="false" title="menu 1">
      我是子应用菜单1
      <div class="editor-container">
        <dropzone id="myVueDropzone" url="https://httpbin.org/post" @dropzone-removedFile="dropzoneR" @dropzone-success="dropzoneS" />
      </div>
      <router-view />
    </el-alert>
  </div>
</template>
<script>
import Dropzone from 'baseComponent/components/Dropzone'
export default {
  name: 'Menu1',
  components: { Dropzone },
  methods: {
    dropzoneS(file) {
      console.log(file)
      this.$message({ message: 'Upload success', type: 'success' })
    },
    dropzoneR(file) {
      console.log(file)
      this.$message({ message: 'Delete success', type: 'success' })
    },
    /**
     * 点击跳转到页面
     * @param name
     */
    jumpApp2(name) {
      // 向基项目发送数据d
      window.microApp && window.microApp.dispatch({ route: { name }})
    }
  }
}
</script>

然后同样为了明显的看清楚我这边子应用1嵌入了base组件,我同样在代码里加了一点描述用来区分

<div style="color: #ff4949;font-size: 18px;">我是基座的公共组件</div>

在这里插入图片描述
实现效果如下图所示:
在这里插入图片描述

7、总结

到这里,对micro-app在vue-element-admin中的使用就研究的差不多了,因为初学,可能也存在一些问题,所以欢迎搭建评论区留言纠正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/499453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

❤ 个人博客的搭建和设置

❤ 个人博客的搭建和设置 闲暇时候自己试着做了一个自己的个人博客&#xff0c;博客使用的Github进行托管&#xff0c;还在阿里云买了属于自己的域名 具体步骤如下 1、登陆自己的博客账号&#xff0c;新建个人主页的仓库 2、到了我们的名字设置&#xff0c;格外注意&#xf…

Leetcode刷题之两两交换链表中的结点和相交链表

只有把抱怨环境的心情&#xff0c;化为上进的力量&#xff0c;才是成功的保证。 ——罗曼罗兰目录 &#x1f349;一.相交链表 &#x1f490;1.双指针 &#x1f34d;2.计算长度加双指针 &#x1f352;二.两两交换链表中的结点 &#x1f34c;1.迭代 &#x1f349;一…

【Golang】多线程下载器的实现

〇、前言 多线程下载&#xff0c;顾名思义就是对一个文件进行切片访问&#xff0c;等待所有的文件下载完成后在本地进行拼接成一个整体文件的过程。 因此可以利用 golang 的多协程对每个分片同步下载&#xff0c;之后再合并且进行md5校验或者总长度校验。 一、请求资源 下载…

5.7学习周报

文章目录 前言文献阅读摘要简介数据方法论预测结果结论 时间序列预测总结 前言 本周阅读文献《Water quality forecasting based on data decomposition, fuzzy clustering and deep learning neural network》&#xff0c;文献主要结合数据分解、模糊C均值聚类和双向门控循环…

设计模式 - 工厂方法模式

设计模式 - 工厂方法模式 1、关于工厂方法模式2、工厂方法模式小试牛刀2.1、类图2.2、代码清单3、工厂方法模式的扩展3.1、简单工厂模式&#xff08;静态工厂模式&#xff09; 1、关于工厂方法模式 工厂方法模式&#xff0c;就是定义一个用于创建对象的接口&#xff0c;让子类决…

Ubuntu20升级nodejs版本

执行 grunt build的时候提示node版本过低 当前版本为10.19.0&#xff0c;不满足要求 安装 n&#xff0c;用于更新 node 版本的 sudo npm install n -g用n 下载 nodejs 的最新稳定版本 sudo n stable3. 安装完毕&#xff0c;node -r检查当前版本

【算法与数据结构】链表

链表 链表&#xff1a;结构定义 链表是由一串节点串联在一起的&#xff0c;链表的每个节点存储两个信息&#xff1a;数据下一个节点的地址 分清楚两个概念&#xff1a;什么是内存内部&#xff0c;什么是程序内部 内存内部&#xff1a; 信息存储在内存空间里的 程序内部&#…

复习笔记1

考纲(张友生版本软件架构 考试题型&#xff1a; 10*3单选 5*3简答题 5*3设计图&#xff08;含画图&#xff09; 10*2 论述题 10*2综合题 复习以课件为主&#xff0c;书为辅 第一章 (软件危机) &#xff1f; &#xff1f; 构造模型与实现 掌握软件结构体系核心模型 第二章 软件体…

阿里云Alibaba Cloud Linux镜像系统介绍及常见问题解答FAQ

阿里云服务器操作系统Alibaba Cloud Linux镜像怎么样&#xff1f;可以代替CentOS吗&#xff1f;Alibaba Cloud Linux兼容性如何&#xff1f;有人维护吗&#xff1f;漏洞可以修复吗&#xff1f;Alibaba Cloud Linux完全兼容CentOS&#xff0c;并由阿里云官方免费提供长期维护。 …

Java并发,夺命 60 问

基础 1.并行跟并发有什么区别&#xff1f; 从操作系统的角度来看&#xff0c;线程是CPU分配的最小单位。 并行就是同一时刻&#xff0c;两个线程都在执行。这就要求有两个CPU去分别执行两个线程。 并发就是同一时刻&#xff0c;只有一个执行&#xff0c;但是一个时间段内&am…

linux系统中rpm与Yum软件仓库

rpm的作用&#xff1a; 在没有rpm软件管理之前我们在安装、升级、卸载服务程序时要考虑到其他程序、库的依赖关系&#xff0c;所以在进行安装、校验、卸载、升级等操作时的难度就非常之大。 rpm机制则为就是为了解决这些问题而设计的&#xff0c;rpm有点像windows系统中的控制…

xawtv涉及的vivid系统调用分析

xawtv涉及的vivid系统调用分析 文章目录 xawtv涉及的vivid系统调用分析调用过程分析摄像头驱动程序必需的11个ioctl非必须必须 分析数据的获取过程1.请求分配缓冲区: ioctl(4, VIDIOC_REQBUFS // 请求系统分配缓冲区2.查询映射缓冲区:3.把缓冲区放入队列:4.启动摄像头5.用selec…

Docker-Flannel网络讲解

目录 什么是Flannel Flannel原理 部署 环境准备 安装etcd 安装fannel 在server2上装flannel 测试 什么是Flannel flannel是 CoreOS 团队针对 Kubernetes 设计的一个覆盖网络&#xff08;Overlay Network&#xff09;工具&#xff0c;其目的在于帮助每一个使用 Kuberent…

文心一言 VS chatgpt (15)-- 算法导论3.2 4~5题

四、函数 ⌈ lg ⁡ n ⌉ ! \lceil \lg n \rceil ! ⌈lgn⌉! 多项式有界吗&#xff1f;函数 ⌈ lg ⁡ lg ⁡ n ⌉ ! \lceil \lg \lg n \rceil ! ⌈lglgn⌉! 多项式有界吗&#xff1f; 文心一言&#xff1a; chatgpt&#xff1a; 对于第一个问题&#xff0c;函数 ⌈ lg ⁡ n…

C++类和对象(6)

类和对象 1.在谈构造函数1.1. 构造函数体赋值1.2. 初始化列表1.3. explicit关键字 2. static成员2.1. 概念2.2. 特性 3.友元函数3.2.友元类 4. 内部类5.匿名对象6.拷贝对象时的一些编译器优化7.再次理解类和对象 1.在谈构造函数 1.1. 构造函数体赋值 在创建对象时&#xff0c…

【SPSS】回归分析详细操作教程(附案例实战)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

数据结构入门-顺序表链表

线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。线性表是一种实际中广泛使用多个数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线。…

前后端图片交互的简易方式

前后端图片交互的简易方式 一、交互方式说明二、前后端具体代码实现前端具体代码实现后端具体代码实现效果 测试结果 一、交互方式说明 在项目的实际开发中&#xff0c;难免会遇到前端需要渲染数据库中保存的图片&#xff0c;那咱知道图片也属于一种文件&#xff0c;不好保存到…

maven依赖jar包时版本冲突的解决

1、第一声明优先原则 在pom.xml配置文件中&#xff0c;如果有两个名称相同版本不同的依赖声明&#xff0c;那么先写的会生效。 所以&#xff0c;先声明自己要用的版本的jar包即可。 所以&#xff0c;添加新依赖时要放在最后边&#xff0c;以防止新依赖替换原有依赖造成版本冲…

Mybatis基础操作XML映射文件

Mybatis基本操作 一、环境准备 数据库表和springboot工程在课程资料中都有提供 注意&#xff0c;entrydate是用的jdk1.8中的LocalDate类型&#xff0c;createTime用的是jdk1.8中的LocalDateTime类型 二、删除 Mybatis中提供了一种参数占位符 #{id} empMapper.java package…