# MatchPrizeSetSimple 奖品设置简易版

奖品设置简易版组件,提供基础的奖品类型选择和数量设置功能,适用于简化的奖品配置场景。

# 引入

import PressMatchPrizeSetSimple from 'press-next/press-match-prize-set-simple/press-match-prize-set-simple.vue';

# 代码演示

# 基础用法

<template>
  <PressMatchPrizeSetSimple
    :form-fields="formFields"
    @field-select="handleFieldSelect"
    @field-change="handleFieldChange"
    @delete="handleDelete"
    @add="handleAdd"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import PressMatchPrizeSetSimple from 'press-next/press-match-prize-set-simple/press-match-prize-set-simple.vue';

const formFields = ref([
  {
    key: 'type',
    label: '奖品类型',
    type: 'select',
    placeholder: '请选择',
    defaultText: '请选择',
  },
  {
    key: 'quantity',
    label: '数量份额',
    type: 'stepper',
    stepperValue: 1,
    min: 1,
    max: 999,
    step: 1,
  },
]);

const handleFieldSelect = (field, index) => {
  console.log('选择字段:', field.key);
};

const handleFieldChange = (field, index, value) => {
  console.log('字段值变化:', field.key, value);
};

const handleDelete = () => {
  console.log('删除奖品');
};

const handleAdd = () => {
  console.log('添加奖品');
};
</script>

# 奖品类型选择

组件支持奖品类型选择功能,点击后可触发外部 ActionSheet 动作面板:

<template>
  <PressMatchPrizeSetSimple
    @type-select="handleTypeSelect"
  />
  
  <PressActionSheet
    v-model:show="showActionSheet"
    :actions="prizeTypeActions"
    title="选择奖品类型"
    @select="handlePrizeTypeSelect"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import PressMatchPrizeSetSimple from 'press-next/press-next/press-match-prize-set-simple/press-match-prize-set-simple.vue';
import PressActionSheet from 'press-ui/press-action-sheet/press-action-sheet.vue';

const showActionSheet = ref(false);
const prizeTypeActions = [
  { name: '虚拟奖品', value: 'virtual' },
  { name: '实物奖品', value: 'physical' },
  { name: '现金奖励', value: 'cash' },
];

const handleTypeSelect = () => {
  showActionSheet.value = true;
};

const handlePrizeTypeSelect = (action) => {
  console.log('选择了奖品类型:', action.name);
  showActionSheet.value = false;
};
</script>

# 数量设置

组件内置步进器支持数量调节:

<template>
  <PressMatchPrizeSetSimple
    :data="prizeData"
    @change="handleQuantityChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import PressMatchPrizeSetSimple from 'press-next/press-next/press-match-prize-set-simple/press-match-prize-set-simple.vue';

const prizeData = ref({
  quantity: 5,
});

const handleQuantityChange = () => {
  console.log('当前数量:', prizeData.value.quantity);
};
</script>

# 自定义字段类型

组件支持两种字段类型:select(选择器)和 stepper(步进器):

<template>
  <PressMatchPrizeSetSimple
    :form-fields="customFields"
    @field-select="handleFieldSelect"
    @field-change="handleFieldChange"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import PressMatchPrizeSetSimple from 'press-next/press-match-prize-set-simple/press-match-prize-set-simple.vue';

const customFields = ref([
  // 选择器类型字段
  {
    key: 'category',
    label: '奖品分类',
    type: 'select',
    selectedValue: '', // 选中的值,会自动回显
    defaultText: '请选择分类',
  },
  // 步进器类型字段
  {
    key: 'stock',
    label: '库存数量',
    type: 'stepper',
    stepperValue: 10,
    min: 0,
    max: 9999,
    step: 5,
  },
]);

const handleFieldSelect = (field, index) => {
  // 处理选择器点击
  if (field.key === 'category') {
    // 显示分类选择器
  }
};

const handleFieldChange = (field, index, value) => {
  // 处理步进器值变化
  if (field.key === 'stock') {
    console.log('库存更新为:', value);
  }
};
</script>

# API

# Props

参数 说明 类型 默认值
formFields 表单字段配置 FormFieldConfig[] []

# FormFieldConfig 接口定义

