2

Vue.js has a built-in directive called v-for which is used to literate over list.

HTML code

<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>

Script code

var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

Here, by using the v-for directive, the elements in items array are returned as variables named item. Here, the variables returned by this v-for directive, can be used in the html DOM. How do I create such a custom directive which returns a variable to the html DOM?

Note: I did search for v-for directives source code in the source code of vuejs, but could not find. Please help me to get this as I am very new to vuejs. Thank you.

Edit:

What I currently have?

There are 3 similar input groups for inputting 'First Name', 'Last Name' and 'Address' respectively. Each input field has label, state, disabled, value, and max properties which are stored in a inputOptions array.

<!-- HMTL -->
<b-input-group :prepend="inputOptions.firstName.label">
    <b-form-input 
        :state="inputOptions.firstName.state" 
        v-model="inputOptions.firstName.value" 
        :disabled="inputOptions.firstName.disabled" 
        :maxlength="inputOptions.firstName.max"
        ></b-form-input>
</b-input-group>

<b-input-group :prepend="inputOptions.lastName.label">
    <b-form-input 
        :state="inputOptions.lastName.state" 
        v-model="inputOptions.lastName.value" 
        :disabled="inputOptions.lastName.disabled" 
        :maxlength="inputOptions.lastName.max"
        ></b-form-input>
</b-input-group>

<b-input-group :prepend="inputOptions.address.label">
    <b-form-input 
        :state="inputOptions.address.state" 
        v-model="inputOptions.address.value" 
        :disabled="inputOptions.address.disabled" 
        :maxlength="inputOptions.address.max"
        ></b-form-input>
</b-input-group>

//Script

inputOptions: {
            firstName: {
                label: 'First Name',
                state: true,
                value: 'Foo',
                disabled: true,
                max: 45
            },
            lastName: {
                label: 'Last Name',
                state: true,
                value: 'Bar',
                disabled: true,
                max: 45
            },
            address: {
                label: 'Address',
                state: false,
                value: 'Foo, Bar.',
                disabled: true,
                max: 255
            },
}

What I needed to achieve

For each input-group field, it is needed to provide the property names one by one. Assume that I have created a vue directive called mydirective and code is simplified as follows.

<!-- HMTL -->
<b-input-group v-mydirective="inputOptions.firstName as myProperty" :prepend="myProperty.label">
    <b-form-input 
        :state="myProperty.state" 
        v-model="myProperty.value" 
        :disabled="myProperty.disabled" 
        :maxlength="myProperty.max"
        ></b-form-input>
</b-input-group>

<b-input-group v-mydirective="inputOptions.lastName as myProperty" :prepend="myProperty.label">
    <b-form-input 
        :state="myProperty.state" 
        v-model="myProperty.value" 
        :disabled="myProperty.disabled" 
        :maxlength="myProperty.max"
        ></b-form-input>
</b-input-group>

<b-input-group v-mydirective="inputOptions.address as myProperty" :prepend="myProperty.label">
    <b-form-input 
        :state="myProperty.state" 
        v-model="myProperty.value" 
        :disabled="myProperty.disabled" 
        :maxlength="myProperty.max"
        ></b-form-input>
</b-input-group>

//Script

inputOptions: {
            firstName: {
                label: 'First Name',
                state: true,
                value: 'Foo',
                disabled: true,
                max: 45
            },
            lastName: {
                label: 'Last Name',
                state: true,
                value: 'Bar',
                disabled: true,
                max: 45
            },
            address: {
                label: 'Address',
                state: false,
                value: 'Foo, Bar.',
                disabled: true,
                max: 255
            },
}
Tharindu Sathischandra
  • 1,654
  • 1
  • 15
  • 37

1 Answers1

1

HTML

In your template, iterate over the multiple inputOptions using v-for like:

<div id="app">
  <b-input-group v-for="option in inputOptions" :key="option.label" :option="option" />
</div>

SCRIPT

Create custom components for the group, input, and label, like:

Vue.component('b-label', {
  props: ['label'],
  template: '<div>{{ label }}</div>'
})

Vue.component('b-form-input', {
  props: ['state', 'value', 'disabled', 'maxlength'],
  template: '<input type="text" :value="value" />'
})

Vue.component('b-input-group', {
  props: ['option'],
  template:
  `<div>
    <b-label :label="option.label" />
    <b-form-input
        :state="option.state"
        v-model="option.value"
        :disabled="option.disabled"
        :maxlength="option.max" />
  </div>`
})

FIDDLE

Here is a demo on JSFiddle

This is a basic example of how to use components. Whatever transformations you need to do to the strings can be done in the associated components, via computed properties or methods. You can see a demo by clicking the link where I use a computed property to transform the labels into lowercase. That should be enough to get you going.

Dan
  • 59,490
  • 13
  • 101
  • 110