@discreted/vue-browser-tabs
v0.1.16
Published
A browser-like tabs component for Vue3
Downloads
28
Maintainers
Readme
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
npm i @opentiny/vue-browser-tabs导入 TinyBrowserTabs :
import TinyBrowserTabs from '@opentiny/vue-browser-tabs'在模板中使用:
<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>本地开发
git clone [email protected]:opentiny/mcp.git
cd package/tiny-browser-tabs
pnpm i
pnpm dev打开浏览器访问: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 } | 自定义标签页内容 |
类型定义
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 代理客户端设置目标源:
// 等待父组件发送配置
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 应用界面。
工作原理
- 当 iframe 加载时,它会向父应用发送
LOAD_COMPLETE消息 - 父应用响应并发送 MCP 配置给 iframe
- iframe 使用
mcpProxyClient与父应用的 MCP 服务通信 - 父应用处理 MCP 操作并将结果返回给 iframe
在 iframe 应用中使用 mcpProxyClient
// 在 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 能够:
- 控制多个 iframe 应用
- 从不同的 iframe 应用注册工具
- 协调跨多个应用的复杂任务
- 维护统一的控制界面
贡献者 ✨
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
