vue3乾坤使用(2)------乾坤微前端如何控制权限

610 阅读4分钟

在 乾坤(qiankun)  微前端架构中,权限控制是一个重要的需求。由于主应用和子应用是独立开发和部署的,权限控制需要在主应用和子应用之间协同完成。以下是实现权限控制的几种常见方案:


1. 权限控制方案

1.1 主应用统一控制权限

  • 实现方式

    • 主应用负责用户登录和权限管理。
    • 主应用通过 props 将权限信息传递给子应用。
    • 子应用根据权限信息渲染内容或路由。
  • 优点

    • 权限逻辑集中管理,便于维护。
    • 子应用无需关心权限逻辑,只需根据权限数据渲染内容。
  • 缺点

    • 主应用和子应用需要约定权限数据的格式。
  • 实现步骤

    1. 在主应用中获取用户权限。

    2. 注册子应用时,通过 props 传递权限数据。

    3. 子应用根据权限数据控制路由或页面内容。

    // 主应用
    registerMicroApps([
      {
        name: 'vue3-app',
        entry: '//localhost:8081',
        container: '#subapp-container',
        activeRule: '/vue3',
        props: {
          permissions: ['user:read', 'user:write'] // 传递权限数据
        }
      }
    ])
    
    // 子应用
    export async function mount(props) {
      const { permissions } = props
      // 根据权限数据控制路由或页面内容
      if (!permissions.includes('user:read')) {
        router.replace('/no-permission')
      }
      render(props)
    }
    

1.2 子应用独立控制权限

  • 实现方式

    • 子应用独立管理权限逻辑。
    • 子应用通过接口或主应用传递的 props 获取权限数据。
  • 优点

    • 子应用可以灵活处理权限逻辑。
    • 主应用和子应用解耦。
  • 缺点

    • 每个子应用需要重复实现权限逻辑。
  • 实现步骤

    1. 子应用在 mount 生命周期中获取权限数据。

    2. 根据权限数据控制路由或页面内容。

    // 子应用
    export async function mount(props) {
      const permissions = await fetchPermissions() // 从接口获取权限数据
      if (!permissions.includes('user:read')) {
        router.replace('/no-permission')
      }
      render(props)
    }
    

1.3 主应用和子应用协同控制权限

  • 实现方式

    • 主应用负责全局权限管理(如菜单权限)。
    • 子应用负责局部权限管理(如按钮权限)。
  • 优点

    • 权限控制更加细粒度。
    • 主应用和子应用各司其职。
  • 缺点

    • 需要主应用和子应用协同开发。
  • 实现步骤

    1. 主应用通过 props 传递全局权限数据。

    2. 子应用根据全局权限数据控制路由或菜单。

    3. 子应用内部通过接口或本地逻辑控制按钮权限。

    // 主应用
    registerMicroApps([
      {
        name: 'vue3-app',
        entry: '//localhost:8081',
        container: '#subapp-container',
        activeRule: '/vue3',
        props: {
          globalPermissions: ['menu:user', 'menu:order'] // 传递全局权限数据
        }
      }
    ])
    
    // 子应用
    export async function mount(props) {
      const { globalPermissions } = props
      // 根据全局权限数据控制菜单
      if (!globalPermissions.includes('menu:user')) {
        router.replace('/no-permission')
      }
      render(props)
    }
    

2. 动态路由权限控制

在子应用中,可以根据权限动态生成路由。

  • 实现方式

    1. 在 mount 生命周期中获取权限数据。

    2. 根据权限数据动态生成路由。

    3. 使用 router.addRoute 动态添加路由。

    // 子应用
    export async function mount(props) {
      const permissions = await fetchPermissions()
      const routes = generateRoutes(permissions) // 根据权限生成路由
      routes.forEach(route => router.addRoute(route))
      render(props)
    }
    

3. 权限控制的常见场景

3.1 菜单权限

  • 主应用根据权限数据动态生成菜单。
  • 子应用根据权限数据动态生成子菜单。

3.2 路由权限

  • 主应用根据权限数据动态加载子应用。
  • 子应用根据权限数据动态生成路由。

3.3 按钮权限

  • 子应用根据权限数据控制按钮的显示和隐藏。

4. 示例代码

主应用

// main.js (主应用)
import { registerMicroApps, start } from 'qiankun'

const permissions = ['user:read', 'user:write'] // 模拟权限数据

registerMicroApps([
  {
    name: 'vue3-app',
    entry: '//localhost:8081',
    container: '#subapp-container',
    activeRule: '/vue3',
    props: { permissions }
  }
])

start()

子应用

// main.js (子应用)
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

let instance = null

function render(props = {}) {
  const { container, permissions } = props
  instance = createApp(App)
  instance.use(router)
  instance.mount(container ? container.querySelector('#app') : '#app')

  // 根据权限控制路由
  if (!permissions.includes('user:read')) {
    router.replace('/no-permission')
  }
}

export async function mount(props) {
  console.log('子应用挂载')
  render(props)
}

export async function unmount() {
  console.log('子应用卸载')
  instance.unmount()
  instance = null
}

5. 总结

在乾坤微前端架构中,权限控制可以通过以下方式实现:

  1. 主应用统一控制权限:通过 props 传递权限数据。
  2. 子应用独立控制权限:子应用通过接口或 props 获取权限数据。
  3. 主应用和子应用协同控制权限:主应用控制全局权限,子应用控制局部权限。

根据项目需求选择合适的方案,确保权限控制的灵活性和可维护性。