UNPKG

@discreted/vue-browser-tabs

Version:
243 lines (189 loc) 8.5 kB
# TinyBrowserTabs - 浏览器标签页组件 TinyBrowserTabs 是一个基于 TinyVue 组件库、遵循 OpenTiny 设计规范的 Vue3 浏览器标签页组件。它易于使用且功能强大,支持标签页的添加、删除、拖拽排序等操作,提供接近真实浏览器的多标签页体验。 ## 特性与优势 - 支持多标签页的添加、删除、切换和拖拽排序,交互接近主流浏览器,易于使用。 - 提供 tab-title、tab-icon 和 default 等多个插槽,开发者可以自定义每个标签页的标题、图标和内容区域,满足各种业务需求。 - 通过 `tabs` 属性传入标签页数据,支持动态添加、删除和切换,便于与后端或业务逻辑集成。 - 提供 add、close、go-back、go-forward、refresh 等事件,方便父组件监听和处理用户操作。 - 支持嵌入网页/iframe,每个标签页可以加载不同的 URL,适用于 WebView、页面预览、低代码平台等场景。 - 作为 Vue3 组件开发,API 简单,易于集成到任何 Vue 项目中。 ## 快速上手 安装 TinyBrowserTabs ```shell npm i @opentiny/vue-browser-tabs ``` 导入 TinyBrowserTabs : ```javascript import TinyBrowserTabs from '@opentiny/vue-browser-tabs' ``` 在模板中使用: ```html <script setup> import { ref } from 'vue' import TinyBrowserTabs from '@opentiny/vue-browser-tabs' const tabs = ref([ { title: '百度', name: 'baidu', url: 'https://www.baidu.com', icon: 'https://www.baidu.com/favicon.ico' }, { title: '必应', name: 'bing', url: 'https://www.bing.com', icon: 'https://www.bing.com/favicon.ico' } ]) const activeName = ref('baidu') const handleClose = (name) => { tabs.value = tabs.value.filter((tab) => tab.name !== name) } const handleAdd = () => { const idx = tabs.value.length + 1 tabs.value.push({ title: `新标签页${idx}`, name: `tab${idx}`, url: '', icon: '' }) } </script> <template> <TinyBrowserTabs v-model="activeName" :items="tabs" @close="handleClose" @add="handleAdd" /> </template> ``` ## 本地开发 ```shell git clone git@github.com:opentiny/mcp.git cd package/tiny-browser-tabs pnpm i pnpm dev ``` 打开浏览器访问:[http://localhost:5173/tiny-browser-tabs/](http://localhost:5173/tiny-browser-tabs/) ## API ### Props | 属性名 | 类型 | 默认值 | 说明 | | --------------- | ------- | ------ | -------------------- | | items | items[] | [] | 标签页列表数据 | | modelValue | string | - | 当前激活的标签页名称 | | draggable | boolean | false | 标签页是否可拖拽 | | backward | boolean | true | 是否启用后退功能 | | forward | boolean | true | 是否启用前进功能 | | addressEditable | boolean | false | 地址栏是否可编辑 | ## 事件 | 事件 | 参数 | 说明 | | ------------- | ------------- | ------------------- | | change | Item | 标签页已更改 | | close | Item | 标签页已关闭 | | add | - | 添加新标签页 | | address-enter | string, Item | 地址栏回车 | | go-back | Item | 后退 | | go-forward | Item | 前进 | | refresh | Item | 刷新 | | minimize | - | 最小化窗口 | | maximize | - | 最大化窗口 | | window-close | - | 关闭窗口 | | star | Item, boolean | 收藏/取消收藏标签页 | ### 插槽 (Slots) | 插槽 | 属性 | 说明 | | --------- | --------------------------- | ---------------- | | tab-icon | { item, index, isActive } | 自定义标签页图标 | | tab-title | { item, index, isActive } | 自定义标签页标题 | | default | { item, items, activeName } | 自定义标签页内容 | ### 类型定义 ````typescript interface Tab { title: string name: string url?: string icon?: string } ## MCP 集成 ### 在 iframe 页面中使用 McpProxyClient ```javascript import { McpProxyClient } from '@opentiny/vue-browser-tabs' // 创建一个新的 MCP 代理客户端实例 const mcpProxyClient = new McpProxyClient() // 注册一个工具 await mcpProxyClient.registerTool('my-tool', { description: '一个示例工具', parameters: { type: 'object', properties: { message: { type: 'string', description: '要处理的消息' } }, required: ['message'] }, implementation: async (args) => { // 工具实现在 iframe 上下文中运行 return { success: true, result: `已处理: ${args.message}` } } }) // 调用一个工具 const result = await mcpProxyClient.callTool('another-tool', { param1: 'value1' }) // 列出可用的工具 const tools = await mcpProxyClient.listTools() ```` ### 设置与父组件的通信 在你的 iframe 页面中,你需要为 MCP 代理客户端设置目标源: ```javascript // 等待父组件发送配置 window.addEventListener('message', (event) => { if (event.data && event.data.type === 'MCP_CONFIG') { // 设置通信的目标源 mcpProxyClient.setTargetOrigin(event.origin) } }) ``` ### iframe 应用的 MCP 代理 组件还提供了一个 MCP 代理机制,允许 iframe 应用通过 postMessage 通信使用父应用的 MCP 服务。这使得单个 web agent 能够控制多个 iframe 应用界面。 #### 工作原理 1. 当 iframe 加载时,它会向父应用发送 `LOAD_COMPLETE` 消息 2. 父应用响应并发送 MCP 配置给 iframe 3. iframe 使用 `mcpProxyClient` 与父应用的 MCP 服务通信 4. 父应用处理 MCP 操作并将结果返回给 iframe #### 在 iframe 应用中使用 mcpProxyClient ```javascript // 在 iframe 应用组件中 import { inject } from 'vue' // 获取父应用提供的 MCP 代理客户端 const mcpProxyClient = inject('mcpProxyClient') // 注册工具 await mcpProxyClient.registerTool('my-tool', { description: '我的自定义工具', implementation: async (args) => { return { success: true, result: '工具执行成功' } } }) // 调用工具 const result = await mcpProxyClient.callTool('existing-tool', { param: 'value' }) // 列出所有工具 const tools = await mcpProxyClient.listTools() ``` 这种机制使单个 AI agent 能够: 1. 控制多个 iframe 应用 2. 从不同的 iframe 应用注册工具 3. 协调跨多个应用的复杂任务 4. 维护统一的控制界面 ## 贡献者 ✨ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> <!-- prettier-ignore-start --> <!-- markdownlint-disable --> <table> <tbody> <tr> <td align="center" valign="top" width="12.5%"><a href="https://kagol.github.io/blogs"><img src="https://avatars.githubusercontent.com/u/9566362?v=4?s=100" width="100px;" alt="Kagol"/><br /><sub><b>Kagol</b></sub></a><br /><a href="https://github.com/opentiny/tiny-browser-tabs/commits?author=kagol" title="Code">💻</a></td> <td align="center" valign="top" width="12.5%"><a href="https://github.com/zzcr"><img src="https://avatars.githubusercontent.com/u/18521562?v=4?s=100" width="100px;" alt="ajaxzheng"/><br /><sub><b>ajaxzheng</b></sub></a><br /><a href="https://github.com/opentiny/tiny-browser-tabs/commits?author=zzcr" title="Code">💻</a></td> <td align="center" valign="top" width="12.5%"><a href="https://github.com/discreted66"><img src="https://avatars.githubusercontent.com/u/190872652?v=4?s=100" width="100px;" alt="liukun"/><br /><sub><b>liukun</b></sub></a><br /><a href="https://github.com/opentiny/tiny-vue/commits?author=discreted66" title="Code">💻</a></td> </tr> </tbody> </table> <!-- markdownlint-restore --> <!-- prettier-ignore-end --> <!-- ALL-CONTRIBUTORS-LIST:END --> This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!