# MatchPrizeSetSimple
A simplified prize setting component that provides basic prize type selection and quantity setting functions through dynamic form field configuration, suitable for simplified prize configuration scenarios.
# Import
import PressMatchPrizeSetSimple from 'press-next/press-match-prize-set-simple/press-match-prize-set-simple.vue';
# Usage
# Basic Usage
<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: 'Prize Type',
type: 'select',
placeholder: 'Please select',
defaultText: 'Please select',
},
{
key: 'quantity',
label: 'Quantity',
type: 'stepper',
stepperValue: 1,
min: 1,
max: 999,
step: 1,
},
]);
const handleFieldSelect = (field, index) => {
console.log('Select field:', field.key);
};
const handleFieldChange = (field, index, value) => {
console.log('Field value changed:', field.key, value);
};
const handleDelete = () => {
console.log('Delete prize');
};
const handleAdd = () => {
console.log('Add prize');
};
</script>
# Dynamic Form Field Configuration
The component supports dynamic form field configuration through formFields, including two types: selector and stepper:
<template>
<PressMatchPrizeSetSimple
:form-fields="formFields"
@field-select="handleFieldSelect"
@field-change="handleFieldChange"
/>
<!-- ActionSheet Field Selector -->
<PressActionSheet
v-model:show="showFieldSheet"
:actions="fieldActions"
:title="currentFieldLabel"
@close="onFieldSheetClose"
@select="handleFieldValueSelect"
/>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
import PressMatchPrizeSetSimple from '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';
// Configure form fields
const formFields = ref([
{
key: 'type',
label: 'Prize Type',
type: 'select',
placeholder: 'Please select',
defaultText: 'Please select',
},
{
key: 'quantity',
label: 'Quantity',
type: 'stepper',
stepperValue: 1,
min: 1,
max: 999,
step: 1,
},
{
key: 'level',
label: 'Prize Level',
type: 'select',
placeholder: 'Please select',
defaultText: 'Please select',
},
]);
// ActionSheet related states
const showFieldSheet = ref(false);
const currentFieldKey = ref('');
const currentFieldLabel = ref('');
// Field selector options configuration
const fieldOptionsMap = {
type: [
{ name: 'Physical Prize', value: 'Physical Prize' },
{ name: 'Virtual Prize', value: 'Virtual Prize' },
{ name: 'Cash Reward', value: 'Cash Reward' },
{ name: 'Coupon', value: 'Coupon' },
],
level: [
{ name: 'First Prize', value: 'First Prize' },
{ name: 'Second Prize', value: 'Second Prize' },
{ name: 'Third Prize', value: 'Third Prize' },
{ name: 'Participation Prize', value: 'Participation Prize' },
],
};
// Compute current field options list
const fieldActions = computed(() => fieldOptionsMap[currentFieldKey.value] || []);
// Handle field selection
const handleFieldSelect = (field, index) => {
console.log('Select field:', field.key);
currentFieldKey.value = field.key;
currentFieldLabel.value = `Select ${field.label}`;
if (fieldOptionsMap[field.key]) {
showFieldSheet.value = true;
}
};
// Field value selection callback (handle echo)
const handleFieldValueSelect = (action) => {
const fieldIndex = formFields.value.findIndex(f => f.key === currentFieldKey.value);
if (fieldIndex !== -1) {
formFields.value[fieldIndex].selectedValue = action.value;
console.log(`${currentFieldLabel.value}: ${action.value}`);
}
showFieldSheet.value = false;
};
// Close selector
const onFieldSheetClose = () => {
showFieldSheet.value = false;
};
// Handle field value change (stepper)
const handleFieldChange = (field, index, value) => {
console.log('Field value changed:', field.key, value);
if (field.type === 'stepper') {
formFields.value[index].stepperValue = value;
}
};
</script>
# Custom Field Types
The component supports two field types: select (selector) and stepper (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([
// Selector type field
{
key: 'category',
label: 'Prize Category',
type: 'select',
selectedValue: '', // Selected value, will auto-echo
defaultText: 'Please select category',
},
// Stepper type field
{
key: 'stock',
label: 'Stock Quantity',
type: 'stepper',
stepperValue: 10,
min: 0,
max: 9999,
step: 5,
},
]);
const handleFieldSelect = (field, index) => {
// Handle selector click
if (field.key === 'category') {
// Show category selector
}
};
const handleFieldChange = (field, index, value) => {
// Handle stepper value change
if (field.key === 'stock') {
console.log('Stock updated to:', value);
}
};
</script>
# API
# Props
| Attribute | Description | Type | Default |
|-----------|-------------|------|---------||
| formFields | Form field configuration | FormFieldConfig[] | [] |
# FormFieldConfig Interface
interface FormFieldConfig {
key: string; // Unique field identifier
label: string; // Field label text
type: 'select' | 'stepper'; // Field type
placeholder?: string; // Placeholder text
selectedValue?: string; // Selected value (for echo)
defaultText?: string; // Default display text
stepperValue?: number; // Stepper current value
min?: number; // Stepper minimum value
max?: number; // Stepper maximum value
step?: number; // Stepper step value
}
# Events
| Event | Description | Parameters |
|---|---|---|
| field-select | Triggered when selector field is clicked | (field: FormFieldConfig, index: number) |
| field-change | Triggered when field value changes (stepper) | (field: FormFieldConfig, index: number, value: number) |
| delete | Triggered when delete is clicked | - |
| add | Triggered when add prize is clicked | - |
# Features
# Core Functions
- ✅ Dynamic Form Configuration: Flexibly configure form fields through
formFields - ✅ Dual Field Type Support: Supports selector (select) and stepper (stepper)
- ✅ Auto Echo Mechanism: Selector selected values auto-echo
- ✅ Delete Prize Function: Supports deleting current prize configuration
- ✅ Add Prize Function: Supports adding new prize configuration
# Field Type Description
# 1. Selector Field (select)
- Clicking triggers
field-selectevent - Supports external ActionSheet selection
- Echo implemented through
selectedValue - Display priority:
selectedValue>defaultText>placeholder
# 2. Stepper Field (stepper)
- Supports numeric increment/decrement operations
- Configurable min, max, and step values
- Triggers
field-changeevent when value changes - Suitable for quantity, quota, and other numeric configurations
# Simplified Design
- 🎯 Configuration Driven: Define forms through configuration without modifying component code
- 🎯 Flexible Extension: Freely combine different types of fields
- 🎯 Quick Integration: Simple Props and event design
- 🎯 Complementary Functions: Complements full-featured component
# Use Cases
- Simplified competition prize setting
- Quick prize configuration process
- Mobile prize management
- Lightweight prize system
- Dynamic form scenarios
# Theming
# CSS Variables
The component provides the following CSS variables, which can be used to customize styles.
# Spacing System
| Name | Default Value | Description |
|---|---|---|
| --pmpss-delete-mr | $spacing-sm | Delete button right margin |
| --pmpss-form-gap | $spacing-lg | Form item gap |
| --pmpss-add-mt | $spacing-lg | Add button top margin |
| --pmpss-add-gap | $spacing-sm | Add button internal gap |
| --pmpss-content-padding-tb | $spacing-md | Content area vertical padding |
| --pmpss-content-padding-lr | $spacing-lg | Content area horizontal padding |
# Size System
| Name | Default Value | Description |
|---|---|---|
| --pmpss-delete-icon-size | .4rem | Delete icon size |
| --pmpss-form-item-height | .9rem | Form item height |
| --pmpss-form-label-width | 1.42rem | Form label width |
| --pmpss-ctrls-icon-size | .4rem | Control button icon size |
# Color System
| Name | Default Value | Description |
|---|---|---|
| --pmpss-content-bg | linear-gradient(...) | Content area background gradient |
| --pmpss-content-border-color | $color-surface-brand-light2 | Content area border color |
| --pmpss-primary-text-color | $color-text-primary | Primary text color |
| --pmpss-add-text-color | $color-text-primary | Add button text color |
| --pmpss-delete-text-color | $color-text-primary | Delete button text color |
| --pmpss-label-text-color | $color-text-primary | Label text color |
| --pmpss-cell-border-color | $color-divider-light | Cell border color |
| --pmpss-ctrls-text-color | $color-text-invert-default | Control button text color |
| --pmpss-ctrls-icon-color | $color-text-primary | Control button icon color |
| --pmpss-stepper-input-bg | rgba(#eceff2, .4) | Stepper input background |
# Font System
| Name | Default Value | Description |
|---|---|---|
| --pmpss-icon-font-size | .4rem | IconPlus font size |
| --pmpss-label-font-size | $font-size-md | Label font size |
| --pmpss-add-font-size | $font-size-md | Add button font size |
| --pmpss-add-font-weight | $font-weight-bold | Add button font weight |
| --pmpss-ctrls-text-font-size | $font-size-md | Control button font size |
# Border Radius System
| Name | Default Value | Description |
|---|---|---|
| --pmpss-content-border-radius | $border-radius-xs | Content area border radius |
# Custom Style Example
<template>
<PressMatchPrizeSetSimple
:form-fields="formFields"
class="custom-prize-set"
/>
</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: 'quantity',
label: 'Quantity',
type: 'stepper',
stepperValue: 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>
# Notes
Component Dependencies:
- Internally uses the
PressSteppercomponent frompress-ui - Ensure that the
press-uidependency is correctly installed
- Internally uses the
Form Field Configuration:
formFieldsis required and must contain at least one field configuration- Each field's
keymust be unique typeonly supports'select'and'stepper'types- Selector fields should configure
defaultTextas prompt text when not selected
Event Handling:
field-selectevent is only triggered whentype: 'select'field is clickedfield-changeevent is only triggered whentype: 'stepper'field value changes- Selector needs to work with external components (such as ActionSheet) to implement selection function
addanddeleteevents need to implement specific logic in parent component
Echo Mechanism:
- Selector field implements echo by updating
selectedValue - Stepper field implements value sync by updating
stepperValue - It is recommended to wrap
formFieldswithrefto ensure reactive updates
- Selector field implements echo by updating
Style Isolation:
styleIsolation: 'shared'is enabled in WeChat Mini Program environment- Pay attention to style scope when customizing styles
# FAQ
# How to add new form fields?
Simply add new field configurations to the formFields array:
<script setup lang="ts">
import { ref } from 'vue';
const formFields = ref([
{
key: 'type',
label: 'Prize Type',
type: 'select',
defaultText: 'Please select',
},
{
key: 'quantity',
label: 'Quantity',
type: 'stepper',
stepperValue: 1,
min: 1,
max: 999,
},
// Add new field
{
key: 'priority',
label: 'Priority',
type: 'stepper',
stepperValue: 0,
min: 0,
max: 10,
step: 1,
},
]);
</script>
# How to implement selector echo?
Implement echo by updating the field's selectedValue property:
<script setup lang="ts">
import { ref } from 'vue';
const formFields = ref([
{
key: 'type',
label: 'Prize Type',
type: 'select',
selectedValue: '', // Initially empty
defaultText: 'Please select',
},
]);
// Update selectedValue after user selection
const handleFieldValueSelect = (action) => {
const fieldIndex = formFields.value.findIndex(f => f.key === 'type');
if (fieldIndex !== -1) {
// Will auto-echo after update
formFields.value[fieldIndex].selectedValue = action.value;
}
};
</script>
# How to dynamically adjust stepper range?
You can modify the field's min, max, and step properties:
<script setup lang="ts">
import { ref } from 'vue';
const formFields = ref([
{
key: 'quantity',
label: 'Quantity',
type: 'stepper',
stepperValue: 10,
min: 1,
max: 100,
step: 1,
},
]);
// Dynamically adjust range based on business requirements
const adjustRange = (newMax) => {
const field = formFields.value.find(f => f.key === 'quantity');
if (field) {
field.max = newMax;
// Automatically adjust if current value exceeds new range
if (field.stepperValue > newMax) {
field.stepperValue = newMax;
}
}
};
</script>
# How to implement field linkage?
Implement field linkage by listening to field-change or field-select events:
<script setup lang="ts">
import { ref } from 'vue';
const formFields = ref([
{
key: 'type',
label: 'Prize Type',
type: 'select',
selectedValue: '',
defaultText: 'Please select',
},
{
key: 'quantity',
label: 'Quantity',
type: 'stepper',
stepperValue: 1,
min: 1,
max: 100,
},
]);
// Field selection callback
const handleFieldValueSelect = (action) => {
const fieldIndex = formFields.value.findIndex(f => f.key === 'type');
if (fieldIndex !== -1) {
formFields.value[fieldIndex].selectedValue = action.value;
// Linkage: Adjust quantity range based on prize type
const quantityField = formFields.value.find(f => f.key === 'quantity');
if (quantityField) {
if (action.value === 'Physical Prize') {
quantityField.max = 50; // Max 50 for physical prizes
} else if (action.value === 'Virtual Prize') {
quantityField.max = 999; // Max 999 for virtual prizes
}
}
}
};
</script>