2

I am trying to create a modal component that does not use Vue slots and only takes a configuration object to determine the content of the modal. So far I've managed to figure out a way to fill the component with the required input fields and form elements but I'm having trouble with binding the data from the input to the v-model variables.

A person would use the component by passing a content array of objects as a prop:

<ReusableDialog
  :content="[ 
    {label: 'Text Field', type: 'inputField'}, 
    {label: 'Text Area', type: 'textArea'} 
  ]"
/>

And then I can access that prop in my ReusableDialog template and loop through the array. For each item in that array I will check the type of form element that was entered (e.g. "textArea", "inputField") and dynamically generate the element.

<div v-for="(item, index) in props.content" :key="item">
  <template v-if="item.type == 'inputField'" style="margin-top: 1rem;">
    <label>{{ item.label }}</label>
    <input
      type="text"
      :v-model="contentArray[index]"
      placeholder="Enter text"
    />
  </template>

  <template v-if="item.type == 'textArea'" style="margin-top: 1rem;">
    <label>{{ item.label }}</label>
    <textarea
      name="textarea"
      :v-model="contentArray[index]"
      cols="10"
      rows="10"
    ></textarea>
  </template>
</div>
<button label="submit" @click="getAllData" />

My setup looks like this:

    setup(props) {
            const displayDialog = ref(false);
            const contentArray = ref([null, null, null, null, null, null, null, null, null]);

            const open = () => {
                displayDialog.value = true;
            };
            const close = () => {
                displayDialog.value = false;
            };

            const getAllData = () => {
                console.log(contentArray.value);
            }

            return {
                displayDialog, open, close, props, getAllData, contentArray
            }
        }
    }

When the getAllData() method print the contentArray all the values remain null. Using my example above the first and the second values should change with the input but they do not. Not sure if I'm in the direction here but I need some suggestions on if there is a better way to do this?

1 Answer 1

2

Everything is setup correctly, it's just a small typo, if we can call it that.

v-model should not have the :

so

  :v-model="contentArray[index]"

should be

  v-model="contentArray[index]"

As an aside you can set length of array with

const contentArray = Vue.ref(new Array(props.content.length));
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, with such a setup, how would I handle any validation logic? Would I have to also pass a function to handle validation alongside each element in my 'contentArray'?Or should I just take the data and emit it to the parent element to handle that? Not sure what the best approach would be here.
I would probably include a validation function in the object. You could also pass a regex and use a function to validate that regex, but that could be more restrictive. I think sending it to parent for validation would create more complexity without any clear benefit, though YMMV.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.