Vue 3.2组件Prop如何自动复用预定义嵌套对象属性
问题原因
你之前的写法无法运行核心是两个Vue模板语法误区:
{{}}是模板文本插值语法,仅用于标签包裹的文本内容,不能直接嵌套在v-bind绑定的属性值的JS表达式内部- 给组件传递数组、对象这类非字符串类型的Prop时,必须加
v-bind:(简写为:),否则Vue会将属性值识别为普通字符串,不会解析为JS数据结构
实现方案
整体思路是把动作的固定字段统一抽离到全局配置维护,组件内部自动做配置和传入参数的合并,调用方只需要传动作标识和可变参数即可。
步骤1:抽离统一动作配置
新建独立配置文件存放所有动作的固定字段,后续修改动作描述、新增动作只需要改这一个文件:
// src/config/exerciseConfig.js export const exerciseConfig = { 'Exercice 1': { exName: 'Exercice 1', exDescription: 'The description...', // 其余固定字段:发力部位、动作要点、禁忌提示等都统一存在这里 }, 'Exercice 2': { exName: 'Exercice 2', exDescription: 'Another description...', } }
步骤2:改造WorkoutComponent内部逻辑
在组件内部通过计算属性自动补全固定字段,不要直接使用传入的原始Prop值(注意不要直接修改Prop本身,遵循Vue单向数据流规范):
<!-- src/components/WorkoutComponent.vue --> <script setup> import { computed } from 'vue' // 导入默认全局配置 import { exerciseConfig as defaultConfig } from '@/config/exerciseConfig.js' const props = defineProps({ // 调用时只需要传动作标识+可变字段 Exercices: { type: Array, required: true, default: () => [] }, // 可选:支持调用方传入自定义配置覆盖默认配置,适配特殊场景 customExerciseMap: { type: Object, default: () => ({}) } }) // 自动补全动作完整信息 const fullExerciseList = computed(() => { // 合并默认配置和自定义配置 const mergedConfig = { ...defaultConfig, ...props.customExerciseMap } return props.Exercices.map(item => { const baseExerciseInfo = mergedConfig[item.exName] || {} // 固定字段在前,传入的自定义字段在后,支持临时覆盖同名字段 return { ...baseExerciseInfo, ...item } }) }) </script> <template> <!-- 模板遍历使用补全后的列表即可 --> <div class="workout-container"> <div v-for="(exercise, index) in fullExerciseList" :key="index" class="exercise-card"> <h4>{{ exercise.exName }}</h4> <p class="desc">{{ exercise.exDescription }}</p> <p class="series">训练组数:{{ exercise.nbSeries }}</p> </div> </div> </template>
步骤3:父页面调用组件
调用时只需要传动作名、训练组数这类可变参数即可,注意给Prop加:做动态绑定:
<!-- src/views/Workout.vue --> <template> <WorkoutComponent :Exercices="[ { exName: 'Exercice 1', nbSeries: 6 }, { exName: 'Exercice 2', nbSeries: 3 } ]" /> </template> <script setup> import WorkoutComponent from '@/components/WorkoutComponent.vue' </script>
可选扩展方案
如果不想把配置内置在组件里,也可以在父组件调用时直接展开配置项,但这种方式每次调用都需要导入配置,维护成本更高,仅适合临时场景:
<template> <WorkoutComponent :Exercices="[ { ...exList['Exercice 1'], nbSeries: 6 }, { ...exList['Exercice 2'], nbSeries: 3 } ]" /> </template> <script setup> import WorkoutComponent from '@/components/WorkoutComponent.vue' import { exList } from '@/config/exerciseConfig.js' </script>
内容的提问来源于stack exchange,提问作者Nehrz
相关产品推荐
相关产品推荐

