You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue.js中基于JSON数据动态添加输入字段及组件调用

Hey there! Let's break this down step by step since you're new to Vue—no worries, we'll make this work smoothly. We'll focus on fixing your template structure, setting up dynamic field rendering, and splitting reusable components as you requested.


Step 1: Set Up Your Vue Instance & Base Data

First, we need to define a proper data structure so Vue can handle reactivity correctly. We'll include your dropdown options, the dynamic rules array (for adding multiple form rows), and ensure each rule has the nested data fields you need for binding.

const { createApp } = Vue;

createApp({
  data() {
    return {
      // Your dropdown options (match your refId and text values)
      data: [
        { refId: "indian_act", text: "Indian Act 1931" },
        { refId: "narcotic", text: "Narcotic" },
        { refId: "ker", text: "Ker" }
      ],
      // Dynamic form rows
      rules: [
        {
          name: "", // Binds to dropdown selection
          data: [
            {
              head: {
                "arms(if any)": "", // For Indian Act
                qty: "" // For Narcotic
              },
              value: {
                wild: { qty: "", item: "" }, // For Ker's wild option
                enc: { /* Add your enc fields here */ }
              },
              selectedKerOptions: [] // Tracks selected options for Ker
            }
          ]
        }
      ]
    };
  },
  methods: {
    // Optional: Add new form rows
    addNewRule() {
      this.rules.push({
        name: "",
        data: [
          {
            head: { "arms(if any)": "", qty: "" },
            value: { wild: { qty: "", item: "" }, enc: {} },
            selectedKerOptions: []
          }
        ]
      });
    }
  }
})
// Register reusable components here (we'll define these next)
.component('indian-act-field', {
  props: ['ruleData'],
  template: `
    <div class="mt-2">
      <label>arms(if any):</label>
      <input 
        class="form-control" 
        v-model="ruleData.head['arms(if any)']"
        placeholder="Enter arms details"
      />
    </div>
  `
})
.component('narcotic-field', {
  props: ['ruleData'],
  template: `
    <div class="mt-2">
      <label>qty:</label>
      <input 
        class="form-control" 
        v-model="ruleData.head.qty"
        type="number"
        placeholder="Enter quantity"
      />
    </div>
  `
})
.component('ker-field', {
  props: ['ruleData'],
  template: `
    <div class="mt-2">
      <label>Select Options (multi-select):</label>
      <select 
        class="form-control" 
        multiple
        v-model="ruleData.selectedKerOptions"
      >
        <option value="wild">wild</option>
        <option value="enc">enc</option>
      </select>

      <!-- Render wild fields if selected -->
      <div v-if="ruleData.selectedKerOptions.includes('wild')" class="mt-2">
        <label>wild qty:</label>
        <input 
          class="form-control mb-2" 
          v-model="ruleData.value.wild.qty"
          type="number"
        />
        <label>wild item:</label>
        <input 
          class="form-control" 
          v-model="ruleData.value.wild.item"
        />
      </div>

      <!-- Render enc fields if selected (add your fields here) -->
      <div v-if="ruleData.selectedKerOptions.includes('enc')" class="mt-2">
        <label>enc field:</label>
        <input 
          class="form-control" 
          v-model="ruleData.value.enc.yourField"
          placeholder="Enter enc details"
        />
      </div>
    </div>
  `
})
.mount('#app');
Step 2: Fixed Base Template Structure

Your original HTML had nested tags out of order—here's the corrected template that uses our components and dynamic rendering:

<div id="app">
  <!-- Button to add new form rows (optional) -->
  <button class="btn btn-primary mb-3" @click="addNewRule">Add New Rule</button>

  <div id="add">
    <div class="card-content border p-3 mb-3" v-for="(bok, index) in rules" :key="index">
      <!-- Main Type Dropdown -->
      <select class="form-control" v-model="bok.name" name="type">
        <option value="" selected disabled hidden>Choose Type here</option>
        <option v-for="post in data" :value="post.refId">
          {{ post.text }}
        </option>
      </select>

      <!-- Dynamic Field Rendering -->
      <indian-act-field v-if="bok.name === 'indian_act'" :rule-data="bok.data[0]"></indian-act-field>
      <narcotic-field v-if="bok.name === 'narcotic'" :rule-data="bok.data[0]"></narcotic-field>
      <ker-field v-if="bok.name === 'ker'" :rule-data="bok.data[0]"></ker-field>
    </div>
  </div>
</div>

Key Notes for Beginners
  1. Reactivity: We pre-defined all nested data fields (like head['arms(if any)'] and value.wild) so Vue can track changes properly. If you add new fields later, use Vue.set or the spread operator to maintain reactivity.
  2. Component Props: We pass rule-data to each component so they can access and modify the parent's data directly (two-way binding works here because we're modifying nested objects).
  3. Special Characters in Property Names: For arms(if any), we use bracket notation (ruleData.head['arms(if any)']) instead of dot notation since the name has parentheses.

内容的提问来源于stack exchange,提问作者ash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:42:09