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