当前位置:首页 > VUE

vue实现动态租户入口

2026-01-22 03:11:44VUE

Vue 实现动态租户入口方案

动态租户入口通常用于 SaaS 或多租户系统,允许用户通过不同域名或路径访问各自独立的租户环境。以下是基于 Vue 的实现方案:

路由动态配置

通过 Vue Router 实现动态路由匹配,根据租户标识加载不同模块:

// router.js
const router = new VueRouter({
  routes: [
    {
      path: '/:tenantId',
      component: TenantLayout,
      children: [
        {
          path: 'dashboard',
          component: () => import('./views/TenantDashboard.vue')
        }
      ]
    }
  ]
})

全局租户状态管理

使用 Vuex 或 Pinia 管理租户信息:

// store/tenant.js
export const useTenantStore = defineStore('tenant', {
  state: () => ({
    currentTenant: null,
    tenants: []
  }),
  actions: {
    async fetchTenants() {
      this.tenants = await api.getTenants()
    },
    setTenant(tenantId) {
      this.currentTenant = this.tenants.find(t => t.id === tenantId)
    }
  }
})

动态主题切换

根据租户配置加载不同的主题样式:

vue实现动态租户入口

// utils/theme.js
export function loadTenantTheme(tenantId) {
  const link = document.createElement('link')
  link.rel = 'stylesheet'
  link.href = `/themes/${tenantId}.css`
  document.head.appendChild(link)
}

入口组件处理

创建租户入口组件处理初始化逻辑:

<!-- TenantEntry.vue -->
<template>
  <router-view v-if="initialized"/>
</template>

<script>
import { useTenantStore } from '@/stores/tenant'

export default {
  data() {
    return {
      initialized: false
    }
  },
  async created() {
    const tenantId = this.$route.params.tenantId
    await useTenantStore().setTenant(tenantId)
    loadTenantTheme(tenantId)
    this.initialized = true
  }
}
</script>

API 请求拦截

在 axios 拦截器中自动添加租户头信息:

vue实现动态租户入口

// api/interceptors.js
axios.interceptors.request.use(config => {
  const tenantId = store.state.tenant.currentTenant?.id
  if (tenantId) {
    config.headers['X-Tenant-ID'] = tenantId
  }
  return config
})

多域名支持配置

对于跨域名的租户访问,可通过动态 publicPath 实现:

// vue.config.js
module.exports = {
  publicPath: process.env.VUE_APP_TENANT_ID 
    ? `https://${process.env.VUE_APP_TENANT_ID}.domain.com`
    : '/'
}

租户切换处理

实现租户切换的逻辑:

// utils/tenantSwitch.js
export function switchTenant(newTenantId) {
  const currentPath = route.path.replace(/^\/[^/]+/, '')
  router.push(`/${newTenantId}${currentPath}`)
  location.reload() // 确保资源重新加载
}

动态组件加载

按需加载租户特定的组件:

// components/TenantComponent.js
export default {
  components: {
    TenantSpecific: () => import(
      /* webpackChunkName: "tenant-[request]" */ 
      `@/components/tenants/${tenantId}/SpecialComponent.vue`
    )
  }
}

实现时需考虑缓存策略、错误处理和权限验证等边界情况。部署阶段需要配合后端服务进行租户识别和资源配置。

标签: 租户入口
分享给朋友: