@tplc/business 0.0.39 → 0.0.41
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 +21 -0
- package/components/lcb-list/components/FilterList/index.vue +7 -2
- package/components/lcb-list/lcb-list.vue +4 -2
- package/components/lcb-nav/lcb-nav.vue +8 -8
- package/components/lcb-product/lcb-product.vue +29 -19
- package/components/lcb-product/types.ts +3 -5
- package/components/lcb-product-item/components/ItemValue.vue +115 -0
- package/components/lcb-product-item/lcb-product-item.vue +54 -130
- package/components/lcb-product-item/types.ts +15 -17
- package/package.json +1 -1
- package/types/components/lcb-product/lcb-product.vue.d.ts +3 -0
- package/types/components/lcb-product/types.d.ts +3 -1
- package/types/components/lcb-product-item/components/ItemValue.vue.d.ts +55 -0
- package/types/components/lcb-product-item/lcb-product-item.vue.d.ts +38 -23
- package/types/components/lcb-product-item/types.d.ts +14 -1
- package/types/utils/createReuse.d.ts +0 -59
- package/utils/createReuse.tsx +0 -121
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.0.41](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/compare/v0.0.40...v0.0.41) (2024-10-25)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ✨ Features | 新功能
|
|
9
|
+
|
|
10
|
+
* sticky 兼容小程序 ([c179ae0](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/c179ae0d276d51e91fe6d7cc3cadb57bf238c969))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### 🐛 Bug Fixes | Bug 修复
|
|
14
|
+
|
|
15
|
+
* filter颜色 ([ca3cd9c](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/ca3cd9ca596306580e06305eabad4e5e7ad44d1f))
|
|
16
|
+
* nav 兼容statusbar ([322e6d4](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/322e6d46d7bd8c32e45e2236064d8ed16ac0793c))
|
|
17
|
+
|
|
18
|
+
### [0.0.40](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/compare/v0.0.39...v0.0.40) (2024-10-24)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### ✨ Features | 新功能
|
|
22
|
+
|
|
23
|
+
* 增加 list 组件可配置性 ([8f3bc26](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/8f3bc267f965cd74e66ab714f0713440a9d64451))
|
|
24
|
+
* 消除 product-item reuse 代码 ([32eee08](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/32eee089a360c4d8c32207eaee083f5f1646e7c5))
|
|
25
|
+
|
|
5
26
|
### [0.0.39](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/compare/v0.0.38...v0.0.39) (2024-10-23)
|
|
6
27
|
|
|
7
28
|
|
|
@@ -7,15 +7,20 @@
|
|
|
7
7
|
@query="queryList"
|
|
8
8
|
use-page-scroll
|
|
9
9
|
>
|
|
10
|
-
<lcb-product
|
|
10
|
+
<lcb-product
|
|
11
|
+
v-bind="{ ...productProps, ...attrs }"
|
|
12
|
+
:listType="listType"
|
|
13
|
+
:items="normalizeDataList"
|
|
14
|
+
/>
|
|
11
15
|
</z-paging>
|
|
12
16
|
</template>
|
|
13
17
|
|
|
14
18
|
<script setup lang="ts">
|
|
15
|
-
import { computed, ref, watch } from 'vue'
|
|
19
|
+
import { computed, ref, watch, useAttrs } from 'vue'
|
|
16
20
|
import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging'
|
|
17
21
|
import { LcbFilterListProps } from './type'
|
|
18
22
|
import { formatJson } from '../../../../utils/utils'
|
|
23
|
+
const attrs = useAttrs()
|
|
19
24
|
|
|
20
25
|
defineOptions({
|
|
21
26
|
name: 'FilterList',
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
:class="{
|
|
6
6
|
'lcb-filter__border-top': showPlain ? false : border,
|
|
7
7
|
'lcb-filter__plain': showPlain,
|
|
8
|
+
'!bg-white': !showPlain,
|
|
8
9
|
}"
|
|
9
10
|
class="w-100vw"
|
|
10
11
|
>
|
|
@@ -67,12 +68,12 @@
|
|
|
67
68
|
</view>
|
|
68
69
|
</wd-sticky>
|
|
69
70
|
|
|
70
|
-
<FilterList v-bind="{ ...info.listInfo, listType, filter }" test2="11" />
|
|
71
|
+
<FilterList v-bind="{ ...info.listInfo, listType, filter, ...attrs }" test2="11" />
|
|
71
72
|
</view>
|
|
72
73
|
</template>
|
|
73
74
|
|
|
74
75
|
<script setup lang="ts">
|
|
75
|
-
import { computed, inject, Ref, ref, watch } from 'vue'
|
|
76
|
+
import { computed, inject, Ref, ref, watch, useAttrs } from 'vue'
|
|
76
77
|
import { LcbListProps, defaultLcbListProps } from './types'
|
|
77
78
|
import { FilterComponent, getFilterDetail, LcbFilterResult } from './api'
|
|
78
79
|
import FilterSelect from './components/FilterSelect/index.vue'
|
|
@@ -83,6 +84,7 @@ import FilterList from './components/FilterList/index.vue'
|
|
|
83
84
|
import FilterTabs from './components/FilterTabs/index.vue'
|
|
84
85
|
import './index.scss'
|
|
85
86
|
import { FORM_KEY } from '../../constants'
|
|
87
|
+
const attrs = useAttrs()
|
|
86
88
|
|
|
87
89
|
defineOptions({
|
|
88
90
|
name: 'LcbList',
|
|
@@ -9,20 +9,20 @@
|
|
|
9
9
|
paddingTop,
|
|
10
10
|
}"
|
|
11
11
|
>
|
|
12
|
+
<view
|
|
13
|
+
class="navbar-header-background"
|
|
14
|
+
:style="{
|
|
15
|
+
backgroundColor: navbarBgColor,
|
|
16
|
+
opacity: navbarBgOpacity,
|
|
17
|
+
backgroundImage: backgroundType === 'img' ? `url(${backgroundImage})` : '',
|
|
18
|
+
}"
|
|
19
|
+
/>
|
|
12
20
|
<view
|
|
13
21
|
class="navbar-header"
|
|
14
22
|
:style="{
|
|
15
23
|
color: contentColor,
|
|
16
24
|
}"
|
|
17
25
|
>
|
|
18
|
-
<view
|
|
19
|
-
class="navbar-header-background"
|
|
20
|
-
:style="{
|
|
21
|
-
backgroundColor: navbarBgColor,
|
|
22
|
-
opacity: navbarBgOpacity,
|
|
23
|
-
backgroundImage: backgroundType === 'img' ? `url(${backgroundImage})` : '',
|
|
24
|
-
}"
|
|
25
|
-
/>
|
|
26
26
|
<!-- 左边布局 -->
|
|
27
27
|
<view class="navbar-left z-1">
|
|
28
28
|
<!-- 返回按钮 -->
|
|
@@ -1,20 +1,44 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, useAttrs } from 'vue'
|
|
3
|
+
import { LcbProductProps } from './types'
|
|
4
|
+
const attrs = useAttrs()
|
|
5
|
+
defineOptions({
|
|
6
|
+
name: 'LcbProduct',
|
|
7
|
+
options: {
|
|
8
|
+
addGlobalClass: true,
|
|
9
|
+
virtualHost: true,
|
|
10
|
+
styleIsolation: 'shared',
|
|
11
|
+
},
|
|
12
|
+
})
|
|
13
|
+
const props = withDefaults(defineProps<LcbProductProps>(), {
|
|
14
|
+
listType: 'list',
|
|
15
|
+
items: [],
|
|
16
|
+
imageWidthPercent: (1 / 3) * 100,
|
|
17
|
+
imageHeightPercent: (300 / 560) * 100,
|
|
18
|
+
itemHeight: 560,
|
|
19
|
+
} as any)
|
|
20
|
+
</script>
|
|
21
|
+
|
|
1
22
|
<template>
|
|
2
23
|
<lcb-block v-bind="$props">
|
|
3
24
|
<view class="flex flex-col gap-2 p-2" v-if="listType === 'list'">
|
|
4
25
|
<view v-for="(item, index) in items" :key="`${item?.productId}:${index}`">
|
|
5
|
-
<lcb-product-item
|
|
26
|
+
<lcb-product-item
|
|
27
|
+
v-bind="{ ...item, ...attrs }"
|
|
28
|
+
:imageStyle="{ width: `${imageWidthPercent}%` }"
|
|
29
|
+
/>
|
|
6
30
|
</view>
|
|
7
31
|
</view>
|
|
8
32
|
|
|
9
33
|
<view class="flex p-1 flex-wrap" v-if="listType === 'grid'">
|
|
10
34
|
<view v-for="(item, index) in items" :key="`${item?.productId}:${index}`" class="w-1/2">
|
|
11
35
|
<view class="p-1 overflow-hidden">
|
|
12
|
-
<view class="rounded overflow-hidden
|
|
36
|
+
<view class="rounded overflow-hidden" :style="{ height: `${itemHeight}rpx` }">
|
|
13
37
|
<lcb-product-item
|
|
14
|
-
v-bind="item"
|
|
38
|
+
v-bind="{ ...item, ...attrs }"
|
|
15
39
|
layoutType="vertical"
|
|
16
|
-
|
|
17
|
-
|
|
40
|
+
className="!h-full"
|
|
41
|
+
:imageStyle="{ height: `${imageHeightPercent}%` }"
|
|
18
42
|
/>
|
|
19
43
|
</view>
|
|
20
44
|
</view>
|
|
@@ -35,18 +59,4 @@
|
|
|
35
59
|
</lcb-block>
|
|
36
60
|
</template>
|
|
37
61
|
|
|
38
|
-
<script setup lang="ts">
|
|
39
|
-
import { computed } from 'vue'
|
|
40
|
-
import { LcbProductProps, defaultLcbProductProps } from './types'
|
|
41
|
-
defineOptions({
|
|
42
|
-
name: 'LcbProduct',
|
|
43
|
-
options: {
|
|
44
|
-
addGlobalClass: true,
|
|
45
|
-
virtualHost: true,
|
|
46
|
-
styleIsolation: 'shared',
|
|
47
|
-
},
|
|
48
|
-
})
|
|
49
|
-
const props = withDefaults(defineProps<LcbProductProps>(), defaultLcbProductProps as any)
|
|
50
|
-
</script>
|
|
51
|
-
|
|
52
62
|
<style lang="scss" scoped></style>
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export interface LcbProductProps {
|
|
2
2
|
// Define the component's prop types here
|
|
3
3
|
listType?: 'list' | 'horizontal' | 'grid' | 'waterfall' // 1列表 2 左右滑动 3一行两个 4瀑布流
|
|
4
|
+
imageWidthPercent?: number
|
|
5
|
+
imageHeightPercent?: number
|
|
6
|
+
itemHeight?: number // 列表项高度
|
|
4
7
|
items?: Record<string, any>[]
|
|
5
8
|
}
|
|
6
|
-
|
|
7
|
-
export const defaultLcbProductProps: LcbProductProps = {
|
|
8
|
-
listType: 'list',
|
|
9
|
-
items: [],
|
|
10
|
-
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { inject, computed, useAttrs } from 'vue'
|
|
3
|
+
import { isArray } from '@tplc/wot/components/common/util'
|
|
4
|
+
|
|
5
|
+
// const attrs = useAttrs()
|
|
6
|
+
|
|
7
|
+
const itemProps = inject('lcb-product-item-props')
|
|
8
|
+
|
|
9
|
+
const props = withDefaults(
|
|
10
|
+
defineProps<{
|
|
11
|
+
prop: string
|
|
12
|
+
className?: string
|
|
13
|
+
}>(),
|
|
14
|
+
{},
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
const visible = computed(() => {
|
|
18
|
+
return itemProps?.[`${props?.prop}Visible`] ?? true
|
|
19
|
+
})
|
|
20
|
+
const className = computed(() => {
|
|
21
|
+
return `${itemProps?.[`${props?.prop}Class`] ?? ''} ${props?.className}`
|
|
22
|
+
})
|
|
23
|
+
const style = computed(() => {
|
|
24
|
+
return itemProps?.[`${props?.prop}Style`] ?? ''
|
|
25
|
+
})
|
|
26
|
+
const value = computed(() => {
|
|
27
|
+
return itemProps?.[props?.prop]
|
|
28
|
+
})
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<template v-if="visible && !!value && (isArray(value) ? value?.length > 0 : true)">
|
|
33
|
+
<!-- 图片 -->
|
|
34
|
+
<view v-if="prop === 'image'" :value="value" :class="className" :style="style">
|
|
35
|
+
<image :src="value" class="w-full h-full" mode="aspectFill" />
|
|
36
|
+
</view>
|
|
37
|
+
|
|
38
|
+
<!-- 标题 -->
|
|
39
|
+
<view
|
|
40
|
+
v-if="prop === 'title'"
|
|
41
|
+
:class="className"
|
|
42
|
+
:style="style"
|
|
43
|
+
:value="value"
|
|
44
|
+
class="text-ellipsis line-clamp-2"
|
|
45
|
+
>
|
|
46
|
+
<view>{{ value }}</view>
|
|
47
|
+
</view>
|
|
48
|
+
|
|
49
|
+
<!-- 位置 -->
|
|
50
|
+
<view
|
|
51
|
+
:class="className"
|
|
52
|
+
:style="style"
|
|
53
|
+
v-if="prop === 'location'"
|
|
54
|
+
:value="value"
|
|
55
|
+
class="text-gray-500 text-22rpx flex gap-3rpx items-center"
|
|
56
|
+
>
|
|
57
|
+
<wd-icon name="location" size="32rpx"></wd-icon>
|
|
58
|
+
<view>{{ value }}</view>
|
|
59
|
+
</view>
|
|
60
|
+
|
|
61
|
+
<!-- 标签 -->
|
|
62
|
+
<view
|
|
63
|
+
:class="className"
|
|
64
|
+
:style="style"
|
|
65
|
+
v-if="prop === 'tags'"
|
|
66
|
+
:value="value"
|
|
67
|
+
class="flex gap-1 whitespace-nowrap overflow-auto"
|
|
68
|
+
>
|
|
69
|
+
<wd-tag
|
|
70
|
+
v-for="tag in value"
|
|
71
|
+
:key="tag"
|
|
72
|
+
class="!text-20rpx"
|
|
73
|
+
:class="className"
|
|
74
|
+
:style="style"
|
|
75
|
+
plain
|
|
76
|
+
type="primary"
|
|
77
|
+
>
|
|
78
|
+
{{ tag }}
|
|
79
|
+
</wd-tag>
|
|
80
|
+
</view>
|
|
81
|
+
|
|
82
|
+
<!-- 价格单位 -->
|
|
83
|
+
<view
|
|
84
|
+
:class="className"
|
|
85
|
+
:style="style"
|
|
86
|
+
v-if="prop === 'priceUnit'"
|
|
87
|
+
:value="value"
|
|
88
|
+
class="text-red-500 font-bold text-22rpx"
|
|
89
|
+
>
|
|
90
|
+
<view>{{ value }}</view>
|
|
91
|
+
</view>
|
|
92
|
+
|
|
93
|
+
<!-- 价格 -->
|
|
94
|
+
<view
|
|
95
|
+
:class="className"
|
|
96
|
+
:style="style"
|
|
97
|
+
v-if="prop === 'price'"
|
|
98
|
+
:value="value"
|
|
99
|
+
class="text-red-500 font-bold text-27rpx"
|
|
100
|
+
>
|
|
101
|
+
<view>{{ value }}</view>
|
|
102
|
+
</view>
|
|
103
|
+
|
|
104
|
+
<!-- 价格后缀 -->
|
|
105
|
+
<view
|
|
106
|
+
:class="className"
|
|
107
|
+
:style="style"
|
|
108
|
+
v-if="prop === 'priceSuffix'"
|
|
109
|
+
:value="value"
|
|
110
|
+
class="text-22rpx"
|
|
111
|
+
>
|
|
112
|
+
<view>{{ value }}</view>
|
|
113
|
+
</view>
|
|
114
|
+
</template>
|
|
115
|
+
</template>
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, useAttrs } from 'vue'
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import { formatJson } from '../../utils/utils'
|
|
6
|
-
import { createReusableTemplate } from '../../utils/createReuse'
|
|
7
|
-
import { isArray } from '@tplc/wot/components/common/util'
|
|
8
|
-
|
|
9
|
-
const [DefineMainContent, MainContent] = createReusableTemplate()
|
|
10
|
-
const [DefineSectionWrapper, SectionWrapper] = createReusableTemplate()
|
|
11
|
-
const [DefineSection, Section] = createReusableTemplate()
|
|
12
|
-
const [DefineSectionGroup, SectionGroup] = createReusableTemplate()
|
|
2
|
+
import { computed, provide, useAttrs } from 'vue'
|
|
3
|
+
import { LcbProductItemProps } from './types'
|
|
4
|
+
import ItemValue from './components/ItemValue.vue'
|
|
13
5
|
|
|
14
6
|
defineOptions({
|
|
15
7
|
name: 'LcbProductItem',
|
|
@@ -20,140 +12,72 @@ defineOptions({
|
|
|
20
12
|
},
|
|
21
13
|
})
|
|
22
14
|
|
|
23
|
-
const props = withDefaults(defineProps<LcbProductItemProps>(),
|
|
15
|
+
const props = withDefaults(defineProps<LcbProductItemProps>(), {
|
|
16
|
+
layoutType: 'horizontal',
|
|
17
|
+
priceUnit: '¥',
|
|
18
|
+
originPriceUnit: '¥',
|
|
19
|
+
imageVisible: true,
|
|
20
|
+
titleVisible: true,
|
|
21
|
+
subTitleVisible: true,
|
|
22
|
+
priceVisible: true,
|
|
23
|
+
priceUnitVisible: true,
|
|
24
|
+
priceSuffixVisible: true,
|
|
25
|
+
originPriceVisible: true,
|
|
26
|
+
originPriceUnitVisible: true,
|
|
27
|
+
tagsVisible: true,
|
|
28
|
+
locationVisible: true,
|
|
29
|
+
distanceVisible: true,
|
|
30
|
+
})
|
|
24
31
|
const attrs = useAttrs()
|
|
25
32
|
|
|
33
|
+
provide('lcb-product-item-props', props)
|
|
34
|
+
|
|
26
35
|
// console.log('attrs', attrs)
|
|
27
36
|
</script>
|
|
28
37
|
|
|
29
38
|
<template>
|
|
30
|
-
<!--
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
:class="[className, props?.[`${prop}Class`]]"
|
|
39
|
-
>
|
|
40
|
-
<component v-if="!!$slots.default" :is="$slots.default" />
|
|
41
|
-
<view v-else>{{ props?.[`${prop}`] }}</view>
|
|
42
|
-
</view>
|
|
43
|
-
</DefineSectionWrapper>
|
|
44
|
-
|
|
45
|
-
<!-- 定义各个内容展示节点 -->
|
|
46
|
-
<DefineSection v-slot="{ prop, class: className }">
|
|
47
|
-
<!-- 图片 -->
|
|
48
|
-
<SectionWrapper v-if="prop === 'image'" prop="image" :class="className">
|
|
49
|
-
<image :src="image" class="w-full h-full" mode="aspectFill" />
|
|
50
|
-
</SectionWrapper>
|
|
51
|
-
|
|
52
|
-
<!-- 标题 -->
|
|
53
|
-
<SectionWrapper
|
|
54
|
-
:class="className"
|
|
55
|
-
v-if="prop === 'title'"
|
|
56
|
-
prop="title"
|
|
57
|
-
class="text-ellipsis line-clamp-2"
|
|
58
|
-
/>
|
|
59
|
-
|
|
60
|
-
<!-- 位置 -->
|
|
61
|
-
<SectionWrapper
|
|
62
|
-
:class="className"
|
|
63
|
-
v-if="prop === 'location'"
|
|
64
|
-
prop="location"
|
|
65
|
-
class="text-gray-500 text-22rpx flex gap-3rpx items-center"
|
|
66
|
-
>
|
|
67
|
-
<wd-icon name="location" size="32rpx"></wd-icon>
|
|
68
|
-
<view>{{ location }}</view>
|
|
69
|
-
</SectionWrapper>
|
|
70
|
-
|
|
71
|
-
<!-- 标签 -->
|
|
72
|
-
<SectionWrapper
|
|
73
|
-
:class="className"
|
|
74
|
-
v-if="prop === 'tags'"
|
|
75
|
-
prop="tags"
|
|
76
|
-
class="flex gap-1 whitespace-nowrap overflow-auto"
|
|
77
|
-
>
|
|
78
|
-
<wd-tag
|
|
79
|
-
v-for="tag in tags"
|
|
80
|
-
:key="tag"
|
|
81
|
-
class="!text-20rpx"
|
|
82
|
-
:class="tagsClass"
|
|
83
|
-
plain
|
|
84
|
-
type="primary"
|
|
85
|
-
>
|
|
86
|
-
{{ tag }}
|
|
87
|
-
</wd-tag>
|
|
88
|
-
</SectionWrapper>
|
|
89
|
-
|
|
90
|
-
<!-- 价格单位 -->
|
|
91
|
-
<SectionWrapper
|
|
92
|
-
:class="className"
|
|
93
|
-
v-if="prop === 'priceUnit'"
|
|
94
|
-
prop="priceUnit"
|
|
95
|
-
class="text-red-500 font-bold text-22rpx"
|
|
96
|
-
/>
|
|
97
|
-
|
|
98
|
-
<!-- 价格 -->
|
|
99
|
-
<SectionWrapper
|
|
100
|
-
:class="className"
|
|
101
|
-
v-if="prop === 'price'"
|
|
102
|
-
prop="price"
|
|
103
|
-
class="text-red-500 font-bold text-27rpx"
|
|
104
|
-
/>
|
|
105
|
-
|
|
106
|
-
<!-- 价格后缀 -->
|
|
107
|
-
<SectionWrapper
|
|
108
|
-
:class="className"
|
|
109
|
-
v-if="prop === 'priceSuffix'"
|
|
110
|
-
prop="priceSuffix"
|
|
111
|
-
class="text-22rpx"
|
|
112
|
-
/>
|
|
113
|
-
|
|
114
|
-
<!-- 价格区域 -->
|
|
115
|
-
</DefineSection>
|
|
39
|
+
<!-- 横向布局 -->
|
|
40
|
+
<view v-if="layoutType === 'horizontal'" :class="className" class="flex gap-3 px-2 py-3 bg-white">
|
|
41
|
+
<ItemValue prop="image" className="w-1/3 h-220rpx bg-gray-100 rounded-sm overflow-hidden" />
|
|
42
|
+
<view class="flex flex-col flex-1 gap-2 justify-between text-26rpx overflow-hidden">
|
|
43
|
+
<view class="flex flex-col gap-2 overflow-hidden">
|
|
44
|
+
<ItemValue v-for="prop in ['title', 'location', 'tags']" :prop="prop" :key="prop" />
|
|
45
|
+
</view>
|
|
116
46
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
47
|
+
<view class="flex gap-2">
|
|
48
|
+
<view class="flex gap-[4rpx] items-end">
|
|
49
|
+
<ItemValue
|
|
50
|
+
v-for="prop in ['priceUnit', 'price', 'priceSuffix']"
|
|
51
|
+
:prop="prop"
|
|
52
|
+
:key="prop"
|
|
53
|
+
/>
|
|
54
|
+
</view>
|
|
55
|
+
</view>
|
|
121
56
|
</view>
|
|
122
|
-
</
|
|
57
|
+
</view>
|
|
123
58
|
|
|
124
|
-
<!--
|
|
125
|
-
<
|
|
59
|
+
<!-- 竖向布局 -->
|
|
60
|
+
<view v-if="layoutType === 'vertical'" :class="className" class="flex flex-col gap-2 bg-white">
|
|
61
|
+
<ItemValue prop="image" className="overflow-hidden" />
|
|
126
62
|
<view
|
|
127
|
-
:class="
|
|
63
|
+
:class="'p-2'"
|
|
128
64
|
class="flex flex-col flex-1 gap-2 justify-between text-26rpx overflow-hidden"
|
|
129
65
|
>
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
66
|
+
<view class="flex flex-col gap-2 overflow-hidden">
|
|
67
|
+
<!-- <ItemValue prop="title"></ItemValue> -->
|
|
68
|
+
<ItemValue v-for="prop in ['title', 'location', 'tags']" :prop="prop" :key="prop" />
|
|
69
|
+
</view>
|
|
70
|
+
|
|
134
71
|
<view class="flex gap-2">
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
72
|
+
<view class="flex gap-[4rpx] items-end">
|
|
73
|
+
<ItemValue
|
|
74
|
+
v-for="prop in ['priceUnit', 'price', 'priceSuffix']"
|
|
75
|
+
:prop="prop"
|
|
76
|
+
:key="prop"
|
|
77
|
+
/>
|
|
78
|
+
</view>
|
|
139
79
|
</view>
|
|
140
80
|
</view>
|
|
141
|
-
</DefineMainContent>
|
|
142
|
-
|
|
143
|
-
<!-- 横向布局 -->
|
|
144
|
-
<view
|
|
145
|
-
v-if="layoutType === 'horizontal'"
|
|
146
|
-
:class="attrs?.class"
|
|
147
|
-
class="flex gap-3 px-2 py-3 bg-white"
|
|
148
|
-
>
|
|
149
|
-
<Section prop="image" class="w-1/3 h-220rpx bg-gray-100 rounded-sm overflow-hidden" />
|
|
150
|
-
<MainContent />
|
|
151
|
-
</view>
|
|
152
|
-
|
|
153
|
-
<!-- 竖向布局 -->
|
|
154
|
-
<view v-if="layoutType === 'vertical'" :class="attrs?.class" class="flex flex-col gap-2 bg-white">
|
|
155
|
-
<Section prop="image" class="overflow-hidden" />
|
|
156
|
-
<MainContent class="p-2" />
|
|
157
81
|
</view>
|
|
158
82
|
</template>
|
|
159
83
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { CSSProperties } from 'vue'
|
|
2
|
+
|
|
1
3
|
export interface LcbProductItemProps {
|
|
2
4
|
// Define the component's prop types here
|
|
3
|
-
|
|
5
|
+
className?: string
|
|
4
6
|
layoutType?: 'vertical' | 'horizontal'
|
|
5
7
|
image?: any
|
|
6
8
|
title?: any
|
|
@@ -38,21 +40,17 @@ export interface LcbProductItemProps {
|
|
|
38
40
|
tagsWrapperClass?: string
|
|
39
41
|
locationClass?: string
|
|
40
42
|
distanceClass?: string
|
|
41
|
-
}
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
tagsVisible: true,
|
|
56
|
-
locationVisible: true,
|
|
57
|
-
distanceVisible: true,
|
|
44
|
+
imageStyle?: CSSProperties
|
|
45
|
+
titleStyle?: CSSProperties
|
|
46
|
+
subTitleStyle?: CSSProperties
|
|
47
|
+
priceStyle?: CSSProperties
|
|
48
|
+
priceUnitStyle?: CSSProperties
|
|
49
|
+
priceSuffixStyle?: CSSProperties
|
|
50
|
+
originPriceStyle?: CSSProperties
|
|
51
|
+
originPriceUnitStyle?: CSSProperties
|
|
52
|
+
tagsStyle?: CSSProperties
|
|
53
|
+
tagsWrapperStyle?: CSSProperties
|
|
54
|
+
locationStyle?: CSSProperties
|
|
55
|
+
distanceStyle?: CSSProperties
|
|
58
56
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export interface LcbProductProps {
|
|
2
2
|
listType?: 'list' | 'horizontal' | 'grid' | 'waterfall'
|
|
3
|
+
imageWidthPercent?: number
|
|
4
|
+
imageHeightPercent?: number
|
|
5
|
+
itemHeight?: number
|
|
3
6
|
items?: Record<string, any>[]
|
|
4
7
|
}
|
|
5
|
-
export declare const defaultLcbProductProps: LcbProductProps
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<
|
|
2
|
+
__VLS_WithDefaults<
|
|
3
|
+
__VLS_TypePropsToOption<{
|
|
4
|
+
prop: string
|
|
5
|
+
className?: string
|
|
6
|
+
}>,
|
|
7
|
+
{}
|
|
8
|
+
>,
|
|
9
|
+
{},
|
|
10
|
+
unknown,
|
|
11
|
+
{},
|
|
12
|
+
{},
|
|
13
|
+
import('vue').ComponentOptionsMixin,
|
|
14
|
+
import('vue').ComponentOptionsMixin,
|
|
15
|
+
{},
|
|
16
|
+
string,
|
|
17
|
+
import('vue').PublicProps,
|
|
18
|
+
Readonly<
|
|
19
|
+
import('vue').ExtractPropTypes<
|
|
20
|
+
__VLS_WithDefaults<
|
|
21
|
+
__VLS_TypePropsToOption<{
|
|
22
|
+
prop: string
|
|
23
|
+
className?: string
|
|
24
|
+
}>,
|
|
25
|
+
{}
|
|
26
|
+
>
|
|
27
|
+
>
|
|
28
|
+
>,
|
|
29
|
+
{},
|
|
30
|
+
{}
|
|
31
|
+
>
|
|
32
|
+
export default _default
|
|
33
|
+
type __VLS_WithDefaults<P, D> = {
|
|
34
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D
|
|
35
|
+
? __VLS_Prettify<
|
|
36
|
+
P[K] & {
|
|
37
|
+
default: D[K]
|
|
38
|
+
}
|
|
39
|
+
>
|
|
40
|
+
: P[K]
|
|
41
|
+
}
|
|
42
|
+
type __VLS_Prettify<T> = {
|
|
43
|
+
[K in keyof T]: T[K]
|
|
44
|
+
} & {}
|
|
45
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T
|
|
46
|
+
type __VLS_TypePropsToOption<T> = {
|
|
47
|
+
[K in keyof T]-?: {} extends Pick<T, K>
|
|
48
|
+
? {
|
|
49
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>
|
|
50
|
+
}
|
|
51
|
+
: {
|
|
52
|
+
type: import('vue').PropType<T[K]>
|
|
53
|
+
required: true
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { LcbProductItemProps } from './types'
|
|
2
2
|
declare const _default: import('vue').DefineComponent<
|
|
3
|
-
__VLS_WithDefaults<
|
|
3
|
+
__VLS_WithDefaults<
|
|
4
|
+
__VLS_TypePropsToOption<LcbProductItemProps>,
|
|
5
|
+
{
|
|
6
|
+
layoutType: string
|
|
7
|
+
priceUnit: string
|
|
8
|
+
originPriceUnit: string
|
|
9
|
+
imageVisible: boolean
|
|
10
|
+
titleVisible: boolean
|
|
11
|
+
subTitleVisible: boolean
|
|
12
|
+
priceVisible: boolean
|
|
13
|
+
priceUnitVisible: boolean
|
|
14
|
+
priceSuffixVisible: boolean
|
|
15
|
+
originPriceVisible: boolean
|
|
16
|
+
originPriceUnitVisible: boolean
|
|
17
|
+
tagsVisible: boolean
|
|
18
|
+
locationVisible: boolean
|
|
19
|
+
distanceVisible: boolean
|
|
20
|
+
}
|
|
21
|
+
>,
|
|
4
22
|
{},
|
|
5
23
|
unknown,
|
|
6
24
|
{},
|
|
@@ -12,23 +30,31 @@ declare const _default: import('vue').DefineComponent<
|
|
|
12
30
|
import('vue').PublicProps,
|
|
13
31
|
Readonly<
|
|
14
32
|
import('vue').ExtractPropTypes<
|
|
15
|
-
__VLS_WithDefaults<
|
|
33
|
+
__VLS_WithDefaults<
|
|
34
|
+
__VLS_TypePropsToOption<LcbProductItemProps>,
|
|
35
|
+
{
|
|
36
|
+
layoutType: string
|
|
37
|
+
priceUnit: string
|
|
38
|
+
originPriceUnit: string
|
|
39
|
+
imageVisible: boolean
|
|
40
|
+
titleVisible: boolean
|
|
41
|
+
subTitleVisible: boolean
|
|
42
|
+
priceVisible: boolean
|
|
43
|
+
priceUnitVisible: boolean
|
|
44
|
+
priceSuffixVisible: boolean
|
|
45
|
+
originPriceVisible: boolean
|
|
46
|
+
originPriceUnitVisible: boolean
|
|
47
|
+
tagsVisible: boolean
|
|
48
|
+
locationVisible: boolean
|
|
49
|
+
distanceVisible: boolean
|
|
50
|
+
}
|
|
51
|
+
>
|
|
16
52
|
>
|
|
17
53
|
>,
|
|
18
54
|
{
|
|
19
|
-
title: any
|
|
20
|
-
image: any
|
|
21
|
-
location: any
|
|
22
55
|
layoutType: 'vertical' | 'horizontal'
|
|
23
|
-
imageClass: string
|
|
24
|
-
subTitle: any
|
|
25
|
-
price: any
|
|
26
56
|
priceUnit: any
|
|
27
|
-
priceSuffix: any
|
|
28
|
-
originPrice: any
|
|
29
57
|
originPriceUnit: any
|
|
30
|
-
tags: any
|
|
31
|
-
distance: any
|
|
32
58
|
imageVisible: boolean
|
|
33
59
|
titleVisible: boolean
|
|
34
60
|
subTitleVisible: boolean
|
|
@@ -40,17 +66,6 @@ declare const _default: import('vue').DefineComponent<
|
|
|
40
66
|
tagsVisible: boolean
|
|
41
67
|
locationVisible: boolean
|
|
42
68
|
distanceVisible: boolean
|
|
43
|
-
titleClass: string
|
|
44
|
-
subTitleClass: string
|
|
45
|
-
priceClass: string
|
|
46
|
-
priceUnitClass: string
|
|
47
|
-
priceSuffixClass: string
|
|
48
|
-
originPriceClass: string
|
|
49
|
-
originPriceUnitClass: string
|
|
50
|
-
tagsClass: string
|
|
51
|
-
tagsWrapperClass: string
|
|
52
|
-
locationClass: string
|
|
53
|
-
distanceClass: string
|
|
54
69
|
},
|
|
55
70
|
{}
|
|
56
71
|
>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { CSSProperties } from 'vue'
|
|
1
2
|
export interface LcbProductItemProps {
|
|
3
|
+
className?: string
|
|
2
4
|
layoutType?: 'vertical' | 'horizontal'
|
|
3
5
|
image?: any
|
|
4
6
|
title?: any
|
|
@@ -34,5 +36,16 @@ export interface LcbProductItemProps {
|
|
|
34
36
|
tagsWrapperClass?: string
|
|
35
37
|
locationClass?: string
|
|
36
38
|
distanceClass?: string
|
|
39
|
+
imageStyle?: CSSProperties
|
|
40
|
+
titleStyle?: CSSProperties
|
|
41
|
+
subTitleStyle?: CSSProperties
|
|
42
|
+
priceStyle?: CSSProperties
|
|
43
|
+
priceUnitStyle?: CSSProperties
|
|
44
|
+
priceSuffixStyle?: CSSProperties
|
|
45
|
+
originPriceStyle?: CSSProperties
|
|
46
|
+
originPriceUnitStyle?: CSSProperties
|
|
47
|
+
tagsStyle?: CSSProperties
|
|
48
|
+
tagsWrapperStyle?: CSSProperties
|
|
49
|
+
locationStyle?: CSSProperties
|
|
50
|
+
distanceStyle?: CSSProperties
|
|
37
51
|
}
|
|
38
|
-
export declare const defaultLcbProductItemProps: LcbProductItemProps
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { DefineComponent, Slot } from 'vue'
|
|
2
|
-
type ObjectLiteralWithPotentialObjectLiterals = Record<string, Record<string, any> | undefined>
|
|
3
|
-
type GenerateSlotsFromSlotMap<T extends ObjectLiteralWithPotentialObjectLiterals> = {
|
|
4
|
-
[K in keyof T]: Slot<T[K]>
|
|
5
|
-
}
|
|
6
|
-
export type DefineTemplateComponent<
|
|
7
|
-
Bindings extends Record<string, any>,
|
|
8
|
-
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
|
|
9
|
-
> = DefineComponent & {
|
|
10
|
-
new (): {
|
|
11
|
-
$slots: {
|
|
12
|
-
default: (
|
|
13
|
-
_: Bindings & {
|
|
14
|
-
$slots: GenerateSlotsFromSlotMap<MapSlotNameToSlotProps>
|
|
15
|
-
},
|
|
16
|
-
) => any
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
export type ReuseTemplateComponent<
|
|
21
|
-
Bindings extends Record<string, any>,
|
|
22
|
-
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
|
|
23
|
-
> = DefineComponent<Bindings> & {
|
|
24
|
-
new (): {
|
|
25
|
-
$slots: GenerateSlotsFromSlotMap<MapSlotNameToSlotProps>
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
export type ReusableTemplatePair<
|
|
29
|
-
Bindings extends Record<string, any>,
|
|
30
|
-
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
|
|
31
|
-
> = [
|
|
32
|
-
DefineTemplateComponent<Bindings, MapSlotNameToSlotProps>,
|
|
33
|
-
ReuseTemplateComponent<Bindings, MapSlotNameToSlotProps>,
|
|
34
|
-
] & {
|
|
35
|
-
define: DefineTemplateComponent<Bindings, MapSlotNameToSlotProps>
|
|
36
|
-
reuse: ReuseTemplateComponent<Bindings, MapSlotNameToSlotProps>
|
|
37
|
-
}
|
|
38
|
-
export interface CreateReusableTemplateOptions {
|
|
39
|
-
/**
|
|
40
|
-
* Inherit attrs from reuse component.
|
|
41
|
-
*
|
|
42
|
-
* @default true
|
|
43
|
-
*/
|
|
44
|
-
inheritAttrs?: boolean
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* This function creates `define` and `reuse` components in pair,
|
|
48
|
-
* It also allow to pass a generic to bind with type.
|
|
49
|
-
*
|
|
50
|
-
* @see https://vueuse.org/createReusableTemplate
|
|
51
|
-
*/
|
|
52
|
-
export declare function createReusableTemplate<
|
|
53
|
-
Bindings extends Record<string, any>,
|
|
54
|
-
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals = Record<
|
|
55
|
-
'default',
|
|
56
|
-
undefined
|
|
57
|
-
>,
|
|
58
|
-
>(options?: CreateReusableTemplateOptions): ReusableTemplatePair<Bindings, MapSlotNameToSlotProps>
|
|
59
|
-
export {}
|
package/utils/createReuse.tsx
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import type { DefineComponent, Slot } from 'vue'
|
|
2
|
-
import { defineComponent, shallowRef } from 'vue'
|
|
3
|
-
|
|
4
|
-
type ObjectLiteralWithPotentialObjectLiterals = Record<string, Record<string, any> | undefined>
|
|
5
|
-
|
|
6
|
-
type GenerateSlotsFromSlotMap<T extends ObjectLiteralWithPotentialObjectLiterals> = {
|
|
7
|
-
[K in keyof T]: Slot<T[K]>
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type DefineTemplateComponent<
|
|
11
|
-
Bindings extends Record<string, any>,
|
|
12
|
-
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
|
|
13
|
-
> = DefineComponent & {
|
|
14
|
-
new (): {
|
|
15
|
-
$slots: {
|
|
16
|
-
default: (_: Bindings & { $slots: GenerateSlotsFromSlotMap<MapSlotNameToSlotProps> }) => any
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export type ReuseTemplateComponent<
|
|
22
|
-
Bindings extends Record<string, any>,
|
|
23
|
-
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
|
|
24
|
-
> = DefineComponent<Bindings> & {
|
|
25
|
-
new (): { $slots: GenerateSlotsFromSlotMap<MapSlotNameToSlotProps> }
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type ReusableTemplatePair<
|
|
29
|
-
Bindings extends Record<string, any>,
|
|
30
|
-
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
|
|
31
|
-
> = [
|
|
32
|
-
DefineTemplateComponent<Bindings, MapSlotNameToSlotProps>,
|
|
33
|
-
ReuseTemplateComponent<Bindings, MapSlotNameToSlotProps>,
|
|
34
|
-
] & {
|
|
35
|
-
define: DefineTemplateComponent<Bindings, MapSlotNameToSlotProps>
|
|
36
|
-
reuse: ReuseTemplateComponent<Bindings, MapSlotNameToSlotProps>
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface CreateReusableTemplateOptions {
|
|
40
|
-
/**
|
|
41
|
-
* Inherit attrs from reuse component.
|
|
42
|
-
*
|
|
43
|
-
* @default true
|
|
44
|
-
*/
|
|
45
|
-
inheritAttrs?: boolean
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* This function creates `define` and `reuse` components in pair,
|
|
50
|
-
* It also allow to pass a generic to bind with type.
|
|
51
|
-
*
|
|
52
|
-
* @see https://vueuse.org/createReusableTemplate
|
|
53
|
-
*/
|
|
54
|
-
export function createReusableTemplate<
|
|
55
|
-
Bindings extends Record<string, any>,
|
|
56
|
-
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals = Record<
|
|
57
|
-
'default',
|
|
58
|
-
undefined
|
|
59
|
-
>,
|
|
60
|
-
>(
|
|
61
|
-
options: CreateReusableTemplateOptions = {},
|
|
62
|
-
): ReusableTemplatePair<Bindings, MapSlotNameToSlotProps> {
|
|
63
|
-
const { inheritAttrs = true } = options
|
|
64
|
-
|
|
65
|
-
const render = shallowRef<Slot | undefined>()
|
|
66
|
-
|
|
67
|
-
const define = defineComponent({
|
|
68
|
-
setup(_, { slots }) {
|
|
69
|
-
return () => {
|
|
70
|
-
render.value = slots.default
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
}) as unknown as DefineTemplateComponent<Bindings, MapSlotNameToSlotProps>
|
|
74
|
-
|
|
75
|
-
const reuse = defineComponent({
|
|
76
|
-
inheritAttrs,
|
|
77
|
-
setup(_, { attrs, slots }) {
|
|
78
|
-
return () => {
|
|
79
|
-
if (!render.value && process.env.NODE_ENV !== 'production')
|
|
80
|
-
throw new Error('[VueUse] Failed to find the definition of reusable template')
|
|
81
|
-
const vnode = render.value?.({ ...keysToCamelKebabCase(attrs), $slots: slots })
|
|
82
|
-
|
|
83
|
-
return inheritAttrs && vnode?.length === 1 ? vnode[0] : vnode
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
}) as unknown as ReuseTemplateComponent<Bindings, MapSlotNameToSlotProps>
|
|
87
|
-
|
|
88
|
-
return makeDestructurable({ define, reuse }, [define, reuse]) as any
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function keysToCamelKebabCase(obj: Record<string, any>) {
|
|
92
|
-
const newObj: typeof obj = {}
|
|
93
|
-
for (const key in obj) newObj[camelize(key)] = obj[key]
|
|
94
|
-
return newObj
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* @see What the hack? https://antfu.me/posts/destructuring-with-object-or-array
|
|
98
|
-
*/
|
|
99
|
-
function makeDestructurable<T extends Record<string, unknown>, A extends readonly any[]>(
|
|
100
|
-
obj: T,
|
|
101
|
-
arr: A,
|
|
102
|
-
): T & A {
|
|
103
|
-
const clone = { ...obj }
|
|
104
|
-
Object.defineProperty(clone, Symbol.iterator, {
|
|
105
|
-
enumerable: false,
|
|
106
|
-
value() {
|
|
107
|
-
let index = 0
|
|
108
|
-
return {
|
|
109
|
-
next: () => ({
|
|
110
|
-
value: arr[index++],
|
|
111
|
-
done: index > arr.length,
|
|
112
|
-
}),
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
})
|
|
116
|
-
return clone as T & A
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function camelize(str: string) {
|
|
120
|
-
return str.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : ''))
|
|
121
|
-
}
|