interface FormFieldConfig {
  key: string;                    // 字段唯一标识
  label: string;                  // 字段标签文本
  type: 'select' | 'stepper';     // 字段类型
  placeholder?: string;           // 占位符文本
  selectedValue?: string;         // 选中的值(用于回显)
  defaultText?: string;           // 默认显示文本
  stepperValue?: number;          // 步进器当前值
  min?: number;                   // 步进器最小值
  max?: number;                   // 步进器最大值
  step?: number;                  // 步进器步长
}

# Events

事件名 说明 回调参数
field-select 选择器字段被点击时触发 (field: FormFieldConfig, index: number)
field-change 字段值变化时触发(步进器) (field: FormFieldConfig, index: number, value: number)
delete 点击删除时触发 -
add 点击添加奖品时触发 -

# 功能特性

# 核心功能

  • 动态表单配置:通过 formFields 灵活配置表单字段
  • 双类型字段支持:支持选择器(select)和步进器(stepper)
  • 自动回显机制:选择器选中值自动回显
  • 删除奖品功能:支持删除当前奖品配置
  • 添加奖品功能:支持添加新的奖品配置

# 字段类型说明

# 1. 选择器字段(select)

  • 点击触发 field-select 事件
  • 支持外部 ActionSheet 选择
  • 通过 selectedValue 实现回显
  • 显示优先级:selectedValue > defaultText > placeholder

# 2. 步进器字段(stepper)

  • 支持数值增减操作
  • 可配置最小值、最大值、步长
  • 值变化时触发 field-change 事件
  • 适用于数量、份额等数值配置

# 简化设计

  • 🎯 配置驱动:无需修改组件代码,通过配置定义表单
  • 🎯 灵活扩展:可自由组合不同类型的字段
  • 🎯 快速集成:简单的 Props 和事件设计
  • 🎯 功能互补:与完整版组件功能互补

# 使用场景

  • 简化的比赛奖品设置
  • 快速奖品配置流程
  • 移动端奖品管理
  • 轻量级奖品系统
  • 动态表单场景

# 主题定制

# CSS 变量

组件提供了下列 CSS 变量,可用于自定义样式。

# 间距系统

名称 默认值 描述
--pmpss-delete-mr $spacing-sm 删除按钮右边距
--pmpss-form-gap $spacing-lg 表单项间距
--pmpss-add-mt $spacing-lg 添加按钮上边距
--pmpss-add-gap $spacing-sm 添加按钮内部间距
--pmpss-content-padding-tb $spacing-md 内容区域上下内边距
--pmpss-content-padding-lr $spacing-lg 内容区域左右内边距

# 尺寸系统

名称 默认值 描述
--pmpss-delete-icon-size .4rem 删除图标尺寸
--pmpss-form-item-height .9rem 表单项高度
--pmpss-form-label-width 1.42rem 表单标签宽度
--pmpss-ctrls-icon-size .4rem 控制按钮图标尺寸

# 颜色系统

