1
votes

I am trying to create custom input as VueJS component. It will have <input type="text"> field and button. This component must implement such behavior: you can type text with autocomplete or press button which opens modal dialog with records from database and then select one. Something like this:

<div class="input-group">
    <input type="text" class="form-control" placeholder="Search for...">
    <span class="input-group-btn">
        <button class="btn btn-default" type="button" @click="openModal">Choose</button>
    </span>
</div>

The modal dialog will contain complicated logic and a lot of HTML code. I think I will put modal dialog in other component.

After all my custom input component will be used on page in table rows like:

<tr v-for="item in items">
    <td><input-component :item="item"><input-component></td>
</tr>

The table may contain 10-30 rows and that is a question - should I exclude heavy modal dialog code from my custom input component or it is fine in VueJS to have such many tens duplications in DOM?

What variant should I choose:

1) exclude modal dialog, place it once in top of page and call it from custom input components

<body>
    <modal-component></modal-component>
    <table><tbody>
        <tr v-for="item in items">
            <td><input-component :item="item"><input-component></td>
        </tr>
    </tbody></table>
</body>

2) include modal dialog and have tens of its duplicated code in DOM

<body>
    <table><tbody>
        <tr v-for="item in items">
            <td><input-component :item="item"><input-component></td><!--now contains <modal-component></modal-component>-->
        </tr>
    </tbody></table>
</body>
2

2 Answers

1
votes

Use a dynamic component and bind the component type to a reactive property.

Vue.component('customer-dialog', {
	template: '<p>Customer Dialog</p>'
})

Vue.component('supplier-dialog', {
	template: '<p>Supplier Dialog</p>'
})

var app = new Vue({
  el: '#app',
  data: {
    dialog: null // initial dialog to use
  },
  methods: {
  	showDialog: function(d) {
    	this.dialog = d
        // additional dialog initialization code
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="app">
  <component :is="dialog"></component>
  <button @click="showDialog('customer-dialog')">Customers</button>
  <button @click="showDialog('supplier-dialog')">Suppliers</button>
</div>

If you want to keep the switched-out dialogs in memory so that you can preserve their state or avoid re-rendering, you can wrap the dynamic component in a element.

<keep-alive><component :is="dialog"></component></keep-alive>
0
votes

Just use one modal dialog for the whole page.

Fill in the dialog with relevant data from an array that will look like this

var dialogs = [
  { name: 'john', surname: 'snow' },
  { name: undefined, surname: undefined },
  ...
]

var currentDialog = 4
var dialogData = dialogs[currentDialog]