如何在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
- Reactivity: We pre-defined all nested data fields (like
head['arms(if any)']andvalue.wild) so Vue can track changes properly. If you add new fields later, useVue.setor the spread operator to maintain reactivity. - Component Props: We pass
rule-datato each component so they can access and modify the parent's data directly (two-way binding works here because we're modifying nested objects). - 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
相关产品推荐
相关产品推荐

