在全球团队用工场景里,Remote.com 扮演的是名义雇主与薪酬服务商角色,它把不同国家的合同、税务、社保封装成一套 API。Vue 3 项目如果只图快,很容易把 fetch 调用直接写进页面,结果上线后遇到 Token 过期、多子公司数据串号、Webhook 被重放等麻烦。工程化集成意味着把 Remote.com 当成一个内部 HR 中台来设计:环境隔离、请求层统一、业务组件只消费状态。

工程目录与构建层的环境隔离
Vue 3 配合 Vite 时,最先要处理的是 Remote.com 的 API Base 与 Client ID 在不同环境(本地、预发、生产)下的切换。很多项目习惯把密钥写进 .env 但忘了在 vite.config.ts 里做前缀过滤,导致前端包体泄露生产域名。正确方式是用 loadEnv 读取后以 VITE_REMOTE_ 前缀注入,同时在构建时通过 define 把非当前环境的变量 tree-shaking 掉。
目录上建议单开 src/remote/ 收敛所有 Remote.com 相关代码:client.ts 管请求实例,types.ts 管雇员与发票类型,composables/ 暴露给组件的组合式函数。这样当 Remote.com 的 API 版本从 v1 升到 v2,只需改 client.ts 的拦截器,页面层无感。下表给出一种可落地的结构划分:
| 路径 | 职责 |
|---|---|
| src/remote/client.ts | Axios 实例、鉴权头、重试 |
| src/remote/types.ts | 雇员、合同、发薪单类型 |
| src/remote/composables/useEmployee.ts | 组合式函数供组件调用 |
这种拆法的好处是测试容易写。你可以直接 mock client.ts 导出的 remoteApi 对象,而不用启动真实 Remote.com 沙箱。对于全球 HR 平台来说,合规字段(如本地税号格式)常随国家变化,类型定义集中后,TypeScript 能在编译期拦住大部分字段拼错。
API 请求层与 Token 刷新封装
Remote.com 使用 OAuth2 Client Credentials 拿访问令牌,令牌有效期短,前端若每次进入页面都重新走授权会触发限流。工程化做法是在 client.ts 里用单例维护 access_token 与 expires_at,拦截器发现 401 或本地判断过期就排队刷新,避免并发请求同时刷新造成令牌浪费。
下面是一段去除了业务细节的封装示例,展示如何在 Vue 3 工程里统一处理 Remote.com 的请求头与错误:
import axios from 'axios';
const remoteApi = axios.create({
baseURL: import.meta.env.VITE_REMOTE_BASE,
timeout: 10000
});
let token = '';
let expireAt = 0;
async function ensureToken() {
// 提前 30 秒刷新
if (Date.now() > expireAt - 30000) {
const res = await axios.post(import.meta.env.VITE_REMOTE_AUTH, {
client_id: import.meta.env.VITE_REMOTE_ID,
client_secret: import.meta.env.VITE_REMOTE_SECRET,
grant_type: 'client_credentials'
});
token = res.data.access_token;
expireAt = Date.now() + res.data.expires_in * 1000;
}
return token;
}
remoteApi.interceptors.request.use(async (cfg) => {
cfg.headers.Authorization = 'Bearer ' + await ensureToken();
return cfg;
});
remoteApi.interceptors.response.use(
(r) => r,
(err) => {
// 统一抛出业务可读错误
return Promise.reject(new Error('Remote.com 请求失败: ' + err.message));
}
);
export default remoteApi;
上面代码把密钥放在构建环境变量,运行时只持有一个内存令牌。若你的 Vue 3 应用是纯前端且密钥不能暴露,应改为由后端代理签发短期令牌,前端通过 useEmployee 这类组合式函数向后端要数据,后端再带 Remote.com 令牌去请求。这样即使前端代码被扒,也拿不到 Remote.com 的 Client Secret。
错误重试也要区分场景。网络抖动可重试,但 400 参数错误重试无意义。建议在拦截器里对 429 与 5xx 做指数退避,对 4xx 直接 reject 并在组件里提示用户检查雇员 ID 或合同状态。全球 HR 数据一旦写错,更正流程跨时区很长,前端早一步拦错能省大量工单。
雇员与发薪数据的组件消费与合规渲染
拿到 Remote.com 的雇员列表后,Vue 3 组件应避免直接 v-for 裸渲染。更好的方式是先用 useEmployee 把数据规整成前端模型:把不同国家的日期格式、货币符号、税号掩码在组合式函数里处理完,模板只负责展示。这样当 Remote.com 返回巴西雇员 CPF 或德国税号时,页面不会因格式差异崩掉。
下面的组合式函数示例展示如何把 Remote.com 的雇员对象转成表格行,并标记是否需要本地合规提示:
import { ref } from 'vue';
import remoteApi from '../client';
export function useEmployee() {
const list = ref<any[]>([]);
const loading = ref(false);
async function load(companyId: string) {
loading.value = true;
try {
const res = await remoteApi.get('/v1/companies/' + companyId + '/employees');
list.value = res.data.map((e: any) => ({
id: e.id,
name: e.full_name,
country: e.country_code,
payroll: e.last_invoice_amount ? '已出薪' : '待处理'
}));
} finally {
loading.value = false;
}
}
return { list, loading, load };
}
在页面里调用 useEmployee 后,可以用 <table> 配合 v-if="loading" 做骨架屏。对于 HR 平台,敏感字段如银行账号必须脱敏,不能在 Vue 模板里直接输出原文。建议在 useEmployee 的 map 阶段就把账号转成尾号四位加星号,从源头降低泄露风险。
最后要注意 Webhook。Remote.com 在雇员状态变更时会推事件到你的后端,前端若依赖轮询可能延迟数分钟。工程上应由后端校验签名后写进数据库,前端通过 Vue 3 的响应式 store 订阅变更。这样无论 Remote.com 的推送因网络重放几次,前端看到的都是幂等后的真实状态,不会重复弹窗干扰 HR 操作。
Vue3Remote_comHR_platform修改时间:2026-08-17 07:22:37