简体   繁体   中英

Vue.js how to render dynamic component?

I'am building a laravel project with Vue3 . The main concept is that i'm generating input attributes from the backend and i would like to render out these in Vue. Now i have 2 component. FormComponent that contains the basic form tags, submit button , form title, etc... The second is the BaseInputComponent that contains the basic <input> tag. In the future there will be more components for options , checkboxes , etc... What is the best way to render out these input components with binding from the FormComponent . Firstly i build html string with attributes from php like this: '<base-input-component label="xyz"></base-input-component>' but i cant render this out from vue . The another possible way is that i use switch-case in FormComponent and insert the right input, option, checkbox component. I would like to handle submit in FormComponent . The code is incomplete yet, first i want to render these component and I want ot reach their values.What will be the best solution for this?

 //This will be the first option json that comes from the backend, but i cant render these out from string. { zip_code: '<base-input-component name="zip_code" label="Zip code"></base-input-component>', city: '<base-input-component name="city" label="City"></base-input-component>' } //This will be the second option json that comes from the backend { zip_code: { name: 'zip_code', label: 'Zip code' placeholder: 'sadas', validation_rules: 'required|string', type: 'text' }, city: { name: 'city', label: 'City' placeholder: 'sadas', validation_rules: 'required|string', type: 'text' } }

BaseInputComponent :

 <script> export default { name: "BaseInputComponent", props: { label: { type: String, default: '' }, modelValue: { type: [String, Number], default: '' } }, } </script>
 <template> <div class="w-full md:w-1/2 p-3"> <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"> {{ label }} </label> <input:value="modelValue" @input="$emit('update:modelValue', $event.target.value)" class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500" </div> </template>

If I do get your question clearly, I think what you need is v-for . See Vue3 Documentation: List Rendering

You don't need to send the whole HTML text like option 1 from backend, given that is uncessary, and option 1 will be involved to either Element.appendChild() in javaScript or v-html in Vue template (not secure).

You can simply use option 2 data, assuming currently you only have name and label , which should be Objects inside an Array:

data = [
  zip_code: {
    name: 'zip_code',
    label: 'Zip code'
  },
  city: {
    name: 'city',
    label: 'City'
  }
]

Then use v-for within your template:

<template>
  <div>
    <base-input-component
      v-for="(item, index) in data"
      :key="index"
      :name="item.name"
      :label="item.label"
    />
  </div>
</template>

Equals to:

<template>
  <div>
    <base-input-component
      name="zip_code"
      label="Zip code"
    />
    <base-input-component
      name="city"
      label="City"
    />
  </div>
</template>

That should render all dynamic base-input-component you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM