wui-components-v2 1.1.69 → 1.1.70
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/api/core/index.ts +74 -74
- package/api/menu.ts +45 -45
- package/api/page.ts +114 -114
- package/api/sys.ts +12 -12
- package/components/add-address-page/add-address-page.vue +77 -77
- package/components/custom-date-picker/custom-date-picker.vue +106 -106
- package/components/custom-select-picker/custom-select-picker.vue +95 -95
- package/components/demo-block/demo-block.vue +63 -63
- package/components/detail-popup/detail-popup.vue +99 -99
- package/components/evaluation-page/evaluation-page.vue +196 -196
- package/components/fold-card/fold-card.vue +171 -171
- package/components/form-control/form-control.vue +661 -661
- package/components/global-message/global-message.vue +68 -68
- package/components/label-value/label-value.vue +144 -144
- package/components/list-top-buttons/list-top-buttons.vue +19 -19
- package/components/login-form/login-form.vue +126 -126
- package/components/mulselect-picker/mulselect-picker.vue +86 -86
- package/components/product-card/product-card.vue +201 -201
- package/components/search/search.vue +128 -128
- package/components/user-choose/user-choose.vue +1 -1
- package/components/wui-enume-select-control/wui-enume-select-control.vue +92 -92
- package/components/wui-list/wui-list.vue +235 -235
- package/components/wui-menus/wui-menus.vue +247 -247
- package/components/wui-menus1/components/navbar.vue +43 -43
- package/components/wui-menus1/wui-menus.vue +564 -564
- package/components/wui-notify-info/wui-notify-info.vue +280 -280
- package/components/wui-search-history-babbar/wui-search-history-babbar.vue +204 -204
- package/components/wui-select-list/wui-select-list.vue +310 -310
- package/components/wui-select-popup/wui-select-popup.vue +612 -612
- package/components/wui-system-settings/wui-system-settings.vue +144 -144
- package/components/wui-tabbar/wui-tabbar.vue +106 -106
- package/components/wui-tree-page/components/tree-item.vue +238 -238
- package/components/wui-user/wui-user.vue +202 -202
- package/composables/useCompanyFieldFilter.ts +91 -91
- package/composables/useEnumes.ts +2 -2
- package/composables/useMenus.ts +193 -193
- package/index.ts +83 -83
- package/package.json +1 -1
- package/static/iconfont/iconfont.css +63 -63
- package/store/language.ts +151 -151
- package/styles/dark-mode.css +523 -523
- package/styles/dark-mode.min.css +1 -1
- package/type.ts +2 -2
- package/utils/control-tree.ts +2 -2
- package/utils/control-type-supportor.ts +148 -148
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, defineOptions } from 'vue'
|
|
3
|
-
import { useManualTheme } from '../../composables/useManualTheme'
|
|
4
|
-
import { useLanguageStore } from '../../store/language'
|
|
5
|
-
import type { LocaleOption, ThemeColorOption } from '../../composables/useManualTheme'
|
|
6
|
-
import demoBlock from '../demo-block/demo-block.vue'
|
|
7
|
-
|
|
8
|
-
defineOptions({
|
|
9
|
-
name: 'WuiSystemSettings',
|
|
10
|
-
})
|
|
11
|
-
const {
|
|
12
|
-
theme,
|
|
13
|
-
toggleTheme,
|
|
14
|
-
currentThemeColor,
|
|
15
|
-
showThemeColorSheet,
|
|
16
|
-
themeColorOptions,
|
|
17
|
-
openThemeColorPicker,
|
|
18
|
-
closeThemeColorPicker,
|
|
19
|
-
selectThemeColor,
|
|
20
|
-
LocaleOptions,
|
|
21
|
-
primary,
|
|
22
|
-
currentLocale,
|
|
23
|
-
showLanguageSheet,
|
|
24
|
-
openLanguagePicker,
|
|
25
|
-
closeLanguagePicker,
|
|
26
|
-
selectLanguage,
|
|
27
|
-
} = useManualTheme()
|
|
28
|
-
|
|
29
|
-
const languageStore = useLanguageStore()
|
|
30
|
-
|
|
31
|
-
const isDark = computed({
|
|
32
|
-
get() {
|
|
33
|
-
return theme.value === 'dark'
|
|
34
|
-
},
|
|
35
|
-
set() {
|
|
36
|
-
toggleTheme()
|
|
37
|
-
},
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
// Cell / CellGroup 暗黑内联样式
|
|
41
|
-
const settingsCellStyle = computed(() => ({
|
|
42
|
-
backgroundColor: isDark.value ? '#161616' : '#fff',
|
|
43
|
-
borderBottom: isDark.value ? '1px solid rgba(255,255,255,0.04)' : 'none',
|
|
44
|
-
}))
|
|
45
|
-
|
|
46
|
-
const settingsGroupStyle = computed(() => ({
|
|
47
|
-
backgroundColor: isDark.value ? '#111111' : 'transparent',
|
|
48
|
-
borderRadius: isDark.value ? '10px' : '0',
|
|
49
|
-
}))
|
|
50
|
-
// 处理主题色选择
|
|
51
|
-
function handleThemeColorSelect(option: ThemeColorOption) {
|
|
52
|
-
selectThemeColor(option)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 处理语言选择
|
|
56
|
-
function handleLanguageSelect(option: LocaleOption) {
|
|
57
|
-
selectLanguage(option)
|
|
58
|
-
}
|
|
59
|
-
</script>
|
|
60
|
-
|
|
61
|
-
<template>
|
|
62
|
-
<view class="settings-page" :style="{ backgroundColor: isDark ? '#1B1B1E' : '#F8F9FB' }">
|
|
63
|
-
<demo-block :title="languageStore.t('系统设置')" transparent>
|
|
64
|
-
<wd-cell-group border custom-class="rounded-2! overflow-hidden" :custom-style="settingsGroupStyle">
|
|
65
|
-
<wd-cell :title="languageStore.t('暗黑模式')" :custom-style="settingsCellStyle">
|
|
66
|
-
<wd-switch v-model="isDark" size="18px" />
|
|
67
|
-
</wd-cell>
|
|
68
|
-
<wd-cell
|
|
69
|
-
:title="languageStore.t('选择主题色')"
|
|
70
|
-
is-link
|
|
71
|
-
@click="openThemeColorPicker"
|
|
72
|
-
:custom-style="settingsCellStyle"
|
|
73
|
-
>
|
|
74
|
-
<view class="flex items-center justify-end gap-2">
|
|
75
|
-
<view class="h-4 w-4 rounded-full" :style="{ backgroundColor: currentThemeColor.primary }" />
|
|
76
|
-
<text :style="{ color: isDark ? '#e8e8e8' : '#333' }">{{ currentThemeColor.name }}</text>
|
|
77
|
-
</view>
|
|
78
|
-
</wd-cell>
|
|
79
|
-
<wd-cell
|
|
80
|
-
:title="languageStore.t('选择语言')"
|
|
81
|
-
is-link
|
|
82
|
-
@click="openLanguagePicker"
|
|
83
|
-
:custom-style="settingsCellStyle"
|
|
84
|
-
>
|
|
85
|
-
<view class="flex items-center justify-end gap-2">
|
|
86
|
-
<text :style="{ color: isDark ? '#e8e8e8' : '#333' }">{{ currentLocale.name }}</text>
|
|
87
|
-
</view>
|
|
88
|
-
</wd-cell>
|
|
89
|
-
</wd-cell-group>
|
|
90
|
-
</demo-block>
|
|
91
|
-
<!-- 主题色选择 ActionSheet -->
|
|
92
|
-
<wd-action-sheet
|
|
93
|
-
v-model="showThemeColorSheet"
|
|
94
|
-
:title="languageStore.t('选择主题色')"
|
|
95
|
-
:close-on-click-action="true"
|
|
96
|
-
@cancel="closeThemeColorPicker"
|
|
97
|
-
>
|
|
98
|
-
<view class="px-4 pb-4">
|
|
99
|
-
<view
|
|
100
|
-
v-for="option in themeColorOptions"
|
|
101
|
-
:key="option.value"
|
|
102
|
-
class="flex items-center justify-between border-b border-gray-100 py-3 last:border-b-0 dark:border-gray-700"
|
|
103
|
-
@click="handleThemeColorSelect(option)"
|
|
104
|
-
>
|
|
105
|
-
<view class="flex items-center gap-3">
|
|
106
|
-
<view
|
|
107
|
-
class="h-6 w-6 border-2 border-gray-200 rounded-full dark:border-gray-600"
|
|
108
|
-
:style="{ backgroundColor: option.primary }"
|
|
109
|
-
/>
|
|
110
|
-
<text class="text-4 text-gray-800 dark:text-gray-200">
|
|
111
|
-
{{ option.name }}
|
|
112
|
-
</text>
|
|
113
|
-
</view>
|
|
114
|
-
<wd-icon v-if="currentThemeColor.value === option.value" name="check" :color="option.primary" size="20px" />
|
|
115
|
-
</view>
|
|
116
|
-
</view>
|
|
117
|
-
<wd-gap :height="50" />
|
|
118
|
-
</wd-action-sheet>
|
|
119
|
-
<!-- 语言选择选择 ActionSheet -->
|
|
120
|
-
<wd-action-sheet
|
|
121
|
-
v-model="showLanguageSheet"
|
|
122
|
-
:title="languageStore.t('选择语言')"
|
|
123
|
-
:close-on-click-action="true"
|
|
124
|
-
@cancel="closeLanguagePicker"
|
|
125
|
-
>
|
|
126
|
-
<view class="px-4 pb-4">
|
|
127
|
-
<view
|
|
128
|
-
v-for="option in LocaleOptions"
|
|
129
|
-
:key="option.value"
|
|
130
|
-
class="flex items-center justify-between border-b border-gray-100 py-3 last:border-b-0 dark:border-gray-700"
|
|
131
|
-
@click="handleLanguageSelect(option)"
|
|
132
|
-
>
|
|
133
|
-
<view class="flex items-center gap-3">
|
|
134
|
-
<text class="text-4 text-gray-800 dark:text-gray-200">
|
|
135
|
-
{{ option.name }}
|
|
136
|
-
</text>
|
|
137
|
-
</view>
|
|
138
|
-
<wd-icon v-if="currentLocale.value === option.value" name="check" :color="primary" size="20px" />
|
|
139
|
-
</view>
|
|
140
|
-
</view>
|
|
141
|
-
<wd-gap :height="50" />
|
|
142
|
-
</wd-action-sheet>
|
|
143
|
-
</view>
|
|
144
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, defineOptions } from 'vue'
|
|
3
|
+
import { useManualTheme } from '../../composables/useManualTheme'
|
|
4
|
+
import { useLanguageStore } from '../../store/language'
|
|
5
|
+
import type { LocaleOption, ThemeColorOption } from '../../composables/useManualTheme'
|
|
6
|
+
import demoBlock from '../demo-block/demo-block.vue'
|
|
7
|
+
|
|
8
|
+
defineOptions({
|
|
9
|
+
name: 'WuiSystemSettings',
|
|
10
|
+
})
|
|
11
|
+
const {
|
|
12
|
+
theme,
|
|
13
|
+
toggleTheme,
|
|
14
|
+
currentThemeColor,
|
|
15
|
+
showThemeColorSheet,
|
|
16
|
+
themeColorOptions,
|
|
17
|
+
openThemeColorPicker,
|
|
18
|
+
closeThemeColorPicker,
|
|
19
|
+
selectThemeColor,
|
|
20
|
+
LocaleOptions,
|
|
21
|
+
primary,
|
|
22
|
+
currentLocale,
|
|
23
|
+
showLanguageSheet,
|
|
24
|
+
openLanguagePicker,
|
|
25
|
+
closeLanguagePicker,
|
|
26
|
+
selectLanguage,
|
|
27
|
+
} = useManualTheme()
|
|
28
|
+
|
|
29
|
+
const languageStore = useLanguageStore()
|
|
30
|
+
|
|
31
|
+
const isDark = computed({
|
|
32
|
+
get() {
|
|
33
|
+
return theme.value === 'dark'
|
|
34
|
+
},
|
|
35
|
+
set() {
|
|
36
|
+
toggleTheme()
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// Cell / CellGroup 暗黑内联样式
|
|
41
|
+
const settingsCellStyle = computed(() => ({
|
|
42
|
+
backgroundColor: isDark.value ? '#161616' : '#fff',
|
|
43
|
+
borderBottom: isDark.value ? '1px solid rgba(255,255,255,0.04)' : 'none',
|
|
44
|
+
}))
|
|
45
|
+
|
|
46
|
+
const settingsGroupStyle = computed(() => ({
|
|
47
|
+
backgroundColor: isDark.value ? '#111111' : 'transparent',
|
|
48
|
+
borderRadius: isDark.value ? '10px' : '0',
|
|
49
|
+
}))
|
|
50
|
+
// 处理主题色选择
|
|
51
|
+
function handleThemeColorSelect(option: ThemeColorOption) {
|
|
52
|
+
selectThemeColor(option)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 处理语言选择
|
|
56
|
+
function handleLanguageSelect(option: LocaleOption) {
|
|
57
|
+
selectLanguage(option)
|
|
58
|
+
}
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<template>
|
|
62
|
+
<view class="settings-page" :style="{ backgroundColor: isDark ? '#1B1B1E' : '#F8F9FB' }">
|
|
63
|
+
<demo-block :title="languageStore.t('系统设置')" transparent>
|
|
64
|
+
<wd-cell-group border custom-class="rounded-2! overflow-hidden" :custom-style="settingsGroupStyle">
|
|
65
|
+
<wd-cell :title="languageStore.t('暗黑模式')" :custom-style="settingsCellStyle">
|
|
66
|
+
<wd-switch v-model="isDark" size="18px" />
|
|
67
|
+
</wd-cell>
|
|
68
|
+
<wd-cell
|
|
69
|
+
:title="languageStore.t('选择主题色')"
|
|
70
|
+
is-link
|
|
71
|
+
@click="openThemeColorPicker"
|
|
72
|
+
:custom-style="settingsCellStyle"
|
|
73
|
+
>
|
|
74
|
+
<view class="flex items-center justify-end gap-2">
|
|
75
|
+
<view class="h-4 w-4 rounded-full" :style="{ backgroundColor: currentThemeColor.primary }" />
|
|
76
|
+
<text :style="{ color: isDark ? '#e8e8e8' : '#333' }">{{ currentThemeColor.name }}</text>
|
|
77
|
+
</view>
|
|
78
|
+
</wd-cell>
|
|
79
|
+
<wd-cell
|
|
80
|
+
:title="languageStore.t('选择语言')"
|
|
81
|
+
is-link
|
|
82
|
+
@click="openLanguagePicker"
|
|
83
|
+
:custom-style="settingsCellStyle"
|
|
84
|
+
>
|
|
85
|
+
<view class="flex items-center justify-end gap-2">
|
|
86
|
+
<text :style="{ color: isDark ? '#e8e8e8' : '#333' }">{{ currentLocale.name }}</text>
|
|
87
|
+
</view>
|
|
88
|
+
</wd-cell>
|
|
89
|
+
</wd-cell-group>
|
|
90
|
+
</demo-block>
|
|
91
|
+
<!-- 主题色选择 ActionSheet -->
|
|
92
|
+
<wd-action-sheet
|
|
93
|
+
v-model="showThemeColorSheet"
|
|
94
|
+
:title="languageStore.t('选择主题色')"
|
|
95
|
+
:close-on-click-action="true"
|
|
96
|
+
@cancel="closeThemeColorPicker"
|
|
97
|
+
>
|
|
98
|
+
<view class="px-4 pb-4">
|
|
99
|
+
<view
|
|
100
|
+
v-for="option in themeColorOptions"
|
|
101
|
+
:key="option.value"
|
|
102
|
+
class="flex items-center justify-between border-b border-gray-100 py-3 last:border-b-0 dark:border-gray-700"
|
|
103
|
+
@click="handleThemeColorSelect(option)"
|
|
104
|
+
>
|
|
105
|
+
<view class="flex items-center gap-3">
|
|
106
|
+
<view
|
|
107
|
+
class="h-6 w-6 border-2 border-gray-200 rounded-full dark:border-gray-600"
|
|
108
|
+
:style="{ backgroundColor: option.primary }"
|
|
109
|
+
/>
|
|
110
|
+
<text class="text-4 text-gray-800 dark:text-gray-200">
|
|
111
|
+
{{ option.name }}
|
|
112
|
+
</text>
|
|
113
|
+
</view>
|
|
114
|
+
<wd-icon v-if="currentThemeColor.value === option.value" name="check" :color="option.primary" size="20px" />
|
|
115
|
+
</view>
|
|
116
|
+
</view>
|
|
117
|
+
<wd-gap :height="50" />
|
|
118
|
+
</wd-action-sheet>
|
|
119
|
+
<!-- 语言选择选择 ActionSheet -->
|
|
120
|
+
<wd-action-sheet
|
|
121
|
+
v-model="showLanguageSheet"
|
|
122
|
+
:title="languageStore.t('选择语言')"
|
|
123
|
+
:close-on-click-action="true"
|
|
124
|
+
@cancel="closeLanguagePicker"
|
|
125
|
+
>
|
|
126
|
+
<view class="px-4 pb-4">
|
|
127
|
+
<view
|
|
128
|
+
v-for="option in LocaleOptions"
|
|
129
|
+
:key="option.value"
|
|
130
|
+
class="flex items-center justify-between border-b border-gray-100 py-3 last:border-b-0 dark:border-gray-700"
|
|
131
|
+
@click="handleLanguageSelect(option)"
|
|
132
|
+
>
|
|
133
|
+
<view class="flex items-center gap-3">
|
|
134
|
+
<text class="text-4 text-gray-800 dark:text-gray-200">
|
|
135
|
+
{{ option.name }}
|
|
136
|
+
</text>
|
|
137
|
+
</view>
|
|
138
|
+
<wd-icon v-if="currentLocale.value === option.value" name="check" :color="primary" size="20px" />
|
|
139
|
+
</view>
|
|
140
|
+
</view>
|
|
141
|
+
<wd-gap :height="50" />
|
|
142
|
+
</wd-action-sheet>
|
|
143
|
+
</view>
|
|
144
|
+
</template>
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import { useRoute, useRouter } from 'uni-mini-router'
|
|
3
|
-
import { defineOptions, defineProps, nextTick, onMounted } from 'vue'
|
|
4
|
-
import { useManualTheme } from '../../composables/useManualTheme'
|
|
5
|
-
import globalLoading from '../../components/global-loading/global-loading.vue'
|
|
6
|
-
import globalToast from '../../components/global-toast/global-toast.vue'
|
|
7
|
-
import globalMessage from '../../components/global-message/global-message.vue'
|
|
8
|
-
import { useTabbar } from '../../composables/useTabbar'
|
|
9
|
-
import type { TabbarItem } from '../../composables/useTabbar'
|
|
10
|
-
|
|
11
|
-
defineOptions({
|
|
12
|
-
name: 'WuiTabbar',
|
|
13
|
-
})
|
|
14
|
-
const props = defineProps<Props>()
|
|
15
|
-
// 定义 Props 类型
|
|
16
|
-
interface Props {
|
|
17
|
-
tabbarItems: TabbarItem[]
|
|
18
|
-
}
|
|
19
|
-
const router = useRouter()
|
|
20
|
-
|
|
21
|
-
const route = useRoute()
|
|
22
|
-
|
|
23
|
-
const { themeVars, theme, currentThemeColor } = useManualTheme()
|
|
24
|
-
|
|
25
|
-
const { activeTabbar, getTabbarItemValue, setTabbarItemActive, tabbarList } = useTabbar(props.tabbarItems)
|
|
26
|
-
|
|
27
|
-
function handleTabbarChange({ value }: { value: string }) {
|
|
28
|
-
setTabbarItemActive(value)
|
|
29
|
-
router.pushTab({ name: value })
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
onMounted(() => {
|
|
33
|
-
// #ifdef APP-PLUS
|
|
34
|
-
uni.hideTabBar()
|
|
35
|
-
// #endif
|
|
36
|
-
nextTick(() => {
|
|
37
|
-
if (route.name && route.name !== activeTabbar.value.name) {
|
|
38
|
-
setTabbarItemActive(route.name)
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
</script>
|
|
43
|
-
|
|
44
|
-
<script lang="ts">
|
|
45
|
-
export default {
|
|
46
|
-
options: {
|
|
47
|
-
addGlobalClass: true,
|
|
48
|
-
virtualHost: true,
|
|
49
|
-
styleIsolation: 'shared',
|
|
50
|
-
},
|
|
51
|
-
}
|
|
52
|
-
</script>
|
|
53
|
-
|
|
54
|
-
<template>
|
|
55
|
-
<wd-config-provider :theme-vars="themeVars" :custom-class="`page-wraper ${theme}`" :theme="theme">
|
|
56
|
-
<slot />
|
|
57
|
-
<wd-tabbar
|
|
58
|
-
:model-value="activeTabbar.name"
|
|
59
|
-
bordered
|
|
60
|
-
safe-area-inset-bottom
|
|
61
|
-
placeholder
|
|
62
|
-
fixed
|
|
63
|
-
custom-class="z-14!"
|
|
64
|
-
:active-color="currentThemeColor.primary"
|
|
65
|
-
@change="handleTabbarChange"
|
|
66
|
-
>
|
|
67
|
-
<wd-tabbar-item
|
|
68
|
-
v-for="(item, index) in tabbarList"
|
|
69
|
-
:key="index"
|
|
70
|
-
:name="item.name"
|
|
71
|
-
:value="getTabbarItemValue(item.name)"
|
|
72
|
-
:title="item.title"
|
|
73
|
-
:icon="item.icon"
|
|
74
|
-
>
|
|
75
|
-
<!-- 使用 icon 插槽自定义图标 -->
|
|
76
|
-
<template v-if="item.activeIcon" #icon="{ active }">
|
|
77
|
-
<image :src="active ? item.activeIcon : item.inactiveIcon" class="custom-icon" />
|
|
78
|
-
</template>
|
|
79
|
-
</wd-tabbar-item>
|
|
80
|
-
</wd-tabbar>
|
|
81
|
-
<!-- #ifdef MP-WEIXIN -->
|
|
82
|
-
<privacy-popup />
|
|
83
|
-
<!-- #endif -->
|
|
84
|
-
<wd-notify />
|
|
85
|
-
<wd-toast />
|
|
86
|
-
<global-loading />
|
|
87
|
-
<global-toast />
|
|
88
|
-
<global-message />
|
|
89
|
-
</wd-config-provider>
|
|
90
|
-
</template>
|
|
91
|
-
|
|
92
|
-
<style lang="scss">
|
|
93
|
-
.page-wraper {
|
|
94
|
-
min-height: calc(100vh - var(--window-top));
|
|
95
|
-
box-sizing: border-box;
|
|
96
|
-
background: #f8f9fb;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.wot-theme-dark.page-wraper {
|
|
100
|
-
background: #1b1b1e;
|
|
101
|
-
}
|
|
102
|
-
.custom-icon {
|
|
103
|
-
width: 52rpx;
|
|
104
|
-
height: 52rpx;
|
|
105
|
-
}
|
|
106
|
-
</style>
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useRoute, useRouter } from 'uni-mini-router'
|
|
3
|
+
import { defineOptions, defineProps, nextTick, onMounted } from 'vue'
|
|
4
|
+
import { useManualTheme } from '../../composables/useManualTheme'
|
|
5
|
+
import globalLoading from '../../components/global-loading/global-loading.vue'
|
|
6
|
+
import globalToast from '../../components/global-toast/global-toast.vue'
|
|
7
|
+
import globalMessage from '../../components/global-message/global-message.vue'
|
|
8
|
+
import { useTabbar } from '../../composables/useTabbar'
|
|
9
|
+
import type { TabbarItem } from '../../composables/useTabbar'
|
|
10
|
+
|
|
11
|
+
defineOptions({
|
|
12
|
+
name: 'WuiTabbar',
|
|
13
|
+
})
|
|
14
|
+
const props = defineProps<Props>()
|
|
15
|
+
// 定义 Props 类型
|
|
16
|
+
interface Props {
|
|
17
|
+
tabbarItems: TabbarItem[]
|
|
18
|
+
}
|
|
19
|
+
const router = useRouter()
|
|
20
|
+
|
|
21
|
+
const route = useRoute()
|
|
22
|
+
|
|
23
|
+
const { themeVars, theme, currentThemeColor } = useManualTheme()
|
|
24
|
+
|
|
25
|
+
const { activeTabbar, getTabbarItemValue, setTabbarItemActive, tabbarList } = useTabbar(props.tabbarItems)
|
|
26
|
+
|
|
27
|
+
function handleTabbarChange({ value }: { value: string }) {
|
|
28
|
+
setTabbarItemActive(value)
|
|
29
|
+
router.pushTab({ name: value })
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
onMounted(() => {
|
|
33
|
+
// #ifdef APP-PLUS
|
|
34
|
+
uni.hideTabBar()
|
|
35
|
+
// #endif
|
|
36
|
+
nextTick(() => {
|
|
37
|
+
if (route.name && route.name !== activeTabbar.value.name) {
|
|
38
|
+
setTabbarItemActive(route.name)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<script lang="ts">
|
|
45
|
+
export default {
|
|
46
|
+
options: {
|
|
47
|
+
addGlobalClass: true,
|
|
48
|
+
virtualHost: true,
|
|
49
|
+
styleIsolation: 'shared',
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<wd-config-provider :theme-vars="themeVars" :custom-class="`page-wraper ${theme}`" :theme="theme">
|
|
56
|
+
<slot />
|
|
57
|
+
<wd-tabbar
|
|
58
|
+
:model-value="activeTabbar.name"
|
|
59
|
+
bordered
|
|
60
|
+
safe-area-inset-bottom
|
|
61
|
+
placeholder
|
|
62
|
+
fixed
|
|
63
|
+
custom-class="z-14!"
|
|
64
|
+
:active-color="currentThemeColor.primary"
|
|
65
|
+
@change="handleTabbarChange"
|
|
66
|
+
>
|
|
67
|
+
<wd-tabbar-item
|
|
68
|
+
v-for="(item, index) in tabbarList"
|
|
69
|
+
:key="index"
|
|
70
|
+
:name="item.name"
|
|
71
|
+
:value="getTabbarItemValue(item.name)"
|
|
72
|
+
:title="item.title"
|
|
73
|
+
:icon="item.icon"
|
|
74
|
+
>
|
|
75
|
+
<!-- 使用 icon 插槽自定义图标 -->
|
|
76
|
+
<template v-if="item.activeIcon" #icon="{ active }">
|
|
77
|
+
<image :src="active ? item.activeIcon : item.inactiveIcon" class="custom-icon" />
|
|
78
|
+
</template>
|
|
79
|
+
</wd-tabbar-item>
|
|
80
|
+
</wd-tabbar>
|
|
81
|
+
<!-- #ifdef MP-WEIXIN -->
|
|
82
|
+
<privacy-popup />
|
|
83
|
+
<!-- #endif -->
|
|
84
|
+
<wd-notify />
|
|
85
|
+
<wd-toast />
|
|
86
|
+
<global-loading />
|
|
87
|
+
<global-toast />
|
|
88
|
+
<global-message />
|
|
89
|
+
</wd-config-provider>
|
|
90
|
+
</template>
|
|
91
|
+
|
|
92
|
+
<style lang="scss">
|
|
93
|
+
.page-wraper {
|
|
94
|
+
min-height: calc(100vh - var(--window-top));
|
|
95
|
+
box-sizing: border-box;
|
|
96
|
+
background: #f8f9fb;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.wot-theme-dark.page-wraper {
|
|
100
|
+
background: #1b1b1e;
|
|
101
|
+
}
|
|
102
|
+
.custom-icon {
|
|
103
|
+
width: 52rpx;
|
|
104
|
+
height: 52rpx;
|
|
105
|
+
}
|
|
106
|
+
</style>
|