名称 默认值 描述
--pmpss-content-bg linear-gradient(...) 内容区域背景渐变
--pmpss-content-border-color $color-surface-brand-light2 内容区域边框颜色
--pmpss-primary-text-color $color-text-primary 主要文字颜色
--pmpss-add-text-color $color-text-primary 添加按钮文字颜色
--pmpss-delete-text-color $color-text-primary 删除按钮文字颜色
--pmpss-label-text-color $color-text-primary 标签文字颜色
--pmpss-cell-border-color $color-divider-light 单元格边框颜色
--pmpss-ctrls-text-color $color-text-invert-default 控制按钮文字颜色
--pmpss-ctrls-icon-color $color-text-primary 控制按钮图标颜色
--pmpss-stepper-input-bg rgba(#eceff2, .4) 步进器输入框背景

# 字体系统

名称 默认值 描述
--pmpss-icon-font-size .4rem 图标字体大小
--pmpss-label-font-size $font-size-md 标签字体大小
--pmpss-add-font-size $font-size-md 添加按钮字体大小
--pmpss-add-font-weight $font-weight-bold 添加按钮字体粗细
--pmpss-ctrls-text-font-size $font-size-md 控制按钮字体大小

# 圆角系统

名称 默认值 描述
--pmpss-content-border-radius $border-radius-xs 内容区域圆角

# 自定义样式示例

<template>
  <PressMatchPrizeSetSimple
    :data="prizeData"
    class="custom-prize-set"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import PressMatchPrizeSetSimple from 'press-next/press-next/press-match-prize-set-simple/press-match-prize-set-simple.vue';

const prizeData = ref({
  quantity: 1,
});
</script>

<style scoped lang="scss">
.custom-prize-set {
  --pmpss-content-bg: linear-gradient(135deg, #f0f8ff 0%, #e6f3ff 100%);
  --pmpss-primary-text-color: #1890ff;
  --pmpss-content-border-color: rgba(24, 144, 255, .2);
}
</style>

# 注意事项

  1. 组件依赖

    • 内部使用了 press-uiPressStepper 组件
    • 需要确保已正确安装 press-ui 依赖
  2. 表单字段配置

    • formFields 为必填项,至少包含一个字段配置
    • 每个字段的 key 必须唯一
    • type 只支持 'select''stepper' 两种类型
    • 选择器字段建议配置 defaultText 作为未选择时的提示文本
  3. 事件处理

    • field-select 事件仅在 type: 'select' 字段被点击时触发
    • field-change 事件仅在 type: 'stepper' 字段值变化时触发
    • 选择器需要配合外部组件(如 ActionSheet)实现选择功能
    • adddelete 事件需要在父组件中实现具体逻辑
  4. 回显机制

    • 选择器字段通过更新 selectedValue 实现回显
    • 步进器字段通过更新 stepperValue 实现值同步
    • 建议使用 ref 包装 formFields 确保响应式更新
  5. 样式隔离

    • 微信小程序环境下启用了 styleIsolation: 'shared'
    • 自定义样式时注意样式作用域

# 常见问题

# 如何添加新的表单字段?

直接在 formFields 数组中添加新的字段配置即可:

<script setup lang="ts">
import { ref } from 'vue';

const formFields = ref([
  {
    key: 'type',
    label: '奖品类型',
    type: 'select',
    defaultText: '请选择',
  },
  {
    key: 'quantity',
    label: '数量份额',
    type: 'stepper',
    stepperValue: 1,
    min: 1,
    max: 999,
  },
  // 添加新字段
  {
    key: 'priority',
    label: '优先级',
    type: 'stepper',
    stepperValue: 0,
    min: 0,
    max: 10,
    step: 1,
  },
]);
</script>

# 如何实现选择器回显?

通过更新字段的 selectedValue 属性实现回显:

<script setup lang="ts">
import { ref } from 'vue';

const formFields = ref([
  {
    key: 'type',
    label: '奖品类型',
    type: 'select',
    selectedValue: '', // 初始为空
    defaultText: '请选择',
  },
]);

// 用户选择后更新 selectedValue
const handleFieldValueSelect = (action) => {
  const fieldIndex = formFields.value.findIndex(f => f.key === 'type');
  if (fieldIndex !== -1) {
    // 更新后会自动回显
    formFields.value[fieldIndex].selectedValue = action.value;
  }
};
</script>

# 如何动态调整步进器范围?

可以通过修改字段的 minmaxstep 属性:

<script setup lang="ts">
import { ref } from 'vue';

const formFields = ref([
  {
    key: 'quantity',
    label: '数量份额',
    type: 'stepper',
    stepperValue: 10,
    min: 1,
    max: 100,
    step: 1,
  },
]);

// 根据业务需求动态调整范围
const adjustRange = (newMax) => {
  const field = formFields.value.find(f => f.key === 'quantity');
  if (field) {
    field.max = newMax;
    // 如果当前值超出新范围,自动调整
    if (field.stepperValue > newMax) {
      field.stepperValue = newMax;
    }
  }
};
</script>

# 如何实现字段联动?

通过监听 field-changefield-select 事件实现字段间的联动:

<script setup lang="ts">
import { ref } from 'vue';

const formFields = ref([
  {
    key: 'type',
    label: '奖品类型',
    type: 'select',
    selectedValue: '',
    defaultText: '请选择',
  },
  {
    key: 'quantity',
    label: '数量份额',
    type: 'stepper',
    stepperValue: 1,
    min: 1,
    max: 100,
  },
]);

// 字段选择回调
const handleFieldValueSelect = (action) => {
  const fieldIndex = formFields.value.findIndex(f => f.key === 'type');
  if (fieldIndex !== -1) {
    formFields.value[fieldIndex].selectedValue = action.value;
    
    // 联动:根据奖品类型调整数量范围
    const quantityField = formFields.value.find(f => f.key === 'quantity');
    if (quantityField) {
      if (action.value === '实物奖品') {
        quantityField.max = 50; // 实物奖品最多50份
      } else if (action.value === '虚拟奖品') {
        quantityField.max = 999; // 虚拟奖品最多999份
      }
    }
  }
};
</script>