|
@@ -1,115 +1,148 @@
|
|
<template>
|
|
<template>
|
|
- <view
|
|
+ <view class="fs-cell" :class="[cls, { shadow }]" :style="{ backgroundColor: bgColor }" @click="handleClick">
|
|
- class="fs-cell"
|
|
+ <view class="fs-cell-flex" :class="['fs-cell-align-' + align, justify, { reverse }]">
|
|
- :class="[cls,{shadow}]"
|
|
|
|
- :style="{backgroundColor:bgColor}"
|
|
|
|
- @click="handleClick"
|
|
|
|
- >
|
|
|
|
- <view class="fs-cell-flex" :class="['fs-cell-align-' + align, justify,{reverse}]">
|
|
|
|
<view class="fs-cell-title" :class="{ 'fs-cell-required': required }" :style="titleStyle">
|
|
<view class="fs-cell-title" :class="{ 'fs-cell-required': required }" :style="titleStyle">
|
|
- <template v-if="title">{{title}}</template>
|
|
+ <template v-if="title">
|
|
- <slot v-else name="title"></slot>
|
|
+ {{ title }}
|
|
|
|
+ </template>
|
|
|
|
+ <slot v-else name="title"></slot>
|
|
</view>
|
|
</view>
|
|
<view class="fs-cell-value">
|
|
<view class="fs-cell-value">
|
|
- <template v-if="value">{{value}}</template>
|
|
+ <template v-if="value">
|
|
|
|
+ {{ value }}
|
|
|
|
+ </template>
|
|
<slot v-else name="value"></slot>
|
|
<slot v-else name="value"></slot>
|
|
</view>
|
|
</view>
|
|
<view class="fs-cell-extra">
|
|
<view class="fs-cell-extra">
|
|
- <template v-if="extra">{{extra}}</template>
|
|
+ <template v-if="extra">
|
|
|
|
+ {{ extra }}
|
|
|
|
+ </template>
|
|
<slot v-else name="extra"></slot>
|
|
<slot v-else name="extra"></slot>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="fs-cell-label">
|
|
<view class="fs-cell-label">
|
|
- <template v-if="label">{{label}}</template>
|
|
+ <template v-if="label">
|
|
|
|
+ {{ label }}
|
|
|
|
+ </template>
|
|
<slot v-else name="label"></slot>
|
|
<slot v-else name="label"></slot>
|
|
</view>
|
|
</view>
|
|
- <view class="arrow-icon">
|
|
+ <view class="arrow-icon">
|
|
- <fs-icon type="icon-d-down" rotate="-90" size="28rpx" :color="arrowColor" :colorType="arrowColorType"></fs-icon>
|
|
+ <fs-icon type="icon-d-down" rotate="-90" size="28rpx" :color="arrowColor" :colorType="arrowColorType"></fs-icon>
|
|
- </view>
|
|
+ </view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
-<script setup>
|
|
+<script>
|
|
- import { computed, toRefs, inject } from 'vue'
|
|
+/**
|
|
-
|
|
+ * 单元格组件
|
|
- const props = defineProps({
|
|
+ * @description 单元格组件
|
|
- title: String,
|
|
+ * @property {String} title 标题
|
|
- titleWidth: String,
|
|
+ * @property {String} titleWidth 标题宽度
|
|
- value: String,
|
|
+ * @property {String} value 值
|
|
- extra: String,
|
|
+ * @property {String} label 描述信息
|
|
- label: String,
|
|
+ * @property {String} extra 额外信息
|
|
- arrow: Boolean,
|
|
+ * @property {Boolean} arrow 是否显示箭头
|
|
- arrowColor: {
|
|
+ * @property {String} arrowColor 箭头颜色
|
|
- type: String,
|
|
+ * @property {String} arrowColorType = [primary | danger | warning | info | success] 箭头颜色类型
|
|
- default: '#E8EAF2'
|
|
+ * @property {Boolean} border 是否显示边框
|
|
- },
|
|
+ * @property {Boolean} shadow 是否显示阴影
|
|
- arrowColorType: {
|
|
+ * @property {Boolean} tighten 是否紧凑
|
|
- type: String,
|
|
+ * @property {Boolean} gutter 是否显示间距
|
|
- validator(value) {
|
|
+ * @property {Boolean} radius 是否带圆角
|
|
- return ['primary', 'success', 'info', 'warning', 'danger'].includes(value)
|
|
+ * @property {Boolean} reverse 是否翻转
|
|
- }
|
|
+ * @property {Boolean} required 是否必填配合表单使用
|
|
- },
|
|
+ * @property {String} bgColor 背景颜色
|
|
- border: Boolean,
|
|
+ * @property {String} align = [top | center | bottom | stretch] 垂直对齐方式
|
|
- tighten: Boolean,
|
|
+ * @property {String} justify = [left | center | right] 水平对齐方式
|
|
- gutter: Boolean,
|
|
+ * @property {String} link 跳转地址
|
|
- radius: Boolean,
|
|
+ * @property {String} linkType 跳转类型
|
|
- reverse: Boolean,
|
|
+ */
|
|
- required: Boolean,
|
|
+export default {
|
|
- align: {
|
|
+ name: 'fs-cell'
|
|
- type: String,
|
|
+}
|
|
- default: 'center',
|
|
+</script>
|
|
- validator(value) {
|
|
+
|
|
- return ['top', 'center', 'bottom', 'stretch'].includes(value)
|
|
+<script setup>
|
|
- }
|
|
+import { computed, toRefs, inject } from 'vue'
|
|
- },
|
|
+
|
|
- justify: {
|
|
+const props = defineProps({
|
|
- type: String,
|
|
+ title: String,
|
|
- validator(value) {
|
|
+ titleWidth: String,
|
|
- return ['left', 'center', 'right'].includes(value)
|
|
+ value: String,
|
|
- }
|
|
+ extra: String,
|
|
- },
|
|
+ label: String,
|
|
- bgColor: {
|
|
+ arrow: Boolean,
|
|
- type: String,
|
|
+ arrowColor: {
|
|
- },
|
|
+ type: String,
|
|
- shadow: Boolean,
|
|
+ default: '#E8EAF2'
|
|
- link: String,
|
|
+ },
|
|
- linkType: {
|
|
+ arrowColorType: {
|
|
- type: String,
|
|
+ type: String,
|
|
- default: 'navigateTo'
|
|
+ validator(value) {
|
|
- },
|
|
+ return ['primary', 'success', 'info', 'warning', 'danger'].includes(value)
|
|
- })
|
|
+ }
|
|
-
|
|
+ },
|
|
- const emits = defineEmits(['click'])
|
|
+ border: Boolean,
|
|
- const cellGroup = inject('cellGroup', {})
|
|
+ tighten: Boolean,
|
|
-
|
|
+ gutter: Boolean,
|
|
- const justify = props.justify || cellGroup.justify || 'left'
|
|
+ radius: Boolean,
|
|
- const bgColor = props.bgColor || cellGroup.bgColor || '#fff'
|
|
+ reverse: Boolean,
|
|
- const arrowColor = props.arrowColor || cellGroup.arrowColor
|
|
+ required: Boolean,
|
|
- const arrowColorType = props.arrowColorType || cellGroup.arrowColorType
|
|
+ align: {
|
|
- const cls = computed(() => {
|
|
+ type: String,
|
|
- const classNames = [];
|
|
+ default: 'center',
|
|
-
|
|
+ validator(value) {
|
|
- (props.arrow || cellGroup.arrow) && classNames.push('arrow');
|
|
+ return ['top', 'center', 'bottom', 'stretch'].includes(value)
|
|
- (props.border || cellGroup.border) && classNames.push('border');
|
|
+ }
|
|
- (props.tighten || cellGroup.tighten) && classNames.push('tighten')
|
|
+ },
|
|
- props.gutter && classNames.push('gutter')
|
|
+ justify: {
|
|
- props.radius && classNames.push('radius')
|
|
+ type: String,
|
|
-
|
|
+ validator(value) {
|
|
- return classNames.join(' ')
|
|
+ return ['left', 'center', 'right'].includes(value)
|
|
- })
|
|
+ }
|
|
- const titleStyle = computed(() => {
|
|
+ },
|
|
- const width = props.titleWidth || cellGroup.titleWidth
|
|
+ bgColor: {
|
|
- return width ? `width: ${width}` : ''
|
|
+ type: String
|
|
- })
|
|
+ },
|
|
-
|
|
+ shadow: Boolean,
|
|
- const handleClick = () => {
|
|
+ link: String,
|
|
- if (props.link) {
|
|
+ linkType: {
|
|
- uni[props.linkType]({
|
|
+ type: String,
|
|
- url: props.link
|
|
+ default: 'navigateTo'
|
|
- })
|
|
+ }
|
|
- }
|
|
+})
|
|
- emits('click')
|
|
+
|
|
|
|
+const emits = defineEmits(['click'])
|
|
|
|
+const cellGroup = inject('cellGroup', {})
|
|
|
|
+
|
|
|
|
+const justify = props.justify || cellGroup.justify || 'left'
|
|
|
|
+const bgColor = props.bgColor || cellGroup.bgColor || '#fff'
|
|
|
|
+const arrowColor = props.arrowColor || cellGroup.arrowColor
|
|
|
|
+const arrowColorType = props.arrowColorType || cellGroup.arrowColorType
|
|
|
|
+const cls = computed(() => {
|
|
|
|
+ const classNames = []
|
|
|
|
+
|
|
|
|
+ ;(props.arrow || cellGroup.arrow) && classNames.push('arrow')
|
|
|
|
+ ;(props.border || cellGroup.border) && classNames.push('border')
|
|
|
|
+ ;(props.tighten || cellGroup.tighten) && classNames.push('tighten')
|
|
|
|
+ props.gutter && classNames.push('gutter')
|
|
|
|
+ props.radius && classNames.push('radius')
|
|
|
|
+
|
|
|
|
+ return classNames.join(' ')
|
|
|
|
+})
|
|
|
|
+const titleStyle = computed(() => {
|
|
|
|
+ const width = props.titleWidth || cellGroup.titleWidth
|
|
|
|
+ return width ? `width: ${width}` : ''
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const handleClick = () => {
|
|
|
|
+ if (props.link) {
|
|
|
|
+ uni[props.linkType]({
|
|
|
|
+ url: props.link
|
|
|
|
+ })
|
|
}
|
|
}
|
|
|
|
+ emits('click')
|
|
|
|
+}
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
@@ -120,82 +153,82 @@
|
|
background-color: #fff;
|
|
background-color: #fff;
|
|
line-height: 1.4;
|
|
line-height: 1.4;
|
|
width: 100%;
|
|
width: 100%;
|
|
- box-sizing: border-box;
|
|
+ box-sizing: border-box;
|
|
-
|
|
+
|
|
- &-flex {
|
|
+ &-flex {
|
|
- display: flex;
|
|
+ display: flex;
|
|
- justify-content: space-between;
|
|
+ justify-content: space-between;
|
|
- }
|
|
+ }
|
|
- &-value {
|
|
+ &-value {
|
|
- flex: 1;
|
|
+ flex: 1;
|
|
- padding-left: 20rpx;
|
|
+ padding-left: 20rpx;
|
|
- text-align: right;
|
|
+ text-align: right;
|
|
- }
|
|
+ }
|
|
- &-label {
|
|
+ &-label {
|
|
- font-size: var(--sub-size);
|
|
+ font-size: var(--sub-size);
|
|
- color: var(--sub);
|
|
+ color: var(--sub);
|
|
- }
|
|
+ }
|
|
-
|
|
+
|
|
- &-align-top {
|
|
+ &-align-top {
|
|
- align-items: flex-start;
|
|
+ align-items: flex-start;
|
|
- }
|
|
+ }
|
|
- &-align-center {
|
|
+ &-align-center {
|
|
- align-items: center;
|
|
+ align-items: center;
|
|
- }
|
|
|
|
- &-align-bottom {
|
|
|
|
- align-items: flex-end;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- &.arrow {
|
|
|
|
- padding-right: 50rpx;
|
|
|
|
-
|
|
|
|
- .arrow-icon{
|
|
|
|
- display: block;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- &-required{
|
|
|
|
- position: relative;
|
|
|
|
- padding-left: 7px;
|
|
|
|
-
|
|
|
|
- &::before{
|
|
|
|
- position: absolute;
|
|
|
|
- content: '*';
|
|
|
|
- color: red;
|
|
|
|
- left: 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- &.gutter {
|
|
|
|
- margin-bottom: var(--gutter-v);
|
|
|
|
- }
|
|
|
|
- &.radius {
|
|
|
|
- border-radius: var(--radius);
|
|
|
|
- }
|
|
|
|
- &.reverse{
|
|
|
|
- flex-direction: row-reverse;
|
|
|
|
- }
|
|
|
|
- &.tighten {
|
|
|
|
- padding: var(--tighten-gutter);
|
|
|
|
- }
|
|
|
|
- &.border {
|
|
|
|
- border-bottom: 2rpx solid var(--border-color);
|
|
|
|
}
|
|
}
|
|
-}
|
|
+ &-align-bottom {
|
|
-.arrow-icon{
|
|
+ align-items: flex-end;
|
|
- display: none;
|
|
+ }
|
|
- position: absolute;
|
|
+
|
|
- right: 10rpx;
|
|
+ &.arrow {
|
|
- top: 50%;
|
|
+ padding-right: 50rpx;
|
|
- transform: translateY(-50%);
|
|
+
|
|
-}
|
|
+ .arrow-icon {
|
|
-.left .fs-cell-value {
|
|
+ display: block;
|
|
- text-align: left;
|
|
+ }
|
|
-}
|
|
+ }
|
|
-.center .fs-cell-value {
|
|
+
|
|
- text-align: center;
|
|
+ &-required {
|
|
-}
|
|
+ position: relative;
|
|
-.right .fs-cell-value {
|
|
+ padding-left: 7px;
|
|
- text-align: right;
|
|
+
|
|
|
|
+ &::before {
|
|
|
|
+ position: absolute;
|
|
|
|
+ content: '*';
|
|
|
|
+ color: red;
|
|
|
|
+ left: 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &.gutter {
|
|
|
|
+ margin-bottom: var(--gutter-v);
|
|
|
|
+ }
|
|
|
|
+ &.radius {
|
|
|
|
+ border-radius: var(--radius);
|
|
|
|
+ }
|
|
|
|
+ &.reverse {
|
|
|
|
+ flex-direction: row-reverse;
|
|
|
|
+ }
|
|
|
|
+ &.tighten {
|
|
|
|
+ padding: var(--tighten-gutter);
|
|
|
|
+ }
|
|
|
|
+ &.border {
|
|
|
|
+ border-bottom: 2rpx solid var(--border-color);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.arrow-icon {
|
|
|
|
+ display: none;
|
|
|
|
+ position: absolute;
|
|
|
|
+ right: 10rpx;
|
|
|
|
+ top: 50%;
|
|
|
|
+ transform: translateY(-50%);
|
|
|
|
+}
|
|
|
|
+.left .fs-cell-value {
|
|
|
|
+ text-align: left;
|
|
|
|
+}
|
|
|
|
+.center .fs-cell-value {
|
|
|
|
+ text-align: center;
|
|
|
|
+}
|
|
|
|
+.right .fs-cell-value {
|
|
|
|
+ text-align: right;
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|