New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@sl-theia/theia-socket-vue3

Package Overview
Dependencies
Maintainers
2
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sl-theia/theia-socket-vue3

Vue3 adapter for Theia Socket

latest
npmnpm
Version
0.1.2
Version published
Maintainers
2
Created
Source

@sl-theia/theia-socket-vue3

Vue3 版本的 Theia Socket 客户端封装。它基于 @sl-theia/socket-api-core,提供和 React 版本 @sl-theia/theia-socket-io-client 对齐的 socket 能力,并用 Vue3 的 provide/inject 与组合式 API 封装常用接入方式。

安装

npm install @sl-theia/theia-socket-vue3

或使用 pnpm:

pnpm add @sl-theia/theia-socket-vue3

本包要求项目中已安装 Vue3:

pnpm add vue

快速开始

1. 在应用入口挂载 Provider

TheiaSocketProvider 会创建 TheiaSocketClient 实例,并通过 Vue 的依赖注入提供给子组件。所有使用 useSocket、useTheiaSocket、injectSocket 的组件都必须放在 Provider 子树中。

<template>
  <TheiaSocketProvider :config="socketConfig">
    <RouterView />
  </TheiaSocketProvider>
</template>

<script setup lang="ts">
import {
  TheiaSocketProvider,
  type theiaSocketClientCfg,
} from '@sl-theia/theia-socket-vue3';

const socketConfig: theiaSocketClientCfg = {
  userRole: 'WebController',
  userGroup: 'default',
  hostname: window.location.hostname,
  port: '8070',
  namespace: '/TheiaVis',
  devTool: true,
  webApiJson: {},
};
</script>

2. 在页面中使用 useSocket

useSocket 是推荐用法。它会根据 name 创建当前页面或组件对应的实体 facade,返回的对象只暴露页面常用 socket 方法。

<template>
  <button type="button" @click="queryApis">查询 API</button>
  <button type="button" @click="emitNativeApi">调用 NativeAPI</button>
</template>

<script setup lang="ts">
import { onBeforeUnmount } from 'vue';
import { useSocket } from '@sl-theia/theia-socket-vue3';

const socket = useSocket({ name: 'DashboardPage' });

const offConnect = socket.onConnect((msg) => {
  console.log('socket connected:', msg);
});

const offQueryResponse = socket.onQueryResponse((msg) => {
  console.log('query response:', msg);
});

function queryApis() {
  socket.query();
}

function emitNativeApi() {
  socket.theiaEmit({
    Entity: 'BP_PointManager_2',
    NativeAPI: {
      API_ShowPoint: {
        Description: 'Show point',
        Parms: {
          show: true,
          type: '',
        },
      },
    },
  });
}

onBeforeUnmount(() => {
  offConnect();
  offQueryResponse();
});
</script>

3. 注册 WebAPI

WebAPI 是 Web 侧暴露给 Theia/Native 侧调用的 API。注册时建议在组件卸载时注销,避免页面重新进入后重复注册。

<script setup lang="ts">
import { onBeforeUnmount, ref } from 'vue';
import { useSocket } from '@sl-theia/theia-socket-vue3';

type SetCountParams = {
  count?: number;
};

const count = ref(0);
const socket = useSocket({ name: 'CounterPage' });

function API_SET_COUNT(params: SetCountParams = {}) {
  count.value += Number(params.count || 0);
}

socket.registerAPI('API_SET_COUNT', API_SET_COUNT);

onBeforeUnmount(() => {
  socket.unregisterAPI('API_SET_COUNT');
});
</script>

调用 WebAPI 时,Entity 要和注册 API 时的实体名一致:

socket.theiaEmit({
  Entity: 'CounterPage',
  WebAPI: {
    API_SET_COUNT: {
      Description: 'Update counter',
      Parms: {
        count: 1,
      },
    },
  },
});

在 vis/umi Vue3 项目中使用

如果项目通过 @sl-theia/vis 和 @umijs/preset-vue 接入,可以直接在 .umirc.ts 中开启 theiaSocket。插件会识别 Vue3 项目,并自动选择 @sl-theia/theia-socket-vue3。

