npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gindow/vant-go

v1.0.11

Published

基于 Vant 的移动端扩展组件库

Readme

@gindow/vant-go

基于 Vant 4 的 Vue 3 + TypeScript 移动端业务组件扩展库。 组件前缀 Vax,依赖 @gindow/vue 提供工具类与 i18n 底座。

当前版本:1.0.8 · 15 个组件


1. 速查表

import VantGo, {
  // 组件(15 个,全部可具名导入)
  VaxAssetPreview, VaxAvatar, VaxButton, VaxCaptcha, VaxCell, VaxCellGroup,
  VaxEmpty, VaxField, VaxIcon, VaxLoading, VaxNavBar, VaxPage, VaxSelect,
  VaxTabbar, VaxTabs,
  // Hooks
  useMessage,
  // i18n
  provider, setLocale, getLocale, useLocale,
} from '@gindow/vant-go'

import type { IModel, IAsset } from '@gindow/vant-go'
import { VantGoResolver } from '@gindow/vant-go/resolver'

⚠️ 本包主入口不引入任何样式(刻意为之,见 §9)。样式必须由 app 自己引。

子路径导出

| 子路径 | 内容 | | --- | --- | | @gindow/vant-go | 主入口(无样式副作用) | | @gindow/vant-go/resolver | VantGoResolver | | @gindow/vant-go/locale | 单独的 i18n 入口,不拖入整个组件库 | | @gindow/vant-go/styles/index.css | 完整样式链:vant 本体 + @gindow/vue/style.css + 皮肤 | | @gindow/vant-go/src/styles/style.css | 只有皮肤(不含 vant 本体、不含 tailwind 链) | | @gindow/vant-go/styles/arco.css · purple.css | 可选主题变量 | | @gindow/vant-go/src/* | 源码直取 |

工具函数

@gindow/vant-gosrc/utils 只是 @gindow/vue再导出,且未从主入口透出。 需要 Formatter / Validate / DateTime / Platform 时请直接从 @gindow/vue 导入。


2. 安装

pnpm add @gindow/vant-go @gindow/vue vant vue

| peer 包 | 版本 | 必装 | 用到的组件 | | --- | --- | --- | --- | | vue | ^3.5 | ✅ | 全部 | | vant | ^4.9.24 | ✅ | 全部 | | @gindow/vue | ^1.0.4 | ✅ | i18n / ValidateVaxCaptcha) | | @iconify/vue | ^5 | ✅ | VaxIcon,以及 VaxButton / VaxCell / VaxCellGroup / VaxTabbar / VaxAssetPreview | | vue-router | ^4 \|\| ^5 | 用到才装 | VaxNavBar(back) / VaxTabbar(路由联动) / VaxCell(to) |

vant-go 的 peer 没有 peerDependenciesMeta.optional 声明,包管理器会对全部 5 个提示缺失。 实际只有 vue-router 可按需省略。


3. 注册

A. 全量注册

import { createApp } from 'vue'
import VantGo from '@gindow/vant-go'
import '@gindow/vant-go/styles/index.css'
import App from './App.vue'

createApp(App).use(VantGo, { locale: 'zh-CN' }).mount('#app')

app.use(VantGo, options)provider(options) 初始化语言 + 注册 15 个组件。 options{ locale?: string; messages?: Record<string, any> }

B. 按需 + 自动导入(推荐)

// vite.config.ts
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from '@vant/auto-import-resolver'
import { VantGoResolver } from '@gindow/vant-go/resolver'

export default defineConfig({
  plugins: [
    vue(),
    Components({ resolvers: [VantResolver(), VantGoResolver()] }),
  ],
})

VantGoResolver(options?)

| 选项 | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | prefix | string | 'Vax' | 只解析以此开头的组件名 | | importStyle | boolean | true | 附带 @gindow/vant-go/styles/index.css 副作用(unplugin 去重) |

@layer 组织样式的 app 请设 importStyle: false,改为手动分层引入,见 §9。


4. 组件 API

所有组件均透传 $attrs 到底层 vant 组件(除非下表另行说明),因此 vant 原生 props 可直接使用。

VaxIcon — 图标

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | icon | string | '' | 图标名;含 : 时视为完整名,否则拼 vendor | | vendor | string | 'icon-park-outline' | 图标集前缀 | | size | number | 16 | 宽高(px) | | color | string | — | 颜色 | | background | string | — | 背景色 | | padding | string | — | 内边距;未传时:有 background8px,否则 0 | | round | boolean | false | 圆形;传了 background 时自动为 true | | strokeWidth | number | 3 | 线宽 | | disabled | boolean | false | 置灰(覆盖 color--van-text-color-3) |

  • Slot default:图标右侧追加内容(与图标同处一个 inline-flex 容器)。
  • icon 为空时整个组件不渲染。
  • 颜色优先级:disabledcolor → 有 background 时白色 → 继承。

VaxAvatar — 头像

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | src | string | 内置 avatar.png | 头像地址 | | size | string \| number | 'normal' | small=24 / normal=48 / large=72,或直接给数字(px) | | round | boolean | true | 是否圆形 |

无 slots、无 emits。未知字符串 size 回落到 normal(48)。

VaxButton — 按钮

扩展 van-button,把图标塞进按钮内容区。$attrs 全量透传给 van-buttontypeblockroundloading@click 等直接用)。

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | icon | string | '' | 图标名(传给 VaxIcon) | | iconSize | number | 14 | 图标尺寸 | | iconColor | string | '' | 图标颜色 | | iconStrokeWidth | number | — | 图标线宽 |

Slot default:按钮文字。图标与文字用 flex-center gap-2 排列。

VaxCell — 单元格

扩展 van-cell(固定 center 对齐)。

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | title | string | — | 标题 | | value | string \| number | — | 右侧值 | | label | string | — | 标题下方描述 | | icon | string | — | 左侧图标名 | | iconSize / iconColor / iconBackground / iconStrokeWidth | — | — | 透传给 VaxIcon | | to | string | — | 路由跳转目标(需 vue-router) | | isLink | boolean | false | 显示右箭头;传了 to 时自动为 true | | titleClass / valueClass / labelClass | string | — | 各区域自定义 class | | onClick | () => void | — | 点击回调(作为 prop 传入,也可用 @click) |

| Slot | 说明 | | --- | --- | | icon | 覆盖左侧图标区(默认渲染 VaxIcon) | | title | 自定义标题 | | value | 自定义右侧值 | | label | 自定义描述 |

VaxCellGroup — 卡片容器

数据驱动渲染一组 VaxCell。根元素带 class="vax-card menu"

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | title | string | '' | 分组标题 | | items | IVaxCardItem[] | [] | 数据源 | | compact | boolean | false | 紧凑模式(加 .compact class) | | isLink | boolean | false | 全局默认箭头 | | iconSize / iconColor / iconBackground / iconStrokeWidth | — | — | 全局图标配置 | | titleClass / valueClass / labelClass | string | — | 全局样式类 |

item 级配置覆盖 group 级item.iconColor ?? iconColor)。inset 等 vant 原生 props 直接透传。

| Slot | 说明 | | --- | --- | | title | 自定义标题区 | | default | 在 items 之前插入自定义内容 |

interface IVaxCardItem {
  title: string                 // 必填
  value?: string | number
  label?: string
  icon?: string
  iconSize?: number
  iconColor?: string
  iconBackground?: string
  iconStrokeWidth?: number
  to?: string
  isLink?: boolean
  titleClass?: string
  valueClass?: string
  labelClass?: string
  onClick?: () => void
}

VaxPage — 页面容器

无 props、无 emits,只有默认 slot。渲染 <div class="vax-page">,上下内边距取 var(--ex-page-padding, 16px),左右为 0。

VaxNavBar — 导航栏

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | back | boolean | false | 点击左侧调用 router.back();同时强制显示箭头 | | leftArrow | boolean | false | 显示左箭头 | | leftText | string | '' | 左侧文字 | | clickLeft | Function | 空函数 | 自定义左侧点击处理;back 为 true 时不会被调用 |

Slot right:右侧区域。标题居中/居左由 leftText 决定(有 leftText → 居中,否则居左)。

VaxTabs — 胶囊选项卡

自绘组件(非 van-tabs),横向可滚动。

| Prop / Model | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | tabs | IVaxTab[] | — | 必填 | | sticky | boolean | false | 吸顶(position: sticky; top: 0) | | v-model:active | string | — | 必填,当前选中的 name |

interface IVaxTab { name: string; label: string; badge?: number | string }

无 slots。点击已选中项不会触发更新。

VaxTabbar — 底部标签栏

van-tabbar,固定 placeholder + safe-area-inset-bottom路由 replace 跳转

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | menu | { title?: string; icon: string; to: string; dot?: boolean }[] | [] | 必填 | | flash | boolean | false | 选中项隐藏图标、只放大文字(“闪光”态) |

选中项由当前路由自动推导:取 menu 中能匹配 route.path 前缀且 to 最长的一项,无需手动绑定 active。图标尺寸随 flash 变化(22 / 20)。

VaxEmpty — 空状态

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | image | string | 'default' | vant 内置图片类型或图片 URL | | imageSize | number | — | 图片尺寸 | | description | string | t('empty.noData') | 描述文字;不传时走国际化 |

Slot default:底部操作区。

VaxLoading — 加载

| Prop | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | type | 'circular' \| 'spinner' | 'circular' | 动画类型 | | size | number | 48 | 尺寸 | | color | string | '#ccc' | 颜色 | | vertical | boolean | false | 文字与图标垂直排列 | | text | string | '' | 加载文案 | | fullscreen | boolean | false | 全屏遮罩(Teleport 到 body,z-index: 2000,半透明黑底) |

Slot default:覆盖 text

VaxField — 弹层编辑字段

点击整行弹出对应编辑层(对话框 / 日期选择 / 选择器),适合「详情页可编辑项」。

| Prop / Model | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | v-model | string \| number | — | 字段值 | | label | string | — | 左侧标签 | | icon | string | — | 左侧图标 | | type | 'text' \| 'date' \| 'select' | 'text' | 决定弹出哪种编辑层 | | readonly | boolean | false | 点击不响应 | | columns | { text: string; value: string }[] | [] | type='select' 的选项 |

  • type='select' 时行内显示 columns 中匹配的 textv-modelvalue
  • type='date' 确认后写入 YYYY-M-D 形式(selectedValues.join('-')月/日不补零)。
  • 日期选择器每次打开都以当天为初始值,不回显当前 v-model

VaxSelect — 选择器(单选 / 多选)

van-field + 底部弹出 van-picker(单选)或 van-checkbox-group(多选)。$attrs 透传给 van-fieldlabelplaceholderrequired 等)。

| Prop / Model | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | v-model | string \| number \| string[] \| number[] | — | 选中值 | | multiple | boolean | false | 多选模式 | | options | string[] | [] | 选项;是纯字符串数组,label 与 value 同值 |

多选时行内以 van-tag 展示,多选面板高度固定 264px 可滚动。

VaxCaptcha — 手机号 + 验证码

渲染两个 van-field(手机号、验证码)与「获取验证码」按钮,内置 60 秒倒计时与手机号格式校验。

| Prop / Model | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | v-model:phone | string | — | 必填,手机号 | | v-model:captcha | string | — | 必填,验证码 | | onSend | (data) => Promise<void> | — | 必填,发送接口 | | method | string | '' | 业务场景标识,原样带入 onSend | | label | boolean | false | 是否显示字段标签 | | whatsApp | boolean | false | 开启后先弹 van-action-sheet 选通道(WhatsApp / 短信) |

onSend 收到的参数:{ method, phone, channel }channel'sms''whatsapp'(默认 'sms')。

行为:点击 → Validate.phone() 校验(失败 toast message.phoneInvalid)→ 发送 → 成功后清空 captcha、toast message.otpSent、开始倒计时;失败 toast 后端 message

Validate 的手机号规则默认走国际格式。中国大陆项目需在入口调 Validate.set('CN')(从 @gindow/vue 导入)。

VaxAssetPreview — 资源预览

van-image-preview

| Prop / Model | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | v-model:show | boolean | false | 显示状态 | | asset | IAsset | {} | 初始定位到的资源(按 idassets 中查找) | | assets | IAsset[] | [] | 资源列表 |

展示的是 item.shrink ?? item.url缩略图优先)。加载失败时显示 file-question 图标 + 资源标题。


5. Hooks

useMessage()

vant 全局提示的薄封装,标题走国际化。

const { message, success, error, warning, dialog, confirm, loading } = useMessage()

| 方法 | 签名 | 底层 | | --- | --- | --- | | message | (msg, options?) | showToast | | success | (msg, options?) | showSuccessToast | | error | (msg, options?) | showFailToast | | warning | (msg, options?) | showFailToast(与 error 相同) | | dialog | (msg, title?, options?) | showDialog,标题默认 t('dialog.tip') | | confirm | (msg, title?, options?) | showConfirmDialog,标题默认 t('dialog.confirm'),返回 Promise | | loading | (options: string \| ToastOptions) | showLoadingToast |

useMessage 内部调用 useLocale(),需在 setup 上下文中使用。

useCaptcha(未从主入口导出)

VaxCaptcha 内部使用。需要单独用时从 @gindow/vue 导入同名 hook(实现一致)。


6. 类型定义

主入口只导出两个类型:

interface IModel {
  id?: string | any
  created_at?: string; updated_at?: string; deleted_at?: string
  [property: string]: any
}

interface IAsset extends IModel {
  id: string; type: string; title: string
  url: string      // 原图
  shrink: string   // 缩略图
}

其余通用类型(IField / IParams / IPagination / IResult / IMenu …)请从 @gindow/vue 导入。


7. 国际化

import { setLocale, getLocale, useLocale } from '@gindow/vant-go'
// 或只引 locale 入口,不拖入组件库:
import { setLocale } from '@gindow/vant-go/locale'

setLocale('en')
const { locale, t } = useLocale()
t('message.otpSent')
t('core.someKey', { name: 'Tom' })   // 支持 {name} 插值

初始语言:localStorage.localenavigator.language 完全匹配 → 语言族匹配 → 兜底 'en'

内置文案(zh-CN / en):

cancel · confirm
auth.phone · auth.otp · auth.enterPhone · auth.enterOTP · auth.getOTP
auth.viaWhatsApp · auth.viaPhone
message.otpSent · message.phoneInvalid
empty.noData
dialog.tip · dialog.confirm

扩展语言包:

app.use(VantGo, {
  locale: 'en-KE',
  messages: { 'en-KE': { ...业务文案 } },
})

内置文案有永不被覆盖的 base 底座t() 先查 app 的 messages[locale], 查不到再按语言族(zh*zh-CN,其余 → en-US)回落到包自带文案。 因此自定义 locale 码(en-KE / sw-KE)也能正常显示 Vax* 组件的内置文字, 业务 app 只需写自己的业务 key。

provider(opts?) 已用 getCurrentInstance() 守卫,可在 setup 之外安全调用。


8. 样式文件的选择

| 文件 | 内容 | 适用 | | --- | --- | --- | | @gindow/vant-go/styles/index.css | vant 本体 + @gindow/vue/style.css(含 Tailwind 与层声明)+ 皮肤,全部无层 | 没有自建 Tailwind 入口的 app,一行搞定 | | @gindow/vant-go/src/styles/style.css | 仅皮肤,无 vant 本体、无 Tailwind 链、无指令 | 需要把 vant 套进 @layer 的 app | | @gindow/vant-go/styles/arco.css · purple.css | 可选主题变量 | 按需追加 |

皮肤提供:.text-primary/success/warning/danger.bg-primary/....border-primary.portrait-only(仅竖屏)、.landscape-only(仅横屏),以及 body 基础字号/配色。 另有来自 @gindow/vue/style.css.flex-center*.mob.web 等,见 @gindow/vue README


9. 两种消费模式

exports@source 条件指向 src,默认条件指向 dist

源码包模式(submodule)

vite.config.tsresolve.conditions: ['@source'],并把 @gindow/* alias 到各自的 src。 组件源码由宿主 app 编译,宿主的 unplugin-auto-import 必须能覆盖到它们(computed / ref / useRoute 等靠自动导入注入)。

npm 包模式

不要开 resolve.conditions: ['@source'] —— 包的 src 依赖宿主的 AutoImport 注入, 而 AutoImport 默认不处理 node_modules,走 src 会直接 computed is not defined。 装成 npm 包就吃 dist(默认条件),组件已编译完毕。

样式要自己引,建议全部套进 layer(vendor)

/* app 的 src/style.css */
@layer theme, base, vendor, element-plus, components, utilities;   /* 与本包声明的是同一份 */

