hy-app 0.2.6 → 0.2.8
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/common/shakeService.ts +0 -2
- package/components/hy-address-picker/hy-address-picker.vue +75 -91
- package/components/hy-avatar/hy-avatar.vue +64 -73
- package/components/hy-button/hy-button.vue +2 -2
- package/components/hy-float-button/hy-float-button.vue +115 -37
- package/components/hy-float-button/props.ts +3 -3
- package/components/hy-float-button/typing.d.ts +20 -7
- package/components/hy-icon/hy-icon.vue +1 -1
- package/components/hy-image/hy-image.vue +69 -104
- package/components/hy-image/index.scss +21 -5
- package/components/hy-image/props.ts +11 -10
- package/components/hy-image/typing.d.ts +23 -19
- package/components/hy-modal/index.scss +1 -1
- package/components/hy-popover/hy-popover.vue +200 -0
- package/components/hy-popover/index.scss +83 -0
- package/components/hy-popover/props.ts +13 -0
- package/components/hy-popover/typing.d.ts +56 -0
- package/components/hy-qrcode/hy-qrcode.vue +44 -45
- package/components/hy-rate/props.ts +6 -6
- package/components/hy-transition/hy-transition.vue +64 -72
- package/components/hy-transition/typing.d.ts +10 -6
- package/composables/index.ts +4 -2
- package/composables/usePopover.ts +221 -0
- package/composables/useQueue.ts +52 -0
- package/libs/css/mixin.scss +88 -0
- package/package.json +2 -2
- package/utils/inside.ts +96 -108
|
@@ -1,76 +1,80 @@
|
|
|
1
|
-
import type { CSSProperties } from
|
|
1
|
+
import type { CSSProperties } from 'vue'
|
|
2
2
|
|
|
3
3
|
export default interface HyImageProps {
|
|
4
4
|
/**
|
|
5
5
|
* @description 图片地址
|
|
6
6
|
* */
|
|
7
|
-
src?: string
|
|
7
|
+
src?: string
|
|
8
8
|
/**
|
|
9
9
|
* @description 裁剪模式,见官网说明 (默认 'aspectFill' )
|
|
10
10
|
* */
|
|
11
|
-
mode?: HyApp.ImageModeVo
|
|
11
|
+
mode?: HyApp.ImageModeVo
|
|
12
12
|
/**
|
|
13
13
|
* @description 宽度,单位任意,如果为数值,则为px单位 (默认 '300' )
|
|
14
14
|
* */
|
|
15
|
-
width?: string | number
|
|
15
|
+
width?: string | number
|
|
16
16
|
/**
|
|
17
17
|
* @description 高度,单位任意,如果为数值,则为px单位 (默认 '225' )
|
|
18
18
|
* */
|
|
19
|
-
height?: string | number
|
|
19
|
+
height?: string | number
|
|
20
20
|
/**
|
|
21
21
|
* @description 图片形状,circle-圆形,square-方形 (默认 'square' )
|
|
22
22
|
* */
|
|
23
|
-
shape?: HyApp.ShapeType
|
|
23
|
+
shape?: HyApp.ShapeType
|
|
24
24
|
/**
|
|
25
25
|
* @description 圆角值,单位任意,如果为数值,则为px单位 (默认 0 )
|
|
26
26
|
* */
|
|
27
|
-
radius?: number | string
|
|
27
|
+
radius?: number | string
|
|
28
28
|
/**
|
|
29
29
|
* @description 是否懒加载,仅微信小程序、App、百度小程序、字节跳动小程序有效 (默认 true )
|
|
30
30
|
* */
|
|
31
|
-
lazyLoad?: boolean
|
|
31
|
+
lazyLoad?: boolean
|
|
32
32
|
/**
|
|
33
33
|
* @description 是否开启长按图片显示识别小程序码菜单,仅微信小程序有效 (默认 true )
|
|
34
34
|
* */
|
|
35
|
-
showMenuByLongPress?: boolean
|
|
35
|
+
showMenuByLongPress?: boolean
|
|
36
36
|
/**
|
|
37
37
|
* @description 加载中的图标,或者小图片 (默认 'photo' )
|
|
38
38
|
* */
|
|
39
|
-
loadingIcon?: string
|
|
39
|
+
loadingIcon?: string
|
|
40
40
|
/**
|
|
41
41
|
* @description 加载失败的图标,或者小图片 (默认 'error-circle' )
|
|
42
42
|
* */
|
|
43
|
-
errorIcon?: string
|
|
43
|
+
errorIcon?: string
|
|
44
44
|
/**
|
|
45
45
|
* @description 是否显示加载中的图标或者自定义的slot (默认 true )
|
|
46
46
|
* */
|
|
47
|
-
showLoading?: boolean
|
|
47
|
+
showLoading?: boolean
|
|
48
48
|
/**
|
|
49
49
|
* @description 是否显示加载错误的图标或者自定义的slot (默认 true )
|
|
50
50
|
* */
|
|
51
|
-
showError?: boolean
|
|
51
|
+
showError?: boolean
|
|
52
52
|
/**
|
|
53
53
|
* @description 是否需要淡入效果 (默认 true )
|
|
54
54
|
* */
|
|
55
|
-
fade?: boolean
|
|
55
|
+
fade?: boolean
|
|
56
56
|
/**
|
|
57
57
|
* @description 只支持网络资源,只对微信小程序有效 (默认 false )
|
|
58
58
|
* */
|
|
59
|
-
webp?: boolean
|
|
59
|
+
webp?: boolean
|
|
60
60
|
/**
|
|
61
61
|
* @description 搭配fade参数的过渡时间,单位ms (默认 500 )
|
|
62
62
|
* */
|
|
63
|
-
duration?: number
|
|
63
|
+
duration?: number
|
|
64
64
|
/**
|
|
65
65
|
* @description 背景颜色,用于深色页面加载图片时,为了和背景色融合 (默认 '#f3f4f6' )
|
|
66
66
|
* */
|
|
67
|
-
bgColor?: string
|
|
67
|
+
bgColor?: string
|
|
68
|
+
/**
|
|
69
|
+
* @description 是否模糊图片 (默认 false )
|
|
70
|
+
* */
|
|
71
|
+
indistinct?: boolean
|
|
68
72
|
/**
|
|
69
73
|
* @description 是否预览图片 (默认 false )
|
|
70
74
|
* */
|
|
71
|
-
previewImage?: boolean
|
|
75
|
+
previewImage?: boolean
|
|
72
76
|
/**
|
|
73
77
|
* @description 定义需要用到的外部样式
|
|
74
78
|
* */
|
|
75
|
-
customStyle?: CSSProperties
|
|
79
|
+
customStyle?: CSSProperties
|
|
76
80
|
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hy-popover" :style="customStyle" id="popover" @click.stop="popover.noop">
|
|
3
|
+
<!-- 使用插槽时无法获取正确宽高 -->
|
|
4
|
+
<view class="hy-popover__pos hy-popover__hidden" id="pos">
|
|
5
|
+
<view class="hy-popover__container">
|
|
6
|
+
<view v-if="mode === 'normal'" class="hy-popover__inner">
|
|
7
|
+
{{ content }}
|
|
8
|
+
</view>
|
|
9
|
+
<view v-if="mode === 'menu' && typeof content === 'object'" class="hy-popover__menu">
|
|
10
|
+
<view
|
|
11
|
+
v-for="(item, index) in content"
|
|
12
|
+
:key="index"
|
|
13
|
+
class="hy-popover__menu-inner"
|
|
14
|
+
@click="menuClick(index)"
|
|
15
|
+
>
|
|
16
|
+
<hy-icon v-if="item.iconClass" :name="item.iconClass" custom-class="hy-popover__icon" />
|
|
17
|
+
<text>{{ item.content }}</text>
|
|
18
|
+
</view>
|
|
19
|
+
</view>
|
|
20
|
+
</view>
|
|
21
|
+
</view>
|
|
22
|
+
<hy-transition
|
|
23
|
+
custom-class="hy-popover__pos"
|
|
24
|
+
:custom-style="popover.popStyle"
|
|
25
|
+
:show="showPopover"
|
|
26
|
+
name="fade"
|
|
27
|
+
:duration="200"
|
|
28
|
+
>
|
|
29
|
+
<view class="hy-popover__container">
|
|
30
|
+
<!-- 三角形 -->
|
|
31
|
+
<view
|
|
32
|
+
:class="`hy-popover__arrow ${popover.arrowClass.value}`"
|
|
33
|
+
:style="popover.arrowStyle.value"
|
|
34
|
+
></view>
|
|
35
|
+
<!-- 三角形 -->
|
|
36
|
+
|
|
37
|
+
<!-- 普通模式 -->
|
|
38
|
+
<view v-if="mode === 'normal'" class="hy-popover__inner">
|
|
39
|
+
{{ content }}
|
|
40
|
+
</view>
|
|
41
|
+
<!-- 普通模式 -->
|
|
42
|
+
|
|
43
|
+
<!-- 列表模式 -->
|
|
44
|
+
<view v-if="mode === 'menu'" class="hy-popover__menu">
|
|
45
|
+
<view
|
|
46
|
+
v-for="(item, index) in content"
|
|
47
|
+
:key="index"
|
|
48
|
+
class="hy-popover__menu-inner"
|
|
49
|
+
@click="menuClick(index)"
|
|
50
|
+
:style="index === 0 ? 'border-top: none' : ''"
|
|
51
|
+
>
|
|
52
|
+
<hy-icon
|
|
53
|
+
v-if="typeof item === 'object' && item.iconClass"
|
|
54
|
+
:name="item.iconClass"
|
|
55
|
+
custom-class="hy-popover__icon"
|
|
56
|
+
/>
|
|
57
|
+
<view style="display: inline-block">
|
|
58
|
+
{{ typeof item === 'object' && item.content ? item.content : item }}
|
|
59
|
+
</view>
|
|
60
|
+
</view>
|
|
61
|
+
</view>
|
|
62
|
+
<!-- 列表模式 -->
|
|
63
|
+
|
|
64
|
+
<!-- 用户自定义样式 -->
|
|
65
|
+
<slot name="content" v-else />
|
|
66
|
+
<!-- 用户自定义样式 -->
|
|
67
|
+
</view>
|
|
68
|
+
<hy-icon
|
|
69
|
+
v-if="showClose"
|
|
70
|
+
name="close"
|
|
71
|
+
custom-class="hy-popover__close-icon"
|
|
72
|
+
@click="toggle"
|
|
73
|
+
></hy-icon>
|
|
74
|
+
</hy-transition>
|
|
75
|
+
<view @click="toggle" class="hy-popover__target" id="target">
|
|
76
|
+
<slot />
|
|
77
|
+
</view>
|
|
78
|
+
</view>
|
|
79
|
+
</template>
|
|
80
|
+
|
|
81
|
+
<script lang="ts">
|
|
82
|
+
export default {
|
|
83
|
+
name: 'hy-popover',
|
|
84
|
+
options: {
|
|
85
|
+
virtualHost: true,
|
|
86
|
+
addGlobalClass: true,
|
|
87
|
+
styleIsolation: 'shared',
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<script lang="ts" setup>
|
|
93
|
+
import { getCurrentInstance, onMounted, ref, toRefs, watch } from 'vue'
|
|
94
|
+
import defaultProps from './props'
|
|
95
|
+
import IProps, { type PopoverExpose } from './typing'
|
|
96
|
+
import { isArray } from '../../utils'
|
|
97
|
+
import { type Queue, queueKey, usePopover } from '../../composables'
|
|
98
|
+
|
|
99
|
+
// 组件
|
|
100
|
+
import HyIcon from '../hy-icon/hy-icon.vue'
|
|
101
|
+
import HyTransition from '../hy-transition/hy-transition.vue'
|
|
102
|
+
|
|
103
|
+
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
104
|
+
const { modelValue, content, mode, placement } = toRefs(props)
|
|
105
|
+
const emit = defineEmits(['update:modelValue', 'menuClick', 'change', 'open', 'close'])
|
|
106
|
+
|
|
107
|
+
const queue = inject<Queue | null>(queueKey, null)
|
|
108
|
+
const selector: string = 'popover'
|
|
109
|
+
const { proxy } = getCurrentInstance() as any
|
|
110
|
+
const popover = usePopover()
|
|
111
|
+
const showPopover = ref<boolean>(false) // 控制popover显隐
|
|
112
|
+
|
|
113
|
+
watch(
|
|
114
|
+
() => content.value,
|
|
115
|
+
(newVal) => {
|
|
116
|
+
if (mode.value === 'normal' && typeof newVal !== 'string') {
|
|
117
|
+
console.error('在“normal”模式下,值类型必须为字符串类型。')
|
|
118
|
+
} else if (mode.value === 'menu' && !isArray(newVal)) {
|
|
119
|
+
console.error('在“menu”模式下,值类型必须是数组类型。')
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
watch(
|
|
125
|
+
() => props.placement,
|
|
126
|
+
() => {
|
|
127
|
+
popover.init(placement.value, true, selector)
|
|
128
|
+
},
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
watch(
|
|
132
|
+
() => modelValue.value,
|
|
133
|
+
(newValue: boolean) => {
|
|
134
|
+
showPopover.value = newValue
|
|
135
|
+
},
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
watch(
|
|
139
|
+
() => showPopover.value,
|
|
140
|
+
(newValue) => {
|
|
141
|
+
if (newValue) {
|
|
142
|
+
popover.control(placement.value, props.offset)
|
|
143
|
+
// if (queue && queue.closeOther) {
|
|
144
|
+
// queue.closeOther(proxy)
|
|
145
|
+
// }
|
|
146
|
+
queue.closeOther(proxy)
|
|
147
|
+
}
|
|
148
|
+
popover.showStyle.value = newValue ? 'display: inline-block;' : 'display: none;'
|
|
149
|
+
emit('change', { show: newValue })
|
|
150
|
+
emit(`${newValue ? 'open' : 'close'}`)
|
|
151
|
+
},
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
onMounted(() => {
|
|
155
|
+
popover.init(placement.value, true, selector)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
onBeforeMount(() => {
|
|
159
|
+
queue.pushToQueue(proxy)
|
|
160
|
+
popover.showStyle.value = showPopover.value ? 'opacity: 1;' : 'opacity: 0;'
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
onBeforeUnmount(() => {
|
|
164
|
+
queue.removeFromQueue(proxy)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
const menuClick = (index: number) => {
|
|
168
|
+
updateModelValue(false)
|
|
169
|
+
emit('menuClick', {
|
|
170
|
+
item: (props.content as Array<Record<string, any>>)[index],
|
|
171
|
+
index,
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const toggle = () => {
|
|
176
|
+
if (props.disabled) return
|
|
177
|
+
updateModelValue(!showPopover.value)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const open = () => {
|
|
181
|
+
updateModelValue(true)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const close = () => {
|
|
185
|
+
updateModelValue(false)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function updateModelValue(value: boolean) {
|
|
189
|
+
showPopover.value = value
|
|
190
|
+
emit('update:modelValue', value)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
defineExpose<PopoverExpose>({
|
|
194
|
+
open,
|
|
195
|
+
close,
|
|
196
|
+
})
|
|
197
|
+
</script>
|
|
198
|
+
<style lang="scss" scoped>
|
|
199
|
+
@import './index.scss';
|
|
200
|
+
</style>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
@use "../../theme.scss" as *;
|
|
2
|
+
@use "../../libs/css/mixin.scss" as *;
|
|
3
|
+
|
|
4
|
+
$z-index: 998;
|
|
5
|
+
|
|
6
|
+
@include b(popover) {
|
|
7
|
+
position: relative;
|
|
8
|
+
display: inline-block;
|
|
9
|
+
|
|
10
|
+
@include edeep(icon) {
|
|
11
|
+
vertical-align: middle;
|
|
12
|
+
font-size: 18px;
|
|
13
|
+
margin-right: 5px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* 菜单 */
|
|
17
|
+
@include e(menu-inner) {
|
|
18
|
+
position: relative;
|
|
19
|
+
padding: 20rpx 0;
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
|
|
23
|
+
&:not(:last-child) {
|
|
24
|
+
border-bottom: $hy-border-line;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@include e(menu) {
|
|
29
|
+
display: inline-block;
|
|
30
|
+
padding: 0 $hy-border-margin-padding-base;
|
|
31
|
+
white-space: nowrap;
|
|
32
|
+
z-index: $z-index;
|
|
33
|
+
position: relative;
|
|
34
|
+
background-color: $hy-background--container;
|
|
35
|
+
border-radius: $hy-border-radius-sm;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@include edeep(pos) {
|
|
39
|
+
position: absolute;
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
background-clip: padding-box;
|
|
42
|
+
text-align: center;
|
|
43
|
+
min-height: 36px;
|
|
44
|
+
z-index: $z-index;
|
|
45
|
+
transition: opacity 0.2s;
|
|
46
|
+
box-shadow: $hy-box-shadow;
|
|
47
|
+
border-radius: $hy-border-radius-sm;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@include e(hidden) {
|
|
52
|
+
left: -220vw;
|
|
53
|
+
visibility: hidden;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@include e(container) {
|
|
57
|
+
position: relative;
|
|
58
|
+
border-radius: $hy-border-radius-sm;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@include e(inner) {
|
|
62
|
+
position: relative;
|
|
63
|
+
padding: $hy-border-margin-padding-base;
|
|
64
|
+
line-height: 22px;
|
|
65
|
+
z-index: $z-index;
|
|
66
|
+
background-color: $hy-background--container;
|
|
67
|
+
border-radius: $hy-border-radius-sm;
|
|
68
|
+
box-sizing: content-box;
|
|
69
|
+
width: 200px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@include edeep(close-icon) {
|
|
74
|
+
font-size: 12px;
|
|
75
|
+
position: absolute;
|
|
76
|
+
right: -10px;
|
|
77
|
+
top: -7px;
|
|
78
|
+
padding: 10px;
|
|
79
|
+
z-index: $z-index;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@include squareArrow(6px, $hy-background--container, $z-index, $hy-box-shadow);
|
|
83
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { CSSProperties } from 'vue'
|
|
2
|
+
|
|
3
|
+
export type IPlacementVo =
|
|
4
|
+
| 'top'
|
|
5
|
+
| 'top-start'
|
|
6
|
+
| 'top-end'
|
|
7
|
+
| 'bottom'
|
|
8
|
+
| 'bottom-start'
|
|
9
|
+
| 'bottom-end'
|
|
10
|
+
| 'left'
|
|
11
|
+
| 'left-start'
|
|
12
|
+
| 'left-end'
|
|
13
|
+
| 'right'
|
|
14
|
+
| 'right-start'
|
|
15
|
+
| 'right-end'
|
|
16
|
+
export type IOffset = number | number[] | Record<'x' | 'y', number>
|
|
17
|
+
|
|
18
|
+
export type PopoverExpose = {
|
|
19
|
+
open: () => void
|
|
20
|
+
close: () => void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default interface HyOverlayProps {
|
|
24
|
+
/**
|
|
25
|
+
* @description 控制 popover 的显示状态
|
|
26
|
+
* */
|
|
27
|
+
modelValue?: boolean
|
|
28
|
+
/**
|
|
29
|
+
* @description 显示的内容,也可以通过 slot#content 传入
|
|
30
|
+
*/
|
|
31
|
+
content?: string | Record<string, any>[]
|
|
32
|
+
/**
|
|
33
|
+
* @description 指定 popover 的放置位置:top / top-start / top-end / bottom / bottom-start / bottom-end / left / left-start / left-end / right / right-start / right-end
|
|
34
|
+
*/
|
|
35
|
+
placement?: IPlacementVo
|
|
36
|
+
/**
|
|
37
|
+
* @description 控制 popover 的显示状态
|
|
38
|
+
*/
|
|
39
|
+
offset?: IOffset
|
|
40
|
+
/**
|
|
41
|
+
* @description 是否禁用 popover
|
|
42
|
+
*/
|
|
43
|
+
disabled?: boolean
|
|
44
|
+
/**
|
|
45
|
+
* @description 是否显示关闭按钮
|
|
46
|
+
*/
|
|
47
|
+
showClose?: boolean
|
|
48
|
+
/**
|
|
49
|
+
* 当前显示的模式,决定内容的展现形式,可选值:normal(普通模式)/ menu(菜单模式)
|
|
50
|
+
*/
|
|
51
|
+
mode?: 'normal' | 'menu'
|
|
52
|
+
/**
|
|
53
|
+
* @description 定义需要用到的外部样式
|
|
54
|
+
* */
|
|
55
|
+
customStyle?: CSSProperties
|
|
56
|
+
}
|
|
@@ -26,40 +26,39 @@ export default {
|
|
|
26
26
|
options: {
|
|
27
27
|
addGlobalClass: true,
|
|
28
28
|
virtualHost: true,
|
|
29
|
-
styleIsolation: 'shared'
|
|
30
|
-
}
|
|
29
|
+
styleIsolation: 'shared',
|
|
30
|
+
},
|
|
31
31
|
}
|
|
32
32
|
</script>
|
|
33
33
|
|
|
34
34
|
<script setup lang="ts">
|
|
35
|
-
import { getCurrentInstance, toRefs, ref, onMounted } from
|
|
36
|
-
import defaultProps from
|
|
37
|
-
import type IProps from
|
|
38
|
-
import QRCode from
|
|
39
|
-
import { addUnit, error } from
|
|
40
|
-
import { IconConfig } from
|
|
35
|
+
import { getCurrentInstance, toRefs, ref, onMounted } from 'vue'
|
|
36
|
+
import defaultProps from './props'
|
|
37
|
+
import type IProps from './typing'
|
|
38
|
+
import QRCode from './qrcode.js'
|
|
39
|
+
import { addUnit, error } from '../../utils'
|
|
40
|
+
import { IconConfig } from '../../config'
|
|
41
41
|
|
|
42
42
|
// 组件
|
|
43
|
-
import HyIcon from
|
|
44
|
-
import HyLoading from
|
|
43
|
+
import HyIcon from '../hy-icon/hy-icon.vue'
|
|
44
|
+
import HyLoading from '../hy-loading/hy-loading.vue'
|
|
45
45
|
|
|
46
|
-
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
47
|
-
const { text, allowPreview } = toRefs(props)
|
|
48
|
-
const emit = defineEmits([
|
|
46
|
+
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
47
|
+
const { text, allowPreview } = toRefs(props)
|
|
48
|
+
const emit = defineEmits(['result', 'preview', 'longPress'])
|
|
49
49
|
|
|
50
|
-
const instance = getCurrentInstance()
|
|
51
|
-
const loading = ref(false)
|
|
52
|
-
const qrcode = ref(
|
|
53
|
-
const result = ref(
|
|
50
|
+
const instance = getCurrentInstance()
|
|
51
|
+
const loading = ref(false)
|
|
52
|
+
const qrcode = ref('')
|
|
53
|
+
const result = ref('')
|
|
54
54
|
|
|
55
55
|
onMounted(() => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
});
|
|
56
|
+
initQrCode()
|
|
57
|
+
})
|
|
59
58
|
|
|
60
59
|
const initQrCode = () => {
|
|
61
60
|
if (text.value) {
|
|
62
|
-
loading.value = true
|
|
61
|
+
loading.value = true
|
|
63
62
|
qrcode.value = new QRCode({
|
|
64
63
|
context: instance, // 上下文环境
|
|
65
64
|
canvasId: props.cid, // canvas-id
|
|
@@ -76,34 +75,34 @@ const initQrCode = () => {
|
|
|
76
75
|
imageSize: props.iconSize, // 二维码图标大小
|
|
77
76
|
cbResult: function (res: any) {
|
|
78
77
|
// 生成二维码的回调
|
|
79
|
-
_result(res)
|
|
78
|
+
_result(res)
|
|
80
79
|
},
|
|
81
|
-
})
|
|
80
|
+
})
|
|
82
81
|
} else {
|
|
83
|
-
error(
|
|
82
|
+
error('二维码内容不能为空')
|
|
84
83
|
}
|
|
85
|
-
}
|
|
84
|
+
}
|
|
86
85
|
|
|
87
86
|
const _result = (res: any) => {
|
|
88
|
-
loading.value = false
|
|
89
|
-
result.value = res
|
|
90
|
-
emit(
|
|
91
|
-
}
|
|
87
|
+
loading.value = false
|
|
88
|
+
result.value = res
|
|
89
|
+
emit('result', res)
|
|
90
|
+
}
|
|
92
91
|
|
|
93
92
|
const _saveCode = () => {
|
|
94
|
-
if (result.value !=
|
|
93
|
+
if (result.value != '') {
|
|
95
94
|
uni.saveImageToPhotosAlbum({
|
|
96
95
|
filePath: result.value,
|
|
97
96
|
success: function () {
|
|
98
97
|
uni.showToast({
|
|
99
|
-
title:
|
|
100
|
-
icon:
|
|
98
|
+
title: '二维码保存成功',
|
|
99
|
+
icon: 'success',
|
|
101
100
|
duration: 2000,
|
|
102
|
-
})
|
|
101
|
+
})
|
|
103
102
|
},
|
|
104
|
-
})
|
|
103
|
+
})
|
|
105
104
|
}
|
|
106
|
-
}
|
|
105
|
+
}
|
|
107
106
|
/**
|
|
108
107
|
* @description 预览
|
|
109
108
|
* */
|
|
@@ -114,29 +113,29 @@ const preview = (e) => {
|
|
|
114
113
|
uni.previewImage({
|
|
115
114
|
urls: [result.value],
|
|
116
115
|
longPressActions: {
|
|
117
|
-
itemList: [
|
|
116
|
+
itemList: ['保存二维码图片'],
|
|
118
117
|
success: function (data) {
|
|
119
118
|
// console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
|
|
120
119
|
switch (data.tapIndex) {
|
|
121
120
|
case 0:
|
|
122
|
-
_saveCode()
|
|
123
|
-
break
|
|
121
|
+
_saveCode()
|
|
122
|
+
break
|
|
124
123
|
}
|
|
125
124
|
},
|
|
126
125
|
fail: function (err) {
|
|
127
|
-
console.error(err.errMsg)
|
|
126
|
+
console.error(err.errMsg)
|
|
128
127
|
},
|
|
129
128
|
},
|
|
130
|
-
})
|
|
129
|
+
})
|
|
131
130
|
}
|
|
132
|
-
emit(
|
|
133
|
-
}
|
|
131
|
+
emit('preview', result.value, e)
|
|
132
|
+
}
|
|
134
133
|
|
|
135
134
|
const onLongPress = () => {
|
|
136
|
-
emit(
|
|
137
|
-
}
|
|
135
|
+
emit('longPress')
|
|
136
|
+
}
|
|
138
137
|
</script>
|
|
139
138
|
|
|
140
139
|
<style lang="scss" scoped>
|
|
141
|
-
@import
|
|
140
|
+
@import './index.scss';
|
|
142
141
|
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ColorConfig, IconConfig } from
|
|
2
|
-
import type IProps from
|
|
1
|
+
import { ColorConfig, IconConfig } from '../../config'
|
|
2
|
+
import type IProps from './typing'
|
|
3
3
|
|
|
4
4
|
const defaultProps: IProps = {
|
|
5
5
|
modelValue: 1,
|
|
@@ -7,13 +7,13 @@ const defaultProps: IProps = {
|
|
|
7
7
|
disabled: false,
|
|
8
8
|
readonly: false,
|
|
9
9
|
size: 18,
|
|
10
|
-
inactiveColor:
|
|
11
|
-
activeColor:
|
|
10
|
+
inactiveColor: '#b2b2b2',
|
|
11
|
+
activeColor: '#FFF00D',
|
|
12
12
|
gutter: 4,
|
|
13
13
|
minCount: 1,
|
|
14
14
|
allowHalf: false,
|
|
15
15
|
activeIcon: IconConfig.STAR_FILL,
|
|
16
16
|
inactiveIcon: IconConfig.STAR,
|
|
17
17
|
touchable: true,
|
|
18
|
-
}
|
|
19
|
-
export default defaultProps
|
|
18
|
+
}
|
|
19
|
+
export default defaultProps
|