import { defineConfig } from '@sl-theia/vis';

export default defineConfig({
  presets: ['@umijs/preset-vue'],
  vue: {},
  theiaSocket: {
    userRole: 'webUI',
    userGroup: 'default',
    hostname: '127.0.0.1',
    port: '8070',
    namespace: '/TheiaVis',
    devTool: true,
    autoRegister: {},
  },
});

开启插件后,可以从 umi 导入运行时生成的 socket 工具:

<script setup lang="ts">
import { onBeforeUnmount } from 'vue';
// 由 theiaSocket 运行时插件生成。
import { socketEmiter, useSocket } from 'umi';

const socket = useSocket({ name: 'VueSocketPage' });

function API_SET_COUNT(params: { count?: number } = {}) {
  console.log('receive count:', params.count);
}

socket.registerAPI('API_SET_COUNT', API_SET_COUNT);

function emitApiSetCount() {
  socketEmiter.theiaEmit({
    Entity: 'VueSocketPage',
    WebAPI: {
      API_SET_COUNT: {
        Parms: {
          count: 1,
        },
      },
    },
  });
}

onBeforeUnmount(() => {
  socket.unregisterAPI('API_SET_COUNT');
});
</script>

API

TheiaSocketProvider

Provider 组件,用于创建并注入 socket 实例。

属性类型必填说明
configtheiaSocketClientCfg是socket 连接配置

config 常用字段:

字段类型必填默认值说明
hostnamestring否window.location.hostname 或 127.0.0.1socket 服务地址
portstring否8070socket 服务端口
namespacestring否/TheiaVissocket 命名空间
userRolestring是-当前 Web 客户端注册角色
userGroupstring否-当前 Web 客户端分组
devToolboolean否false是否开启调试工具
webApiJsonobject否{}WebAPI 注册信息,通常由 vis 插件生成

useSocket

function useSocket(config?: { name?: string }): SocketFacade;

推荐在业务页面和组件中使用。name 会作为当前实体名参与 WebAPI 注册和消息发送。

const socket = useSocket({ name: 'HomePage' });

如果不传 name,运行时会输出错误日志,匿名函数场景下建议显式传入。

useTheiaSocket

function useTheiaSocket(): TheiaSocketClient;

返回完整的 TheiaSocketClient 实例,适合需要访问底层 client、entities 或 socket 实例的高级场景。

const client = useTheiaSocket();
client.query();

injectSocket

function injectSocket(config?: { name?: string }): (WrappedComponent: Component) => Component;

injectSocket 会把 socket 注入到被包装组件的 props 中,主要用于需要沿用 React 版本高阶组件风格的场景。

import { defineComponent, type PropType } from 'vue';
import {
  injectSocket,
  type SocketFacade,
} from '@sl-theia/theia-socket-vue3';

const RawPanel = defineComponent({
  name: 'RawPanel',
  props: {
    socket: {
      type: Object as PropType<SocketFacade>,
      required: true,
    },
  },
  setup(props) {
    props.socket.query();

    return () => null;
  },
});

export default injectSocket({ name: 'RawPanel' })(RawPanel);

createTheiaSocket

function createTheiaSocket(config: theiaSocketClientCfg): TheiaSocketClient;

手动创建 socket client。一般情况下优先使用 TheiaSocketProvider,只有在运行时工具、测试或非组件环境中才需要直接创建。

import { createTheiaSocket } from '@sl-theia/theia-socket-vue3';

const socket = createTheiaSocket({
  userRole: 'manual-client',
  webApiJson: {},
});

provideTheiaSocket

function provideTheiaSocket(config: theiaSocketClientCfg): TheiaSocketClient;

在自定义 Provider 中创建并注入 socket。

import { defineComponent, h } from 'vue';
import { provideTheiaSocket } from '@sl-theia/theia-socket-vue3';

