@tplc/business 0.0.17 → 0.0.20
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/CHANGELOG.md +130 -0
- package/action.d.ts +8 -0
- package/components/lcb-action-view/lcb-action-view.vue +145 -0
- package/components/lcb-action-view/types.ts +13 -0
- package/components/lcb-banner/lcb-banner.vue +36 -31
- package/components/lcb-banner/types.ts +3 -3
- package/components/lcb-banner-block/lcb-banner-block.vue +43 -35
- package/components/lcb-banner-block/types.ts +5 -0
- package/components/lcb-block/lcb-block.vue +10 -23
- package/components/lcb-block/types.ts +23 -9
- package/components/lcb-filter/components/FilterSlider/index.vue +40 -4
- package/components/lcb-filter/components/TreeSelect/index.vue +48 -5
- package/components/lcb-filter/lcb-filter.vue +4 -0
- package/components/lcb-gap/lcb-gap.vue +23 -0
- package/components/lcb-gap/types.ts +5 -0
- package/components/lcb-grid/lcb-grid.vue +5 -10
- package/components/lcb-home-search/lcb-home-search.vue +73 -38
- package/components/lcb-home-search/types.ts +7 -0
- package/components/lcb-image/Image/index.vue +96 -0
- package/components/lcb-image/lcb-image.vue +88 -0
- package/components/lcb-image/types.ts +15 -0
- package/components/lcb-img-nav/lcb-img-nav.vue +42 -44
- package/components/lcb-img-nav/types.ts +2 -9
- package/components/lcb-nav/lcb-nav.vue +10 -6
- package/components/lcb-title/lcb-title.vue +2 -3
- package/components/lcb-user-order/lcb-user-order.vue +59 -54
- package/components/lcb-user-order/types.ts +2 -2
- package/components/lcb-user-top/lcb-user-top.vue +96 -48
- package/components/lcb-user-top/types.ts +1 -0
- package/components/lcb-video/lcb-video.vue +33 -0
- package/components/lcb-video/types.ts +11 -0
- package/global.d.ts +4 -0
- package/iconfonts/index.css +24 -5
- package/package.json +2 -2
- package/types/components/lcb-action-view/lcb-action-view.vue.d.ts +41 -0
- package/types/components/lcb-action-view/types.d.ts +13 -0
- package/types/components/lcb-banner/lcb-banner.vue.d.ts +1 -2
- package/types/components/lcb-banner/types.d.ts +3 -3
- package/types/components/lcb-banner-block/lcb-banner-block.vue.d.ts +9 -2
- package/types/components/lcb-banner-block/types.d.ts +5 -0
- package/types/components/lcb-block/lcb-block.vue.d.ts +18 -25
- package/types/components/lcb-block/types.d.ts +21 -9
- package/types/components/lcb-gap/lcb-gap.vue.d.ts +42 -0
- package/types/components/lcb-gap/types.d.ts +5 -0
- package/types/components/lcb-grid/lcb-grid.vue.d.ts +4 -1
- package/types/components/lcb-home-search/lcb-home-search.vue.d.ts +37 -7
- package/types/components/lcb-home-search/types.d.ts +6 -0
- package/types/components/lcb-image/Image/index.vue.d.ts +56 -0
- package/types/components/lcb-image/lcb-image.vue.d.ts +71 -0
- package/types/components/lcb-image/types.d.ts +13 -0
- package/types/components/lcb-img-nav/lcb-img-nav.vue.d.ts +6 -12
- package/types/components/lcb-img-nav/types.d.ts +2 -9
- package/types/components/lcb-nav/lcb-nav.vue.d.ts +1 -1
- package/types/components/lcb-title/lcb-title.vue.d.ts +6 -0
- package/types/components/lcb-user-order/lcb-user-order.vue.d.ts +1 -1
- package/types/components/lcb-user-top/lcb-user-top.vue.d.ts +3 -0
- package/types/components/lcb-user-top/types.d.ts +1 -0
- package/types/components/lcb-video/lcb-video.vue.d.ts +56 -0
- package/types/components/lcb-video/types.d.ts +10 -0
- package/utils/transform.ts +1 -1
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view>
|
|
3
|
-
<wd-slider
|
|
2
|
+
<view class="filter-slider">
|
|
3
|
+
<wd-slider
|
|
4
|
+
hide-label
|
|
5
|
+
:max="max"
|
|
6
|
+
:min="min"
|
|
7
|
+
:minText="`${unit}${min}`"
|
|
8
|
+
:maxText="`${unit}${max}+`"
|
|
9
|
+
v-model="innerValue"
|
|
10
|
+
@dragend="onDragend"
|
|
11
|
+
ref="slider"
|
|
12
|
+
custom-class="px-4"
|
|
13
|
+
custom-min-class="left-0 slider-text"
|
|
14
|
+
custom-max-class="right--2 slider-text"
|
|
15
|
+
/>
|
|
4
16
|
<view class="grid grid-cols-4 gap-4 mt-2">
|
|
5
17
|
<SelectTagView
|
|
6
18
|
v-for="item in options"
|
|
@@ -17,7 +29,8 @@
|
|
|
17
29
|
<script setup lang="ts">
|
|
18
30
|
import { FilterSliderProps } from './types'
|
|
19
31
|
import SelectTagView from '../SelectTagView/index.vue'
|
|
20
|
-
import { ref, watch } from 'vue'
|
|
32
|
+
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
|
33
|
+
import type { SliderInstance } from '@tplc/wot/components/wd-slider/types'
|
|
21
34
|
defineOptions({
|
|
22
35
|
name: 'FilterSlider',
|
|
23
36
|
options: {
|
|
@@ -26,6 +39,7 @@ defineOptions({
|
|
|
26
39
|
styleIsolation: 'shared',
|
|
27
40
|
},
|
|
28
41
|
})
|
|
42
|
+
const slider = ref<SliderInstance>()
|
|
29
43
|
const props = defineProps<FilterSliderProps>()
|
|
30
44
|
const model = defineModel<number[]>()
|
|
31
45
|
const innerValue = ref<number[]>()
|
|
@@ -38,6 +52,17 @@ const onItemClick = (value) => {
|
|
|
38
52
|
}
|
|
39
53
|
}
|
|
40
54
|
}
|
|
55
|
+
|
|
56
|
+
const onDropOpened = () => {
|
|
57
|
+
slider.value?.initSlider()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
onMounted(() => {
|
|
61
|
+
uni.$on('drop-opened', onDropOpened)
|
|
62
|
+
})
|
|
63
|
+
onUnmounted(() => {
|
|
64
|
+
uni.$off('drop-opened', onDropOpened)
|
|
65
|
+
})
|
|
41
66
|
watch(
|
|
42
67
|
() => model.value,
|
|
43
68
|
(val) => {
|
|
@@ -67,4 +92,15 @@ const getChecked = (value) => {
|
|
|
67
92
|
}
|
|
68
93
|
}
|
|
69
94
|
</script>
|
|
70
|
-
<style lang="scss"
|
|
95
|
+
<style lang="scss">
|
|
96
|
+
.filter-slider {
|
|
97
|
+
position: relative;
|
|
98
|
+
padding-top: 24rpx;
|
|
99
|
+
:deep(.slider-text) {
|
|
100
|
+
color: #999 !important;
|
|
101
|
+
font-size: 24rpx !important;
|
|
102
|
+
position: absolute;
|
|
103
|
+
margin-bottom: 100rpx;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
</style>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<view
|
|
6
6
|
v-for="(item, index) in options"
|
|
7
7
|
:key="item.label"
|
|
8
|
-
@click="
|
|
8
|
+
@click="onCategoryClick(index)"
|
|
9
9
|
class="filter-select flex justify-between items-center"
|
|
10
10
|
:class="currentCategory === index ? 'filter-select__choose' : ''"
|
|
11
11
|
>
|
|
@@ -24,8 +24,15 @@
|
|
|
24
24
|
<wd-icon name="check" custom-class="choose_icon" v-if="innerValue === item.value" />
|
|
25
25
|
</view>
|
|
26
26
|
</view>
|
|
27
|
-
<
|
|
28
|
-
|
|
27
|
+
<scroll-view
|
|
28
|
+
scroll-y
|
|
29
|
+
:scroll-into-view="toView"
|
|
30
|
+
scroll-with-animation
|
|
31
|
+
class="flex-1 w-0 bg-#FAFAFA pl-4 scroll-view pt-32rpx"
|
|
32
|
+
@scroll="onGridScroll"
|
|
33
|
+
v-else
|
|
34
|
+
>
|
|
35
|
+
<view v-for="(item, index) in options" :key="item.label" :id="`grid_${index}`">
|
|
29
36
|
<view class="filter-select__title">
|
|
30
37
|
{{ item.label }}
|
|
31
38
|
</view>
|
|
@@ -40,7 +47,7 @@
|
|
|
40
47
|
/>
|
|
41
48
|
</view>
|
|
42
49
|
</view>
|
|
43
|
-
</view>
|
|
50
|
+
</scroll-view>
|
|
44
51
|
</view>
|
|
45
52
|
<ActionView
|
|
46
53
|
:disabled="!Boolean(innerValue)"
|
|
@@ -51,7 +58,7 @@
|
|
|
51
58
|
</template>
|
|
52
59
|
|
|
53
60
|
<script setup lang="ts">
|
|
54
|
-
import { computed, nextTick, ref } from 'vue'
|
|
61
|
+
import { computed, getCurrentInstance, nextTick, watch, ref } from 'vue'
|
|
55
62
|
import { TreeSelectProps } from './type'
|
|
56
63
|
import useSelect from '../../hooks/useSelect'
|
|
57
64
|
import SelectTagView from '../SelectTagView/index.vue'
|
|
@@ -68,6 +75,8 @@ const props = defineProps<TreeSelectProps>()
|
|
|
68
75
|
const model = defineModel<string | string[]>()
|
|
69
76
|
const modelTitle = defineModel<string>('title')
|
|
70
77
|
const innerValue = ref(model.value)
|
|
78
|
+
const toView = ref('')
|
|
79
|
+
const itemTopPositions = ref<{ top: number; bottom: number }[]>([])
|
|
71
80
|
const emits = defineEmits(['submit'])
|
|
72
81
|
const { onItemClick, options, getChecked } = useSelect(props, { model: innerValue })
|
|
73
82
|
const currentCategory = ref(0)
|
|
@@ -91,6 +100,37 @@ const onSubmit = () => {
|
|
|
91
100
|
emits('submit')
|
|
92
101
|
})
|
|
93
102
|
}
|
|
103
|
+
const onCategoryClick = (index: number) => {
|
|
104
|
+
currentCategory.value = index
|
|
105
|
+
toView.value = `grid_${index}`
|
|
106
|
+
}
|
|
107
|
+
const { proxy } = getCurrentInstance() as any
|
|
108
|
+
watch(
|
|
109
|
+
() => options.value,
|
|
110
|
+
() => {
|
|
111
|
+
nextTick(() => {
|
|
112
|
+
const query = uni.createSelectorQuery().in(proxy)
|
|
113
|
+
options.value.forEach((_, index) => {
|
|
114
|
+
query.select(`#grid_${index}`).boundingClientRect()
|
|
115
|
+
})
|
|
116
|
+
query.exec((res) => {
|
|
117
|
+
console.log(res)
|
|
118
|
+
itemTopPositions.value = res.map((rect) => ({ top: rect.top, bottom: rect.bottom }))
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
immediate: true,
|
|
124
|
+
},
|
|
125
|
+
)
|
|
126
|
+
const onGridScroll = (e) => {
|
|
127
|
+
const scrollTop = e.detail.scrollTop
|
|
128
|
+
itemTopPositions.value.forEach((pos, index) => {
|
|
129
|
+
if (pos.top <= scrollTop + 100) {
|
|
130
|
+
currentCategory.value = index
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
}
|
|
94
134
|
</script>
|
|
95
135
|
<style lang="scss" scoped>
|
|
96
136
|
@import '@tplc/wot/components/common/abstracts/variable';
|
|
@@ -112,6 +152,9 @@ const onSubmit = () => {
|
|
|
112
152
|
font-size: 30rpx;
|
|
113
153
|
color: $-color-theme;
|
|
114
154
|
margin-bottom: 30rpx;
|
|
155
|
+
&:first-child {
|
|
156
|
+
margin-top: 0;
|
|
157
|
+
}
|
|
115
158
|
}
|
|
116
159
|
&__choose {
|
|
117
160
|
color: $-color-theme;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
icon-size="26px"
|
|
10
10
|
:selected="getSelect(item)"
|
|
11
11
|
ref="dropMenu"
|
|
12
|
+
@opened="handleOpened"
|
|
12
13
|
>
|
|
13
14
|
<view class="lcb-filter__popup">
|
|
14
15
|
<FilterSelect
|
|
@@ -118,6 +119,9 @@ const getSelect = (item: FilterComponent) => {
|
|
|
118
119
|
return Boolean(filter.value[item.valueName])
|
|
119
120
|
}
|
|
120
121
|
}
|
|
122
|
+
const handleOpened = () => {
|
|
123
|
+
uni.$emit('drop-opened')
|
|
124
|
+
}
|
|
121
125
|
</script>
|
|
122
126
|
|
|
123
127
|
<style lang="scss" scoped>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<wd-gap
|
|
3
|
+
:height="transformValueUnit(height)"
|
|
4
|
+
:safe-area-bottom="safeAreaBottom"
|
|
5
|
+
:bg-color="bgColor"
|
|
6
|
+
/>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script setup lang="ts">
|
|
10
|
+
import { LcbGapProps } from './types'
|
|
11
|
+
import { transformValueUnit } from '../../utils/transform'
|
|
12
|
+
defineOptions({
|
|
13
|
+
name: 'LcbGap',
|
|
14
|
+
options: {
|
|
15
|
+
addGlobalClass: true,
|
|
16
|
+
virtualHost: true,
|
|
17
|
+
styleIsolation: 'shared',
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
|
+
withDefaults(defineProps<LcbGapProps>(), {})
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<style lang="scss" scoped></style>
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<lcb-block
|
|
3
|
-
v-bind="{
|
|
4
|
-
marginTop,
|
|
5
|
-
marginBottom,
|
|
6
|
-
marginLeft: 12,
|
|
7
|
-
marginRight: 12,
|
|
8
|
-
}"
|
|
9
|
-
>
|
|
2
|
+
<lcb-block v-bind="$props">
|
|
10
3
|
<view
|
|
11
4
|
class="grid gap-2"
|
|
12
5
|
:style="{
|
|
@@ -17,8 +10,8 @@
|
|
|
17
10
|
v-for="(item, index) in items"
|
|
18
11
|
:key="index"
|
|
19
12
|
:src="item.url"
|
|
20
|
-
:height="height"
|
|
21
|
-
:radius="radius"
|
|
13
|
+
:height="transformValueUnit(height)"
|
|
14
|
+
:radius="transformValueUnit(radius)"
|
|
22
15
|
mode="aspectFill"
|
|
23
16
|
/>
|
|
24
17
|
</view>
|
|
@@ -27,6 +20,7 @@
|
|
|
27
20
|
|
|
28
21
|
<script setup lang="ts">
|
|
29
22
|
import { LcbGridProps } from './types'
|
|
23
|
+
import { transformValueUnit } from '../../utils/transform'
|
|
30
24
|
defineOptions({
|
|
31
25
|
name: 'LcbGrid',
|
|
32
26
|
options: {
|
|
@@ -36,6 +30,7 @@ defineOptions({
|
|
|
36
30
|
},
|
|
37
31
|
})
|
|
38
32
|
withDefaults(defineProps<LcbGridProps>(), {
|
|
33
|
+
marginHorizontal: 24,
|
|
39
34
|
height: 100,
|
|
40
35
|
cols: 2,
|
|
41
36
|
radius: 8,
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<lcb-block
|
|
3
|
-
|
|
4
|
-
:marginRight="12"
|
|
5
|
-
:radius="12"
|
|
6
|
-
backgroundColor="#fff"
|
|
7
|
-
:marginTop="-(marginTop || 0)"
|
|
8
|
-
>
|
|
9
|
-
<view class="flex w-full bg-#F5F6F9">
|
|
2
|
+
<lcb-block v-bind="$props">
|
|
3
|
+
<view class="flex w-full search-view overflow-hidden">
|
|
10
4
|
<view
|
|
11
5
|
v-for="(item, index) in tabs"
|
|
12
6
|
:key="item"
|
|
@@ -14,24 +8,34 @@
|
|
|
14
8
|
@click="current = index"
|
|
15
9
|
:class="{
|
|
16
10
|
active: current === index,
|
|
11
|
+
'active-left': index === current - 1,
|
|
12
|
+
'active-right': index === current + 1,
|
|
17
13
|
}"
|
|
18
14
|
>
|
|
19
15
|
{{ item }}
|
|
20
16
|
</view>
|
|
21
17
|
</view>
|
|
22
|
-
<view class="box-border px-3">
|
|
23
|
-
<view class="flex items-center justify-center mt-3 text-#333 gap-
|
|
24
|
-
<view class="text-
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
<view class="box-border px-3 leading-none">
|
|
19
|
+
<view class="flex items-center justify-center mt-3 text-#333 gap-16rpx">
|
|
20
|
+
<view class="text-30rpx font-bold">义乌</view>
|
|
21
|
+
<img
|
|
22
|
+
class="w-30rpx h-30rpx"
|
|
23
|
+
mode="aspectFit"
|
|
24
|
+
src="https://ddll-lycs.oss-cn-hangzhou.aliyuncs.com/default/1/20240914164446/%E5%BD%A2%E7%8A%B6%2092%402x.png"
|
|
25
|
+
/>
|
|
26
|
+
<view class="h-42rpx w-1px bg-#F1F1F1"></view>
|
|
27
|
+
<view class="text-#999 text-28rpx">{{ placeholder }}</view>
|
|
28
28
|
<view class="flex-1"></view>
|
|
29
29
|
<view class="justify-center flex flex-col items-center">
|
|
30
|
-
<
|
|
31
|
-
|
|
30
|
+
<img
|
|
31
|
+
class="w-30rpx h-30rpx"
|
|
32
|
+
mode="aspectFit"
|
|
33
|
+
src="https://ddll-lycs.oss-cn-hangzhou.aliyuncs.com/default/1/20240914164707/%E5%BD%A2%E7%8A%B6%2095%402x.png"
|
|
34
|
+
/>
|
|
35
|
+
<view class="text-26rpx text-#333 mt-12rpx">当前位置</view>
|
|
32
36
|
</view>
|
|
33
37
|
</view>
|
|
34
|
-
<view class="w-full h-
|
|
38
|
+
<view class="w-full h-1px bg-#F1F1F1 mt-26rpx mb-44rpx"></view>
|
|
35
39
|
<view class="flex items-center">
|
|
36
40
|
<view class="title">6月12日</view>
|
|
37
41
|
<view class="hint ml-1">今天入住</view>
|
|
@@ -40,14 +44,27 @@
|
|
|
40
44
|
<view class="hint ml-1 flex-1">明天离店</view>
|
|
41
45
|
<view class="tag">共1晚</view>
|
|
42
46
|
</view>
|
|
43
|
-
<wd-button type="primary" customClass="!w-full my-
|
|
44
|
-
<view
|
|
47
|
+
<wd-button type="primary" customClass="!w-full my-42rpx" size="large">搜索酒店</wd-button>
|
|
48
|
+
<view
|
|
49
|
+
class="px-50rpx flex justify-between items-center mb-42rpx text-#000 text-28rpx"
|
|
50
|
+
v-if="items?.length"
|
|
51
|
+
>
|
|
52
|
+
<view
|
|
53
|
+
v-for="item in items"
|
|
54
|
+
:key="item.title"
|
|
55
|
+
class="flex justify-center items-center gap-16rpx"
|
|
56
|
+
>
|
|
57
|
+
<img :src="item.url" class="w-36rpx h-36rpx" />
|
|
58
|
+
{{ item.title }}
|
|
59
|
+
</view>
|
|
60
|
+
</view>
|
|
45
61
|
</view>
|
|
46
62
|
</lcb-block>
|
|
47
63
|
</template>
|
|
48
64
|
|
|
49
65
|
<script setup lang="ts">
|
|
50
66
|
import { ref } from 'vue'
|
|
67
|
+
import { LcbHomeSearch } from './types'
|
|
51
68
|
|
|
52
69
|
defineOptions({
|
|
53
70
|
name: 'LcbHomeSearch',
|
|
@@ -58,37 +75,55 @@ defineOptions({
|
|
|
58
75
|
},
|
|
59
76
|
})
|
|
60
77
|
|
|
61
|
-
defineProps<
|
|
78
|
+
withDefaults(defineProps<LcbHomeSearch>(), {
|
|
79
|
+
marginHorizontal: 24,
|
|
80
|
+
backgroundColor: '#fff',
|
|
81
|
+
radius: 16,
|
|
82
|
+
placeholder: '位置|酒店|关键词',
|
|
83
|
+
})
|
|
62
84
|
const tabs = ['全部', '酒店', '民宿']
|
|
63
85
|
const current = ref(0)
|
|
64
86
|
</script>
|
|
65
87
|
<style lang="scss" scoped>
|
|
66
|
-
.search-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
.search-view {
|
|
89
|
+
border-radius: 16rpx;
|
|
90
|
+
.search-tab {
|
|
91
|
+
flex: 1;
|
|
92
|
+
text-align: center;
|
|
93
|
+
font-size: 30rpx;
|
|
94
|
+
padding: 24rpx 0;
|
|
95
|
+
color: #999;
|
|
96
|
+
background-color: #f5f6f9;
|
|
97
|
+
}
|
|
98
|
+
.active {
|
|
99
|
+
background-color: #fff;
|
|
100
|
+
color: #000;
|
|
101
|
+
font-weight: bold;
|
|
102
|
+
border-top-left-radius: 16rpx;
|
|
103
|
+
border-top-right-radius: 16rpx;
|
|
104
|
+
&-left {
|
|
105
|
+
border-bottom-right-radius: 16rpx;
|
|
106
|
+
}
|
|
107
|
+
&-right {
|
|
108
|
+
border-bottom-left-radius: 16rpx;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
77
111
|
}
|
|
112
|
+
|
|
78
113
|
.title {
|
|
79
|
-
font-weight:
|
|
80
|
-
font-size:
|
|
81
|
-
color: #
|
|
114
|
+
font-weight: bold;
|
|
115
|
+
font-size: 32rpx;
|
|
116
|
+
color: #000;
|
|
82
117
|
}
|
|
83
118
|
.hint {
|
|
84
|
-
font-size:
|
|
119
|
+
font-size: 24rpx;
|
|
85
120
|
color: #999;
|
|
86
121
|
}
|
|
87
122
|
.tag {
|
|
88
|
-
padding:
|
|
89
|
-
font-size:
|
|
123
|
+
padding: 5rpx 12rpx;
|
|
124
|
+
font-size: 20rpx;
|
|
90
125
|
color: #999;
|
|
91
126
|
background-color: #f1f1f1;
|
|
92
|
-
border-radius:
|
|
127
|
+
border-radius: 16rpx;
|
|
93
128
|
}
|
|
94
129
|
</style>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
v-for="(item, index) in items"
|
|
4
|
+
:key="index"
|
|
5
|
+
:class="styleGroup == 2 ? 'flex-1' : ''"
|
|
6
|
+
:style="{
|
|
7
|
+
marginLeft: transformValueUnit(styleGroup != 1 && index > 0 ? imageMargin : 0),
|
|
8
|
+
marginTop: transformValueUnit(styleGroup == 1 && index > 0 ? imageMargin : 0),
|
|
9
|
+
// marginLeft: transformValueUnit(styleGroup == 2 && index > 0 ? imageMargin : 0),
|
|
10
|
+
width: styleGroup == 3 ? transformValueUnit(imageSize) : 'auto',
|
|
11
|
+
}"
|
|
12
|
+
>
|
|
13
|
+
<view class="relative overflow-hidden">
|
|
14
|
+
<wd-img
|
|
15
|
+
v-if="!!item.url"
|
|
16
|
+
:width="`${styleGroup == 3 ? transformValueUnit(imageSize) : '100%'}`"
|
|
17
|
+
@click="item.mode == 1 && onClickItem(item)"
|
|
18
|
+
:src="item.url"
|
|
19
|
+
:enable-preview="enablePreview"
|
|
20
|
+
mode="widthFix"
|
|
21
|
+
:class="`${styleGroup == 3 ? 'overflow-hidden' : 'overflow-hidden block'}`"
|
|
22
|
+
:style="{
|
|
23
|
+
borderRadius: transformValueUnit(imageRadius),
|
|
24
|
+
display: 'block',
|
|
25
|
+
}"
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
<view
|
|
29
|
+
v-if="!item.url"
|
|
30
|
+
class="flex justify-center items-center bg-light color-gray overflow-hidden"
|
|
31
|
+
:style="{
|
|
32
|
+
height: transformValueUnit(styleGroup == 3 ? 300 : 400),
|
|
33
|
+
borderRadius: transformValueUnit(imageRadius),
|
|
34
|
+
}"
|
|
35
|
+
>
|
|
36
|
+
<wd-icon name="image" size="50px"></wd-icon>
|
|
37
|
+
</view>
|
|
38
|
+
|
|
39
|
+
<view
|
|
40
|
+
v-for="(each, edx) in item.hotSpot"
|
|
41
|
+
:key="edx"
|
|
42
|
+
class="link absolute"
|
|
43
|
+
:style="{
|
|
44
|
+
width: transformValueUnit(getRealSize(each.width)),
|
|
45
|
+
height: transformValueUnit(getRealSize(each.height)),
|
|
46
|
+
left: transformValueUnit(getRealSize(each.x)),
|
|
47
|
+
top: transformValueUnit(getRealSize(each.y)),
|
|
48
|
+
}"
|
|
49
|
+
>
|
|
50
|
+
<lcb-action-view v-bind="each.urlObj" />
|
|
51
|
+
</view>
|
|
52
|
+
</view>
|
|
53
|
+
</view>
|
|
54
|
+
</template>
|
|
55
|
+
|
|
56
|
+
<script setup lang="ts">
|
|
57
|
+
import { LcbImageProps } from '../types'
|
|
58
|
+
import { transformValueUnit } from '../../../utils/transform'
|
|
59
|
+
|
|
60
|
+
// defineProps<LcbImageProps>() @click="onClickItem(each.urlObj)"
|
|
61
|
+
|
|
62
|
+
function onClickItem(item: any) {
|
|
63
|
+
if (item?.link) {
|
|
64
|
+
uni.navigateTo({
|
|
65
|
+
url: item.link,
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const props = withDefaults(defineProps<LcbImageProps>(), {
|
|
71
|
+
imageMargin: 0,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
function getRealSize(size: number = 0) {
|
|
75
|
+
const mode = props.styleGroup
|
|
76
|
+
const lens = props.items?.length || 1
|
|
77
|
+
let realWidth = (mode === 1 ? 750 : mode === 2 ? 750 / lens : props.imageSize) || 0
|
|
78
|
+
if (mode !== 3 && props.marginHorizontal) realWidth -= props.marginHorizontal * 2
|
|
79
|
+
const imgSpan = props.imageMargin
|
|
80
|
+
if (mode === 2 && imgSpan) realWidth -= (lens - 1) / 2
|
|
81
|
+
return (realWidth / 375) * size
|
|
82
|
+
}
|
|
83
|
+
</script>
|
|
84
|
+
<style lang="scss" scoped>
|
|
85
|
+
.link {
|
|
86
|
+
.lcb-action-btn {
|
|
87
|
+
position: absolute;
|
|
88
|
+
width: 100%;
|
|
89
|
+
height: 100%;
|
|
90
|
+
top: 0;
|
|
91
|
+
bottom: 0;
|
|
92
|
+
left: 0;
|
|
93
|
+
right: 0;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
|
|
3
|
+
<view v-if="!items?.length" class="flex justify-center items-center bg-light color-gray overflow-hidden" :style="{
|
|
4
|
+
height: transformValueUnit(400),
|
|
5
|
+
borderRadius: transformValueUnit(imageRadius),
|
|
6
|
+
}"><wd-icon name="image" size="50px"></wd-icon></view>
|
|
7
|
+
|
|
8
|
+
<view v-if="styleGroup != 3" :class="styleGroup == 2 ? 'flex' : ''" :style="{
|
|
9
|
+
marginLeft: transformValueUnit(marginHorizontal),
|
|
10
|
+
marginRight: transformValueUnit(marginHorizontal),
|
|
11
|
+
marginTop: transformValueUnit(marginTop),
|
|
12
|
+
marginBottom: transformValueUnit(marginBottom),
|
|
13
|
+
}">
|
|
14
|
+
<!-- <view v-for="(item, index) in items" :key="index" :class="styleGroup == 2 ? 'flex-1 relative' : 'relative'" :style="{
|
|
15
|
+
marginTop: transformValueUnit(styleGroup == 1 && index > 0 ? imageMargin : 0),
|
|
16
|
+
marginLeft: transformValueUnit(styleGroup == 2 && index > 0 ? imageMargin : 0),
|
|
17
|
+
}">
|
|
18
|
+
<wd-img v-if="!!item.url" v-bind="{
|
|
19
|
+
src: item.url,
|
|
20
|
+
class: 'overflow-hidden block',
|
|
21
|
+
}" @click="onClickItem(item)" width="100%" :enable-preview="enablePreview" mode="widthFix" :style="{
|
|
22
|
+
borderRadius: transformValueUnit(imageRadius),
|
|
23
|
+
display: 'block',
|
|
24
|
+
}" />
|
|
25
|
+
<view v-if="!item.url" class="flex justify-center items-center bg-light color-gray overflow-hidden" :style="{
|
|
26
|
+
height: transformValueUnit(400),
|
|
27
|
+
borderRadius: transformValueUnit(imageRadius),
|
|
28
|
+
}"><wd-icon name="image" size="50px"></wd-icon></view>
|
|
29
|
+
</view> -->
|
|
30
|
+
<Image v-bind="imageProps" />
|
|
31
|
+
</view>
|
|
32
|
+
|
|
33
|
+
<scroll-view v-if="styleGroup == 3" scroll-x class="w-full whitespace-nowrap" :style="{
|
|
34
|
+
marginLeft: transformValueUnit(marginHorizontal),
|
|
35
|
+
marginRight: transformValueUnit(marginHorizontal),
|
|
36
|
+
marginTop: transformValueUnit(marginTop),
|
|
37
|
+
marginBottom: transformValueUnit(marginBottom),
|
|
38
|
+
}">
|
|
39
|
+
<view class="flex shrink-0">
|
|
40
|
+
<Image v-bind="imageProps" />
|
|
41
|
+
</view>
|
|
42
|
+
</scroll-view>
|
|
43
|
+
|
|
44
|
+
<!-- <view class="pl-20px pr-20px break-all">{{ JSON.stringify(iconItems) }}</view> -->
|
|
45
|
+
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<script setup lang="ts">
|
|
49
|
+
import { computed } from 'vue';
|
|
50
|
+
import { transformValueUnit } from '../../utils/transform'
|
|
51
|
+
import Image from './Image/index.vue'
|
|
52
|
+
import { LcbImageProps } from './types'
|
|
53
|
+
defineOptions({
|
|
54
|
+
name: 'LcbImage',
|
|
55
|
+
options: {
|
|
56
|
+
addGlobalClass: true,
|
|
57
|
+
virtualHost: true,
|
|
58
|
+
styleIsolation: 'shared',
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
const props = withDefaults(defineProps<LcbImageProps>(), {
|
|
62
|
+
styleGroup: 1,
|
|
63
|
+
imageMargin: 0,
|
|
64
|
+
imageSize: 300,
|
|
65
|
+
marginTop: 0,
|
|
66
|
+
marginBottom: 0,
|
|
67
|
+
marginHorizontal: 0,
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const imageProps = computed(() => {
|
|
71
|
+
return {
|
|
72
|
+
items: props.items,
|
|
73
|
+
imageSize: props.imageSize,
|
|
74
|
+
imageMargin: props.imageMargin,
|
|
75
|
+
imageRadius: props.imageRadius,
|
|
76
|
+
enablePreview: props.enablePreview,
|
|
77
|
+
styleGroup: props.styleGroup,
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
const iconItems = computed(() => {
|
|
82
|
+
console.log('props.items', props.items)
|
|
83
|
+
return props.items;
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ActionView } from 'action'
|
|
2
|
+
export interface LcbImageProps {
|
|
3
|
+
// Define the component's prop types here
|
|
4
|
+
items?: Partial<ActionView>[]
|
|
5
|
+
styleGroup?: number //1 纵向 2 横向 3 横向滚动
|
|
6
|
+
|
|
7
|
+
imageRadius?: number
|
|
8
|
+
itemPadding?: number
|
|
9
|
+
enablePreview?: boolean
|
|
10
|
+
marginHorizontal?: number
|
|
11
|
+
imageMargin?: number
|
|
12
|
+
imageSize?: number
|
|
13
|
+
marginTop?: number
|
|
14
|
+
marginBottom?: number
|
|
15
|
+
}
|