@import 'tailwindcss';
@import 'vant/lib/index.css' layer(vendor);                        /* vant 本体 */
@import '@gindow/vant-go/styles/index.css' layer(vendor);          /* Vax* 组件的抽取样式 */
@import '@gindow/vant-go/src/styles/style.css' layer(vendor);      /* 皮肤 */

并把解析器的 importStyle 关掉,避免它再按组件注入无层样式:

Components({ resolvers: [VantResolver({ importStyle: false }), VantGoResolver({ importStyle: false })] })

为什么必须分层:CSS 规范里无层样式永远赢过有层样式,与源码顺序、特异性无关。 Tailwind v4 把工具类放在 @layer utilities,vant 默认无层——不处理的话 <van-button class="mt-6">mt-6 会被静默吃掉,只能靠满屏 ! 去救。 本包的产物已经不再烘焙按组件样式,也在自己的 CSS 里声明了规范层顺序,正常情况下开箱即用。

主入口为什么不引样式:包入口带样式副作用会让「引一个组件」变成「引整条无层样式链」, 分层 app 的层序会被它先手定死(2026-08-10 实测教训)。因此 src/index.ts 刻意不 import 样式


10. 使用示例

<template>
  <VaxNavBar back left-arrow />

  <VaxPage>
    <VaxTabs v-model:active="tab" :tabs sticky />

    <!-- 数据驱动 -->
    <VaxCellGroup inset title="Send money" :items="channels"
      icon-color="var(--color-violet-600)" icon-background="var(--color-violet-50)" />

    <!-- 混合:自定义标题 + 自定义内容 -->
    <VaxCellGroup inset>
      <template #title>
        <div class="flex-center-between">
          <span>Recent</span>
          <span @click="go('transactions')">View all</span>
        </div>
      </template>
      <van-cell v-for="t in recent" :key="t.id" :title="t.party" center />
    </VaxCellGroup>

    <!-- 单行 -->
    <VaxCell icon="check" title="Approvals" :value="3" label="Tap to review" to="approvals" />

    <VaxButton :block="true" type="primary" icon="send" @click="submit">提交</VaxButton>
  </VaxPage>

  <VaxTabbar :menu />
</template>

<script setup lang="ts">
import { VaxCellGroup } from '@gindow/vant-go'

const tab = ref('all')
const tabs = [
  { name: 'all', label: '全部' },
  { name: 'pending', label: '待处理', badge: 3 },
]

const channels = [
  { icon: 'thunderbolt', title: 'Pesalink', label: 'Instant · 38 banks', to: 'transfer.new' },
  { icon: 'iphone', title: 'M-Pesa', label: 'Daraja API', to: 'transfer.new' },
]

const menu = [
  { icon: 'home', title: '首页', to: '/home' },
  { icon: 'user', title: '我的', to: '/profile', dot: true },
]
</script>

11. 开发

pnpm install
pnpm build       # vue-tsc --noEmit 类型检查 + vite 构建
pnpm pack        # 生成 tarball 用于发布前烟测

产物入口:@gindow/vant-go.{mjs,cjs}resolver.*locale.*styles/index.css。 external:vuevue-router@iconify/vue@gindow/vuevant/*

License

MIT © joming