@gindow/vant-go 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/env.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ declare module '*.vue' {
4
+ import type { DefineComponent } from 'vue'
5
+ const component: DefineComponent<{}, {}, any>
6
+ export default component
7
+ }
@@ -0,0 +1,27 @@
1
+ export const useCaptcha = (api: (data: any) => Promise<void>) => {
2
+
3
+ const waiting = ref(0)
4
+ const loading = ref(false)
5
+
6
+ const send = (para = {}) => {
7
+ return new Promise((resolve, reject) => {
8
+ if (loading.value) return
9
+ loading.value = true
10
+ api(para).then(() => {
11
+ timer()
12
+ resolve(true)
13
+ }).catch(err => reject(err))
14
+ .finally(() => loading.value = false)
15
+ })
16
+ }
17
+
18
+ const timer = () => {
19
+ waiting.value = 60
20
+ const time = setInterval(() => {
21
+ waiting.value--
22
+ if (!waiting.value) clearTimeout(time)
23
+ }, 1000)
24
+ }
25
+
26
+ return { waiting, send }
27
+ }
@@ -0,0 +1,19 @@
1
+ import { showToast, showSuccessToast, showFailToast, showDialog, showConfirmDialog, showLoadingToast, type ToastOptions } from 'vant'
2
+ import { useLocale } from '../locale'
3
+ // import 'vant/es/toast/style'
4
+ // import 'vant/es/dialog/style'
5
+ // import 'vant/es/notify/style'
6
+
7
+ export const useMessage = () => {
8
+ const { t } = useLocale()
9
+
10
+ const message = (message: string, options = {}) => showToast({ message, ...options })
11
+ const success = (message: string, options = {}) => showSuccessToast({ message, ...options })
12
+ const error = (message: string, options = {}) => showFailToast({ message, ...options })
13
+ const warning = (message: string, options = {}) => showFailToast({ message, ...options })
14
+ const dialog = (message: string, title?: string, options = {}) => showDialog({ message, title: title ?? t('dialog.tip'), ...options })
15
+ const confirm = (message: string, title?: string, options = {}) => showConfirmDialog({ message, title: title ?? t('dialog.confirm'), ...options })
16
+ const loading = (options: string | ToastOptions) => showLoadingToast(options)
17
+
18
+ return { message, success, error, warning, dialog, confirm, loading }
19
+ }
package/src/index.ts ADDED
@@ -0,0 +1,73 @@
1
+ import type { App, Plugin } from 'vue'
2
+ import { provider, setLocale, getLocale, useLocale } from './locale'
3
+ import VaxAssetPreview from './components/VaxAssetPreview.vue'
4
+ import VaxAvatar from './components/VaxAvatar.vue'
5
+ import VaxButton from './components/VaxButton.vue'
6
+ import VaxCaptcha from './components/VaxCaptcha.vue'
7
+ import VaxCell from './components/VaxCell.vue'
8
+ import VaxCellGroup from './components/VaxCellGroup.vue'
9
+ import VaxEmpty from './components/VaxEmpty.vue'
10
+ import VaxField from './components/VaxField.vue'
11
+ import VaxIcon from './components/VaxIcon.vue'
12
+ import VaxLoading from './components/VaxLoading.vue'
13
+ import VaxNavBar from './components/VaxNavBar.vue'
14
+ import VaxPage from './components/VaxPage.vue'
15
+ import VaxSelect from './components/VaxSelect.vue'
16
+ import VaxTabbar from './components/VaxTabbar.vue'
17
+ import VaxTabs from './components/VaxTabs.vue'
18
+
19
+ const components = [
20
+ VaxAssetPreview,
21
+ VaxAvatar,
22
+ VaxButton,
23
+ VaxCaptcha,
24
+ VaxCell,
25
+ VaxCellGroup,
26
+ VaxEmpty,
27
+ VaxField,
28
+ VaxIcon,
29
+ VaxLoading,
30
+ VaxNavBar,
31
+ VaxPage,
32
+ VaxSelect,
33
+ VaxTabbar,
34
+ VaxTabs,
35
+ ]
36
+
37
+ components.forEach((c) => {
38
+ ;(c as unknown as Plugin).install = (app: App) => {
39
+ const name =
40
+ (c as { name?: string }).name ?? (c as { __name?: string }).__name
41
+ if (name) app.component(name, c)
42
+ }
43
+ })
44
+
45
+ const VantGo: Plugin = {
46
+ install(app, options?: { locale?: string; messages?: Record<string, any> }) {
47
+ provider(options)
48
+ components.forEach((c) => app.use(c as unknown as Plugin))
49
+ },
50
+ }
51
+
52
+ export default VantGo
53
+ export {
54
+ VaxAssetPreview,
55
+ VaxAvatar,
56
+ VaxButton,
57
+ VaxCaptcha,
58
+ VaxCell,
59
+ VaxCellGroup,
60
+ VaxEmpty,
61
+ VaxField,
62
+ VaxIcon,
63
+ VaxLoading,
64
+ VaxNavBar,
65
+ VaxPage,
66
+ VaxSelect,
67
+ VaxTabbar,
68
+ VaxTabs,
69
+ provider,
70
+ setLocale,
71
+ getLocale,
72
+ useLocale,
73
+ }
@@ -0,0 +1,84 @@
1
+ /* eslint-disable */
2
+ /* prettier-ignore */
3
+ // @ts-nocheck
4
+ // noinspection JSUnusedGlobalSymbols
5
+ // Generated by unplugin-auto-import
6
+ // biome-ignore lint: disable
7
+ export {}
8
+ declare global {
9
+ const EffectScope: typeof import('vue').EffectScope
10
+ const Validate: typeof import('../utils/validate').Validate
11
+ const computed: typeof import('vue').computed
12
+ const createApp: typeof import('vue').createApp
13
+ const customRef: typeof import('vue').customRef
14
+ const defineAsyncComponent: typeof import('vue').defineAsyncComponent
15
+ const defineComponent: typeof import('vue').defineComponent
16
+ const effectScope: typeof import('vue').effectScope
17
+ const getCurrentInstance: typeof import('vue').getCurrentInstance
18
+ const getCurrentScope: typeof import('vue').getCurrentScope
19
+ const getCurrentWatcher: typeof import('vue').getCurrentWatcher
20
+ const h: typeof import('vue').h
21
+ const inject: typeof import('vue').inject
22
+ const isProxy: typeof import('vue').isProxy
23
+ const isReactive: typeof import('vue').isReactive
24
+ const isReadonly: typeof import('vue').isReadonly
25
+ const isRef: typeof import('vue').isRef
26
+ const isShallow: typeof import('vue').isShallow
27
+ const markRaw: typeof import('vue').markRaw
28
+ const nextTick: typeof import('vue').nextTick
29
+ const onActivated: typeof import('vue').onActivated
30
+ const onBeforeMount: typeof import('vue').onBeforeMount
31
+ const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
32
+ const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
33
+ const onBeforeUnmount: typeof import('vue').onBeforeUnmount
34
+ const onBeforeUpdate: typeof import('vue').onBeforeUpdate
35
+ const onDeactivated: typeof import('vue').onDeactivated
36
+ const onErrorCaptured: typeof import('vue').onErrorCaptured
37
+ const onMounted: typeof import('vue').onMounted
38
+ const onRenderTracked: typeof import('vue').onRenderTracked
39
+ const onRenderTriggered: typeof import('vue').onRenderTriggered
40
+ const onScopeDispose: typeof import('vue').onScopeDispose
41
+ const onServerPrefetch: typeof import('vue').onServerPrefetch
42
+ const onUnmounted: typeof import('vue').onUnmounted
43
+ const onUpdated: typeof import('vue').onUpdated
44
+ const onWatcherCleanup: typeof import('vue').onWatcherCleanup
45
+ const provide: typeof import('vue').provide
46
+ const reactive: typeof import('vue').reactive
47
+ const readonly: typeof import('vue').readonly
48
+ const ref: typeof import('vue').ref
49
+ const resolveComponent: typeof import('vue').resolveComponent
50
+ const shallowReactive: typeof import('vue').shallowReactive
51
+ const shallowReadonly: typeof import('vue').shallowReadonly
52
+ const shallowRef: typeof import('vue').shallowRef
53
+ const toRaw: typeof import('vue').toRaw
54
+ const toRef: typeof import('vue').toRef
55
+ const toRefs: typeof import('vue').toRefs
56
+ const toValue: typeof import('vue').toValue
57
+ const triggerRef: typeof import('vue').triggerRef
58
+ const unref: typeof import('vue').unref
59
+ const useAttrs: typeof import('vue').useAttrs
60
+ const useCaptcha: typeof import('../hooks/useCaptcha').useCaptcha
61
+ const useCssModule: typeof import('vue').useCssModule
62
+ const useCssVars: typeof import('vue').useCssVars
63
+ const useId: typeof import('vue').useId
64
+ const useLink: typeof import('vue-router').useLink
65
+ const useMessage: typeof import('../hooks/useMessage').useMessage
66
+ const useModel: typeof import('vue').useModel
67
+ const useRoute: typeof import('vue-router').useRoute
68
+ const useRouter: typeof import('vue-router').useRouter
69
+ const useSlots: typeof import('vue').useSlots
70
+ const useTemplateRef: typeof import('vue').useTemplateRef
71
+ const watch: typeof import('vue').watch
72
+ const watchEffect: typeof import('vue').watchEffect
73
+ const watchPostEffect: typeof import('vue').watchPostEffect
74
+ const watchSyncEffect: typeof import('vue').watchSyncEffect
75
+ }
76
+ // for type re-export
77
+ declare global {
78
+ // @ts-ignore
79
+ export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
80
+ import('vue')
81
+ // @ts-ignore
82
+ export type { Validate } from '../utils/validate'
83
+ import('../utils/validate')
84
+ }
@@ -0,0 +1,51 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ // biome-ignore lint: disable
4
+ // oxlint-disable
5
+ // ------
6
+ // Generated by unplugin-vue-components
7
+ // Read more: https://github.com/vuejs/core/pull/3399
8
+
9
+ export {}
10
+
11
+ /* prettier-ignore */
12
+ declare module 'vue' {
13
+ export interface GlobalComponents {
14
+ RouterLink: typeof import('vue-router')['RouterLink']
15
+ RouterView: typeof import('vue-router')['RouterView']
16
+ VanActionSheet: typeof import('vant/es')['ActionSheet']
17
+ VanBadge: typeof import('vant/es')['Badge']
18
+ VanButton: typeof import('vant/es')['Button']
19
+ VanCell: typeof import('vant/es')['Cell']
20
+ VanCellGroup: typeof import('vant/es')['CellGroup']
21
+ VanCheckbox: typeof import('vant/es')['Checkbox']
22
+ VanCheckboxGroup: typeof import('vant/es')['CheckboxGroup']
23
+ VanDatePicker: typeof import('vant/es')['DatePicker']
24
+ VanDialog: typeof import('vant/es')['Dialog']
25
+ VanEmpty: typeof import('vant/es')['Empty']
26
+ VanField: typeof import('vant/es')['Field']
27
+ VanImage: typeof import('vant/es')['Image']
28
+ VanImagePreview: typeof import('vant/es')['ImagePreview']
29
+ VanLoading: typeof import('vant/es')['Loading']
30
+ VanNavBar: typeof import('vant/es')['NavBar']
31
+ VanPicker: typeof import('vant/es')['Picker']
32
+ VanPopup: typeof import('vant/es')['Popup']
33
+ VanSpace: typeof import('vant/es')['Space']
34
+ VanTag: typeof import('vant/es')['Tag']
35
+ VaxAssetPreview: typeof import('./../components/VaxAssetPreview.vue')['default']
36
+ VaxAvatar: typeof import('./../components/VaxAvatar.vue')['default']
37
+ VaxButton: typeof import('./../components/VaxButton.vue')['default']
38
+ VaxCaptcha: typeof import('./../components/VaxCaptcha.vue')['default']
39
+ VaxCell: typeof import('./../components/VaxCell.vue')['default']
40
+ VaxCellGroup: typeof import('./../components/VaxCellGroup.vue')['default']
41
+ VaxEmpty: typeof import('./../components/VaxEmpty.vue')['default']
42
+ VaxField: typeof import('./../components/VaxField.vue')['default']
43
+ VaxIcon: typeof import('./../components/VaxIcon.vue')['default']
44
+ VaxLoading: typeof import('./../components/VaxLoading.vue')['default']
45
+ VaxNavBar: typeof import('./../components/VaxNavBar.vue')['default']
46
+ VaxPage: typeof import('./../components/VaxPage.vue')['default']
47
+ VaxSelect: typeof import('./../components/VaxSelect.vue')['default']
48
+ VaxTabbar: typeof import('./../components/VaxTabbar.vue')['default']
49
+ VaxTabs: typeof import('./../components/VaxTabs.vue')['default']
50
+ }
51
+ }
@@ -0,0 +1,24 @@
1
+ export default {
2
+ cancel: 'Cancel',
3
+ confirm: 'Confirm',
4
+ auth: {
5
+ phone: 'Phone',
6
+ otp: 'OTP',
7
+ enterPhone: 'Enter Phone Number',
8
+ enterOTP: 'Enter OTP',
9
+ getOTP: 'Get OTP',
10
+ viaWhatsApp: 'Via WhatsApp',
11
+ viaPhone: 'Via SMS',
12
+ },
13
+ message: {
14
+ otpSent: 'OTP sent',
15
+ phoneInvalid: 'Invalid phone number',
16
+ },
17
+ empty: {
18
+ noData: 'No data',
19
+ },
20
+ dialog: {
21
+ tip: 'Tip',
22
+ confirm: 'Confirm',
23
+ },
24
+ }
@@ -0,0 +1,65 @@
1
+ import { getCurrentInstance, inject, provide, reactive, ref } from 'vue'
2
+ import zhCN from './zh-CN'
3
+ import enUS from './en-US'
4
+
5
+ type Messages = Record<string, any>
6
+
7
+ const getStoredLocale = (): string => {
8
+ const availableCodes = ['en', 'zh-CN']
9
+ const storageLocale = localStorage.getItem('locale')
10
+ const browserLocale = navigator.language
11
+ if (storageLocale && availableCodes.includes(storageLocale)) return storageLocale
12
+ else if (browserLocale && availableCodes.includes(browserLocale as string)) return browserLocale as string // 完全匹配
13
+ else if (browserLocale && availableCodes.includes(browserLocale.split('-')[0] as string)) return browserLocale.split('-')[0] as string // 部分匹配
14
+ else return availableCodes[0] ?? 'zh-CN' // 未匹配
15
+ }
16
+
17
+ const LOCALE_INJECTION_KEY = Symbol('vant-go-locale')
18
+ const locale = ref<string>(getStoredLocale())
19
+
20
+ // Vant Go 自带语言底座
21
+ const base: Messages = { 'en': enUS, 'en-US': enUS, 'zh-CN': zhCN }
22
+ const messages: Messages = reactive({ 'en': enUS, 'zh-CN': zhCN })
23
+
24
+ const fallbackCode = (code: string): string => (code.toLowerCase().startsWith('zh') ? 'zh-CN' : 'en-US')
25
+
26
+ const deepGet = (obj: Messages | undefined, keys: string[]): unknown => {
27
+ let result: any = obj
28
+ for (const key of keys) {
29
+ result = result?.[key]
30
+ if (result === undefined) return undefined
31
+ }
32
+ return result
33
+ }
34
+
35
+ export const provider = (opts?: { locale?: string; messages?: Messages }) => {
36
+ if (opts?.locale) locale.value = opts.locale
37
+ if (opts?.messages) {
38
+ for (const [key, value] of Object.entries(opts.messages)) {
39
+ messages[key] = value
40
+ }
41
+ }
42
+ if (getCurrentInstance()) provide(LOCALE_INJECTION_KEY, { locale, messages })
43
+ return { locale, messages }
44
+ }
45
+
46
+ export const useLocale = () => {
47
+ const injected = inject<{ locale: typeof locale; messages: typeof messages } | undefined>(LOCALE_INJECTION_KEY, undefined)
48
+ const currentLocale = injected?.locale ?? locale
49
+ const currentMessages = injected?.messages ?? messages
50
+
51
+ const t = (path: string, params?: Record<string, string | number>): string => {
52
+ const keys = path.replace(/\[(\d+)]/g, '.$1').split('.')
53
+ let result = deepGet(currentMessages[currentLocale.value], keys)
54
+ if (result === undefined) result = deepGet(base[fallbackCode(currentLocale.value)], keys)
55
+ let text = (result ?? path) as string
56
+ if (params && typeof text === 'string') text = text.replace(/\{(\w+)\}/g, (_, k) => params[k] !== undefined ? String(params[k]) : `{${k}}`)
57
+ return text
58
+ }
59
+
60
+ return { locale: currentLocale, t }
61
+ }
62
+
63
+ export const setLocale = (lang: string) => locale.value = lang
64
+
65
+ export const getLocale = () => locale.value
@@ -0,0 +1,24 @@
1
+ export default {
2
+ cancel: '取消',
3
+ confirm: '确认',
4
+ auth: {
5
+ phone: '手机号',
6
+ otp: '验证码',
7
+ enterPhone: '请输入手机号',
8
+ enterOTP: '请输入验证码',
9
+ getOTP: '获取验证码',
10
+ viaWhatsApp: '通过WhatsApp发送',
11
+ viaPhone: '通过短信发送',
12
+ },
13
+ message: {
14
+ otpSent: '验证码已发送',
15
+ phoneInvalid: '手机号格式不正确',
16
+ },
17
+ empty: {
18
+ noData: '暂无数据',
19
+ },
20
+ dialog: {
21
+ tip: '操作提示',
22
+ confirm: '操作确认',
23
+ },
24
+ }
@@ -0,0 +1,26 @@
1
+ export interface VantGoResolverOptions {
2
+ /**
3
+ * 是否自动导入 vant-go 的聚合样式文件。
4
+ * 默认 true:每次解析到 Vax* 组件时附带 `vant-go/style.css` 副作用导入
5
+ * (unplugin-vue-components 会去重,不会重复打包)。
6
+ * 设为 false 时需在应用入口手动 `import 'vant-go/style.css'`。
7
+ */
8
+ importStyle?: boolean
9
+ /** 自定义前缀,默认 'Vax' */
10
+ prefix?: string
11
+ }
12
+
13
+ export function VantGoResolver(options: VantGoResolverOptions = {}) {
14
+ const { importStyle = true, prefix = 'Vax' } = options
15
+ return {
16
+ type: 'component' as const,
17
+ resolve(name: string) {
18
+ if (!name.startsWith(prefix)) return
19
+ return {
20
+ name,
21
+ from: 'vant-go',
22
+ sideEffects: importStyle ? 'vant-go/style.css' : undefined,
23
+ }
24
+ },
25
+ }
26
+ }
package/src/style.css ADDED
@@ -0,0 +1,46 @@
1
+ @import "@gindow/vue/style.css";
2
+
3
+ body {
4
+ font-size: var(--van-font-size-md);
5
+ color: var(--van-text-color);
6
+ background-color: var(--van-background);
7
+ }
8
+
9
+ /** 公共样式 */
10
+ .bg-primary { background-color: var(--van-primary-color); }
11
+ .text-primary { color: var(--van-primary-color); }
12
+ .text-success { color: var(--van-success-color); }
13
+ .text-warning { color: var(--van-warning-color); }
14
+ .text-danger { color: var(--van-danger-color); }
15
+ .border-primary { border-color: var(--van-primary-color); }
16
+
17
+ /* Layout */
18
+ .buttons { padding: var(--van-padding-xl); }
19
+ .buttons > .van-button + .van-button { margin-top: var(--van-padding-md); }
20
+ .van-field .captcha { float: right; background: transparent; color: var(--van-primary-color); border: 0; padding: 0 5px; min-width: 45px; height: 24px; }
21
+ .van-field .captcha .van-button--disabled { color: #ccc; }
22
+
23
+ /** 菜单样式 */
24
+ .van-cell-group.menu { border: 1px solid var(--van-gray-2); }
25
+ .van-cell-group.menu .van-cell { --van-switch-size: 20px; }
26
+ .van-cell-group.menu .van-cell > .i-icon { margin-right: var(--van-padding-md); }
27
+ .van-cell-group--inset + .van-cell-group--inset { margin-top: var(--van-padding-md); }
28
+ .van-cell-group__title {
29
+ padding: var(--van-padding-md) var(--van-padding-md) var(--van-padding-xs) !important;
30
+ font-size: var(--van-font-size-sm) !important;
31
+ font-weight: 500;
32
+ letter-spacing: 0.05em;
33
+ text-transform: uppercase;
34
+ }
35
+
36
+ /* Toast */
37
+ .van-toast { word-break: break-word !important; }
38
+
39
+ /* Form */
40
+ .van-field--label-top .van-field__label .van-field__required { color: var(--van-danger-color); }
41
+ .van-field--label-top .van-field__label {
42
+ font-size: 11px;
43
+ color: var(--van-primary-color);
44
+ text-transform: uppercase;
45
+ font-weight: 500;
46
+ }
@@ -0,0 +1,15 @@
1
+ export interface IModel {
2
+ id?: string | any
3
+ created_at?: string
4
+ updated_at?: string
5
+ deleted_at?: string
6
+ [property: string]: any
7
+ }
8
+
9
+ export interface IAsset extends IModel {
10
+ id: string
11
+ type: string
12
+ title: string
13
+ url: string
14
+ shrink: string
15
+ }
@@ -0,0 +1,23 @@
1
+ export class Validate {
2
+
3
+ static country: string = '' // 国家
4
+
5
+ static set = (country: string) => this.country = country
6
+
7
+ static get phone_pattern () {
8
+ return this.country.toUpperCase() === 'CN'
9
+ ? /([1][3,4,5,6,7,8,9][0-9]{9})$/
10
+ : /^(?:\+?[1-9]\d{7,14}|\d{6,11})$/
11
+ }
12
+
13
+ static email_pattern = /^([a-zA-Z0-9_\.-]+)@([\da-zA-Z\.-]+)\.([a-zA-Z\.]{2,6})$/
14
+ static idcard_pattern = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
15
+ static cname_pattern = /^(?:[\u4e00-\u9fa5·]{2,16})$/
16
+ static password_pattern = /^(?![A-Za-z]+$)(?![0-9]+$)(?![^A-Za-z0-9]+$).{8,20}$/
17
+
18
+ // 校验方法
19
+ static phone = (str: string) => Validate.phone_pattern.test(str)
20
+ static email = (str: string) => Validate.email_pattern.test(str)
21
+ static idcard = (str: string) => Validate.idcard_pattern.test(str)
22
+ static cname = (str: string) => Validate.cname_pattern.test(str)
23
+ }