im-ui-mobile 0.1.1 → 0.1.3
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/README.md +8 -1
- package/components/im-read-receipt/im-read-receipt.vue +2 -2
- package/components/im-tabs/im-tabs.vue +1022 -0
- package/components/im-tabs/tabs-navigation.vue +489 -0
- package/components/im-tabs/utils/helper.ts +181 -0
- package/components/im-tabs-tab-pane/im-tabs-tab-pane.vue +145 -0
- package/index.js +0 -4
- package/package.json +1 -1
- package/styles/common.scss +4 -4
- package/types/components/stepper.d.ts +2 -0
- package/types/components/tabs-tab-pane.d.ts +27 -0
- package/types/components/tabs.d.ts +117 -0
- package/types/components.d.ts +2 -0
- package/types/index.d.ts +27 -33
- package/types/utils/websocket.d.ts +4 -1
- package/plugins/uview-plus.js +0 -29
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<!-- components/im-tabs/im-tabs-tab-pane.vue -->
|
|
2
|
+
<template>
|
|
3
|
+
<view v-if="shouldRender" :class="[
|
|
4
|
+
'im-tabs-tab-pane',
|
|
5
|
+
customClass,
|
|
6
|
+
{
|
|
7
|
+
'im-tabs-tab-pane-active': active,
|
|
8
|
+
'im-tabs-tab-pane-inactive': !active
|
|
9
|
+
}
|
|
10
|
+
]" :style="paneStyle">
|
|
11
|
+
<slot v-if="shouldShowContent" />
|
|
12
|
+
</view>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script lang="ts" setup>
|
|
16
|
+
import { computed, inject, ref } from 'vue'
|
|
17
|
+
import type { PropType } from 'vue'
|
|
18
|
+
|
|
19
|
+
const props = defineProps({
|
|
20
|
+
index: {
|
|
21
|
+
type: Number,
|
|
22
|
+
default: 0
|
|
23
|
+
},
|
|
24
|
+
id: {
|
|
25
|
+
type: [String, Number] as PropType<string | number>,
|
|
26
|
+
default: ''
|
|
27
|
+
},
|
|
28
|
+
title: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: ''
|
|
31
|
+
},
|
|
32
|
+
lazy: {
|
|
33
|
+
type: Boolean,
|
|
34
|
+
default: false
|
|
35
|
+
},
|
|
36
|
+
destroyOnInactive: {
|
|
37
|
+
type: Boolean,
|
|
38
|
+
default: false
|
|
39
|
+
},
|
|
40
|
+
customClass: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: ''
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// 注入父组件数据
|
|
47
|
+
const tabsData = inject<any>('tabs')
|
|
48
|
+
const { currentIndex, keepAlive } = tabsData || {}
|
|
49
|
+
|
|
50
|
+
// 记录是否曾经激活过(用于懒加载)
|
|
51
|
+
const hasBeenActive = ref(false)
|
|
52
|
+
|
|
53
|
+
// 计算属性
|
|
54
|
+
const active = computed(() => {
|
|
55
|
+
const isActive = currentIndex?.value === props.index
|
|
56
|
+
if (isActive) {
|
|
57
|
+
hasBeenActive.value = true
|
|
58
|
+
}
|
|
59
|
+
return isActive
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
const shouldRender = computed(() => {
|
|
63
|
+
if (props.destroyOnInactive && !active.value) {
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (props.lazy && !active.value && !hasBeenActive.value) {
|
|
68
|
+
return false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return true
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const shouldShowContent = computed(() => {
|
|
75
|
+
if (keepAlive?.value === false && !active.value) {
|
|
76
|
+
return false
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (props.lazy && !active.value && !hasBeenActive.value) {
|
|
80
|
+
return false
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return true
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const paneStyle = computed(() => {
|
|
87
|
+
const style: Record<string, any> = {}
|
|
88
|
+
|
|
89
|
+
if (active.value) {
|
|
90
|
+
style.display = 'block'
|
|
91
|
+
} else {
|
|
92
|
+
style.display = 'none'
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return style
|
|
96
|
+
})
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<style lang="scss" scoped>
|
|
100
|
+
.im-tabs-tab-pane {
|
|
101
|
+
width: 100%;
|
|
102
|
+
height: 100%;
|
|
103
|
+
flex-shrink: 0;
|
|
104
|
+
overflow: auto;
|
|
105
|
+
box-sizing: border-box;
|
|
106
|
+
|
|
107
|
+
// 水平布局
|
|
108
|
+
.im-tabs-content:not(.im-tabs-content-vertical) & {
|
|
109
|
+
width: 100%;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 垂直布局
|
|
113
|
+
.im-tabs-content-vertical & {
|
|
114
|
+
height: 100%;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 激活状态
|
|
118
|
+
&-active {
|
|
119
|
+
display: block;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 非激活状态
|
|
123
|
+
&-inactive {
|
|
124
|
+
display: none;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 动画效果
|
|
129
|
+
.im-tabs-content {
|
|
130
|
+
&-fade {
|
|
131
|
+
.im-tabs-tab-pane {
|
|
132
|
+
animation-duration: 0.3s;
|
|
133
|
+
animation-fill-mode: both;
|
|
134
|
+
|
|
135
|
+
&-enter-active {
|
|
136
|
+
animation-name: im-tabs-fade-in;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
&-leave-active {
|
|
140
|
+
animation-name: im-tabs-fade-out;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
</style>
|
package/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { nextTick } from 'vue';
|
|
2
|
-
import { UViewPlusPlugin } from './plugins/uview-plus.js'
|
|
3
2
|
import eventBus from "./utils/eventBus.js";
|
|
4
3
|
import datetime from "./utils/datetime.js";
|
|
5
4
|
import Emoji from "./utils/emoji.js";
|
|
@@ -53,9 +52,6 @@ const install = (app, upuiParams = '') => {
|
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
// 安装插件
|
|
57
|
-
app.use(UViewPlusPlugin)
|
|
58
|
-
|
|
59
55
|
// 注册组件
|
|
60
56
|
components.forEach(component => {
|
|
61
57
|
app.component(component.name || '', component)
|
package/package.json
CHANGED
package/styles/common.scss
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
.none-pointer-events {
|
|
2
2
|
uni-image img {
|
|
3
3
|
// 阻止微信默认长按菜单
|
|
4
|
-
pointer-events: none;
|
|
5
|
-
-webkit-pointer-events: none;
|
|
6
|
-
-ms-pointer-events: none;
|
|
7
|
-
-moz-pointer-events: none;
|
|
4
|
+
// pointer-events: none;
|
|
5
|
+
// -webkit-pointer-events: none;
|
|
6
|
+
// -ms-pointer-events: none;
|
|
7
|
+
// -moz-pointer-events: none;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AllowedComponentProps, VNodeProps } from '../common'
|
|
2
|
+
|
|
3
|
+
declare interface _TabsTabPaneProps {
|
|
4
|
+
/** 标签索引 */
|
|
5
|
+
index?: number;
|
|
6
|
+
/** 标签标识符 */
|
|
7
|
+
id?: string | number;
|
|
8
|
+
/** 是否延迟渲染 */
|
|
9
|
+
lazy?: boolean;
|
|
10
|
+
/** 是否激活 */
|
|
11
|
+
active?: boolean;
|
|
12
|
+
/** 是否销毁 */
|
|
13
|
+
destroyOnInactive?: boolean;
|
|
14
|
+
/** 自定义CSS类 */
|
|
15
|
+
customClass?:string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
declare interface _TabsTabPane {
|
|
20
|
+
new(): {
|
|
21
|
+
$props: AllowedComponentProps & VNodeProps & _TabsTabPaneProps
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
export declare const TabsTabPane: _TabsTabPane
|
|
27
|
+
export declare const TabsTabPaneProps: _TabsTabPaneProps
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { AllowedComponentProps, VNodeProps } from '../common'
|
|
2
|
+
|
|
3
|
+
declare interface _TabItem {
|
|
4
|
+
/** 标签名称 */
|
|
5
|
+
title: string;
|
|
6
|
+
/** 标签标识符 */
|
|
7
|
+
id?: string | number;
|
|
8
|
+
/** 是否禁用 */
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
/** 徽标数字 */
|
|
11
|
+
badge?: number;
|
|
12
|
+
/** 徽标文字 */
|
|
13
|
+
badgeText?: string;
|
|
14
|
+
/** 徽标类型 */
|
|
15
|
+
badgeType?: 'dot' | 'number' | 'text';
|
|
16
|
+
/** 自定义图标 */
|
|
17
|
+
icon?: string;
|
|
18
|
+
/** 选中时的图标 */
|
|
19
|
+
activeIcon?: string;
|
|
20
|
+
/** 是否显示红点 */
|
|
21
|
+
showRedDot?: boolean;
|
|
22
|
+
/** 自定义样式 */
|
|
23
|
+
style?: Record<string, any>;
|
|
24
|
+
/** 自定义类名 */
|
|
25
|
+
class?: string;
|
|
26
|
+
/** 自定义渲染函数 */
|
|
27
|
+
renderTitle?: (tab: TabItem, isActive: boolean) => any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare interface _TabsProps {
|
|
31
|
+
/** 当前激活的标签索引 */
|
|
32
|
+
modelValue?: number;
|
|
33
|
+
/** 当前激活的标签标识符 */
|
|
34
|
+
activeKey?: string | number;
|
|
35
|
+
/** 标签列表 */
|
|
36
|
+
items: TabItem[];
|
|
37
|
+
/** 标签栏位置 */
|
|
38
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
39
|
+
/** 标签栏样式 */
|
|
40
|
+
type?: 'line' | 'card' | 'button' | 'segment';
|
|
41
|
+
/** 是否可滑动切换 */
|
|
42
|
+
swipeable?: boolean;
|
|
43
|
+
/** 是否显示底部滑动条 */
|
|
44
|
+
showSlider?: boolean;
|
|
45
|
+
/** 滑动条宽度(单位px或%) */
|
|
46
|
+
sliderWidth?: string | number;
|
|
47
|
+
/** 滑动条高度(单位px) */
|
|
48
|
+
sliderHeight?: number;
|
|
49
|
+
/** 滑动条颜色 */
|
|
50
|
+
sliderColor?: string;
|
|
51
|
+
/** 是否显示底部边框 */
|
|
52
|
+
border?: boolean;
|
|
53
|
+
/** 标签栏背景色 */
|
|
54
|
+
background?: string;
|
|
55
|
+
/** 标签栏高度(单位px) */
|
|
56
|
+
height?: number;
|
|
57
|
+
/** 标签最小宽度(单位px) */
|
|
58
|
+
minTabWidth?: number;
|
|
59
|
+
/** 标签最大宽度(单位px) */
|
|
60
|
+
maxTabWidth?: number;
|
|
61
|
+
/** 是否开启粘性布局 */
|
|
62
|
+
sticky?: boolean;
|
|
63
|
+
/** 粘性布局吸顶距离(单位px) */
|
|
64
|
+
stickyOffsetTop?: number;
|
|
65
|
+
/** 是否开启滚动导航 */
|
|
66
|
+
scrollable?: boolean;
|
|
67
|
+
/** 标签栏是否居中 */
|
|
68
|
+
centered?: boolean;
|
|
69
|
+
/** 是否在切换标签时保留状态 */
|
|
70
|
+
keepAlive?: boolean;
|
|
71
|
+
/** 是否开启懒加载 */
|
|
72
|
+
lazy?: boolean;
|
|
73
|
+
/** 切换动画持续时间(毫秒) */
|
|
74
|
+
duration?: number;
|
|
75
|
+
/** 是否在初始化时滚动到激活标签 */
|
|
76
|
+
scrollOnInit?: boolean;
|
|
77
|
+
/** 点击标签前回调,返回 false 可阻止切换 */
|
|
78
|
+
beforeChange?: (index: number, tab: TabItem) => boolean | Promise<boolean>;
|
|
79
|
+
/** 自定义类名 */
|
|
80
|
+
customClass?: string;
|
|
81
|
+
/** 自定义标签栏类名 */
|
|
82
|
+
navClass?: string;
|
|
83
|
+
/** 自定义内容类名 */
|
|
84
|
+
contentClass?: string;
|
|
85
|
+
/** 标签间距(单位px) */
|
|
86
|
+
gutter?: number;
|
|
87
|
+
/** 是否显示标签图标 */
|
|
88
|
+
showIcon?: boolean;
|
|
89
|
+
/** 图标位置 */
|
|
90
|
+
iconPosition?: 'left' | 'right' | 'top' | 'bottom';
|
|
91
|
+
/** 动画类型 */
|
|
92
|
+
animation?: 'slide' | 'fade' | 'none';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
declare interface _TabsEmits {
|
|
96
|
+
(e: 'update:modelValue', index: number): void;
|
|
97
|
+
(e: 'update:activeKey', id: string | number): void;
|
|
98
|
+
(e: 'change', index: number, tab: TabItem): void;
|
|
99
|
+
(e: 'click', index: number, tab: TabItem): void;
|
|
100
|
+
(e: 'disabled', index: number, tab: TabItem): void;
|
|
101
|
+
(e: 'scroll', event: any): void;
|
|
102
|
+
(e: 'sticky', isSticky: boolean): void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
declare interface _Tabs {
|
|
106
|
+
new(): {
|
|
107
|
+
$props: AllowedComponentProps & VNodeProps & _TabsProps
|
|
108
|
+
$emit: _TabsEmits
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
export declare const Tabs: _Tabs
|
|
114
|
+
export declare type TabItem = _TabItem
|
|
115
|
+
export declare type TabsProps = _TabsProps
|
|
116
|
+
export declare type TabsEmits = _TabsEmits
|
|
117
|
+
|
package/types/components.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ declare module 'vue' {
|
|
|
33
33
|
['im-link']: typeof import('./components/link')['Link']
|
|
34
34
|
['im-sku']: typeof import('./components/sku')['Sku']
|
|
35
35
|
['im-stepper']: typeof import('./components/stepper')['Stepper']
|
|
36
|
+
['im-tabs']: typeof import('./components/tabs')['Tabs']
|
|
37
|
+
['im-tabs-tab-pane']: typeof import('./components/tabs-tab-pane')['TabsTabPane']
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
|
package/types/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import RecorderH5 from "./utils/recorderH5.d.ts";
|
|
|
11
11
|
import Requester from "./utils/requester.d.ts";
|
|
12
12
|
import * as url from "./utils/url.d.ts";
|
|
13
13
|
import { useDynamicRefs } from "./utils/useDynamicRefs.d.ts";
|
|
14
|
-
import WebSocket from "./utils/websocket.d.ts";
|
|
14
|
+
import { webSocket, type WebSocket } from "./utils/websocket.d.ts";
|
|
15
15
|
import type {
|
|
16
16
|
// 类型常量
|
|
17
17
|
RtcMode,
|
|
@@ -69,20 +69,39 @@ declare module 'im-ui-mobile' {
|
|
|
69
69
|
ValidationResult,
|
|
70
70
|
EmojiType,
|
|
71
71
|
EmojiCategoryType,
|
|
72
|
+
RtcMode,
|
|
73
|
+
RtcInfo,
|
|
74
|
+
Chat,
|
|
75
|
+
Message,
|
|
76
|
+
Friend,
|
|
77
|
+
OnlineTerminal,
|
|
78
|
+
MenuItem,
|
|
79
|
+
WebRTCMessage,
|
|
80
|
+
GroupMember,
|
|
81
|
+
Group,
|
|
82
|
+
UploadImageResponse,
|
|
83
|
+
SubmitItem,
|
|
84
|
+
ImageItem,
|
|
85
|
+
FileItem,
|
|
86
|
+
ApiResponse,
|
|
87
|
+
RecorderError,
|
|
88
|
+
UploadRecorderFileResponse,
|
|
89
|
+
UploadRecorderFileResult,
|
|
90
|
+
RecorderFile,
|
|
91
|
+
UserInfo,
|
|
92
|
+
Response,
|
|
93
|
+
WebSocket
|
|
72
94
|
}
|
|
73
95
|
|
|
74
|
-
//
|
|
96
|
+
// 导出函数/实例
|
|
75
97
|
export {
|
|
76
98
|
isNumber,
|
|
77
99
|
isInteger,
|
|
78
100
|
isMobilePhone,
|
|
79
101
|
isEmail,
|
|
80
102
|
isChineseIDCard,
|
|
81
|
-
validatePassword
|
|
82
|
-
}
|
|
103
|
+
validatePassword,
|
|
83
104
|
|
|
84
|
-
// 导出类型/函数
|
|
85
|
-
export {
|
|
86
105
|
getConfig,
|
|
87
106
|
eventBus,
|
|
88
107
|
datetime,
|
|
@@ -92,7 +111,7 @@ declare module 'im-ui-mobile' {
|
|
|
92
111
|
Requester,
|
|
93
112
|
url,
|
|
94
113
|
useDynamicRefs,
|
|
95
|
-
|
|
114
|
+
webSocket,
|
|
96
115
|
RecorderApp,
|
|
97
116
|
RecorderH5,
|
|
98
117
|
validator,
|
|
@@ -103,30 +122,5 @@ declare module 'im-ui-mobile' {
|
|
|
103
122
|
MESSAGE_TYPE,
|
|
104
123
|
TERMINAL_TYPE,
|
|
105
124
|
MESSAGE_STATUS,
|
|
106
|
-
|
|
107
|
-
// 类型常量
|
|
108
|
-
RtcMode,
|
|
109
|
-
RtcInfo,
|
|
110
|
-
Chat,
|
|
111
|
-
Message,
|
|
112
|
-
Friend,
|
|
113
|
-
OnlineTerminal,
|
|
114
|
-
MenuItem,
|
|
115
|
-
WebRTCMessage,
|
|
116
|
-
GroupMember,
|
|
117
|
-
Group,
|
|
118
|
-
UploadImageResponse,
|
|
119
|
-
SubmitItem,
|
|
120
|
-
ImageItem,
|
|
121
|
-
FileItem,
|
|
122
|
-
ApiResponse,
|
|
123
|
-
RecorderError,
|
|
124
|
-
UploadRecorderFileResponse,
|
|
125
|
-
UploadRecorderFileResult,
|
|
126
|
-
RecorderFile,
|
|
127
|
-
UserInfo,
|
|
128
|
-
Response
|
|
129
125
|
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// export { MESSAGE_TYPE, RTC_STATE, TERMINAL_TYPE, MESSAGE_STATUS }
|
|
126
|
+
}
|
package/plugins/uview-plus.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import uviewPlus from 'uview-plus'
|
|
2
|
-
|
|
3
|
-
export const UViewPlusPlugin = {
|
|
4
|
-
install(app) {
|
|
5
|
-
// 安装 uview-plus
|
|
6
|
-
app.use(uviewPlus)
|
|
7
|
-
|
|
8
|
-
// 注册一些常用的 uview-plus 组件作为全局组件
|
|
9
|
-
app.component('UButton', uviewPlus.Button)
|
|
10
|
-
app.component('UInput', uviewPlus.Input)
|
|
11
|
-
app.component('UAvatar', uviewPlus.Avatar)
|
|
12
|
-
app.component('UBadge', uviewPlus.Badge)
|
|
13
|
-
app.component('UIcon', uviewPlus.Icon)
|
|
14
|
-
app.component('UPopup', uviewPlus.Popup)
|
|
15
|
-
app.component('USearch', uviewPlus.Search)
|
|
16
|
-
app.component('UIndexList', uviewPlus.IndexList)
|
|
17
|
-
app.component('UIndexItem', uviewPlus.IndexItem)
|
|
18
|
-
app.component('UCard', uviewPlus.Card)
|
|
19
|
-
app.component('UTabs', uviewPlus.Tabs)
|
|
20
|
-
app.component('UParse', uviewPlus.Parse)
|
|
21
|
-
app.component('ULink', uviewPlus.Link)
|
|
22
|
-
app.component('UUpload', uviewPlus.Upload)
|
|
23
|
-
app.component('ULineProgress', uviewPlus.LineProgress)
|
|
24
|
-
app.component('UModal', uviewPlus.Modal)
|
|
25
|
-
app.component('UTag', uviewPlus.Tag)
|
|
26
|
-
app.component('UForm', uviewPlus.Form)
|
|
27
|
-
app.component('UFormItem', uviewPlus.FormItem)
|
|
28
|
-
}
|
|
29
|
-
}
|