export default defineComponent({
  setup(_, { slots }) {
    const socket = provideTheiaSocket({
      userRole: 'custom-provider',
      webApiJson: {},
    });

    return () => slots.default?.();
  },
});

SocketFacade 方法

useSocket 和 injectSocket 返回的 socket 都是 SocketFacade。

方法说明返回值
registerAPI(apiName, callback)注册当前实体的 WebAPIvoid
unregisterAPI(apiName)注销当前实体的 WebAPI,支持字符串或字符串数组void
query(entityName?)查询已注册的实体和 API 信息void
theiaEmit(msg)发送 Msg 消息,可调用 NativeAPI 或 WebAPIvoid
theiaOn(callback)监听 Msg 消息() => void
theiaOnce(callback)只监听一次 Msg 消息void
onConnect(callback)监听客户端连接广播() => void
onDisconnect(callback)监听客户端断开广播() => void
onQueryResponse(callback)监听 query 的响应() => void
onNativeAPIResponse(callback)监听 NativeAPI 调用响应() => void
onNativeAPIResponseAsync(callback)监听 NativeAPI 异步响应() => void
onWebAPIResponse(callback)监听 WebAPI 调用响应() => void
on(eventName, callback)监听 socket 原生事件() => void

事件监听方法通常会返回取消监听函数,建议在 onBeforeUnmount 中执行。

const offMsg = socket.theiaOn((msg) => {
  console.log('Msg:', msg);
});

onBeforeUnmount(() => {
  offMsg();
});

消息格式示例

调用 NativeAPI

socket.theiaEmit({
  Entity: 'BP_PointManager_2',
  NativeAPI: {
    API_ShowPoint: {
      Description: 'Show point',
      Parms: {
        show: true,
        type: '',
      },
    },
  },
});

调用 WebAPI

socket.theiaEmit({
  Entity: 'CounterPage',
  WebAPI: {
    API_SET_COUNT: {
      Description: 'Set count',
      Parms: {
        count: 10,
      },
    },
  },
});

监听调用结果

const offNativeResponse = socket.onNativeAPIResponse((msg) => {
  console.log('NativeAPI response:', msg);
});

const offWebResponse = socket.onWebAPIResponse((msg) => {
  console.log('WebAPI response:', msg);
});

onBeforeUnmount(() => {
  offNativeResponse();
  offWebResponse();
});

导出内容

export {
  Entity,
  Provider,
  SocketContext,
  TheiaSocketClient,
  TheiaSocketProvider,
  createSocketFacade,
  createTheiaSocket,
  injectSocket,
  provideTheiaSocket,
  socketKey,
  useSocket,
  useTheiaSocket,
};
export type {
  EntityConfig,
  InjectSocketProps,
  SocketFacade,
  injectSocketProps,
  theiaSocketClientCfg,
};

Provider 是 TheiaSocketProvider 的别名,SocketContext 是 socketKey 的别名,用于对齐 React 版本 API 命名。

打包产物

包内同时提供 CJS、ESM 和独立类型声明:

{
  "main": "dist/cjs/index.js",
  "module": "dist/esm/index.js",
  "types": "dist/types/index.d.ts"
}

发布文件只包含运行时 JS、类型声明,以及用于导出边界和模块类型声明的 package.json 文件,不会发布 .map 文件。

常见问题

useSocket 报错 TheiaSocketClient has not been provided.

说明当前组件没有被 TheiaSocketProvider 包裹。请把 Provider 放在应用入口或当前页面父级。

页面重复进入后 WebAPI 被重复调用.

通常是注册后没有注销。请在 onBeforeUnmount 中调用 unregisterAPI,并清理事件监听返回的 off 函数。

Umi/vis 项目里应该从哪里导入 useSocket.

开启 theiaSocket 插件后,业务页面推荐从 umi 导入:

import { socketEmiter, useSocket } from 'umi';

独立 Vue3 项目或非 Umi 项目从本包导入:

import { TheiaSocketProvider, useSocket } from '@sl-theia/theia-socket-vue3';

FAQs

Package last updated on 25 Jun 2026

Related posts