AngeloC
AngeloC

Reputation: 3523

how to create a select in vue's createElement?

I have a vue component that uses template, I'd like to change it to use render function, I know createElement('h1', 'title'), but how to use it with something like 'select' with all the options? here is the template based component:

https://jsfiddle.net/aaoehLqe/

<div id="app">
  <p>{{ message }}</p>
  <myselect  v-bind:option= "option" ></myselect>
  {{option}}
</div>

Upvotes: 5

Views: 35858

Answers (3)

pespantelis
pespantelis

Reputation: 15382

You could try this:

Vue.component('myselect', {
  props: ['option'],
  data () {
    return {
      items: [
        //
      ]
    }
  },
  render (h) {
    var self = this

    return h('select', {
      class: { 'form-control': true },
      domProps: { value: this.option.value },
      on: {
        input (event) {
          self.option.value = event.target.value
        }
      }
    }, this.items.map((item) => h('option', {
      attrs: { value: item }
    }, item)))
  }
})

[ demo ]

Please check the v-if and v-for & v-model sections.

Upvotes: 1

Saurabh
Saurabh

Reputation: 73609

Here is the select component with createElement:

Vue.component('myselect', {
  props: ['option'],
  render: function(createElement) {
    var self = this
    return createElement(
      'select', {
        domProps: {
          value: self.option.value
        },
        on: {
          input: function(event) {
            self.option.value = event.target.value
          }
        }
      }, [
        createElement('option', {
          attrs: {
            value: 0
          }
        }, 'Under 1'),
        createElement('option', {
          attrs: {
            value: 1
          }
        }, '1'),
      ]
    )
  },
})

You can see the working fiddle here: https://jsfiddle.net/aaoehLqe/1/

To understand how it works, you can see the API details of createElement in docs:

// @returns {VNode}
createElement(
  // {String | Object | Function}
  // An HTML tag name, component options, or function
  // returning one of these. Required.
  'div',
  // {Object}
  // A data object corresponding to the attributes
  // you would use in a template. Optional.
  {
    // (see details in the next section below)
  },
  // {String | Array}
  // Children VNodes. Optional.
  [
    createElement('h1', 'hello world'),
    createElement(MyComponent, {
      props: {
        someProp: 'foo'
      }
    }),
    'bar'
  ]
)

Upvotes: 8

Bert
Bert

Reputation: 82449

Here's a basic version based off your fiddle.

Vue.component("mySelect", {
  props:["value"],
  render(h){
    const vm = this;
    let options = [];
    for (let c = 0; c < 18; c++)
      options.push(h("option", {
        domProps:{innerHTML: c},
        attrs:{value: c},
      }))
    return h("select",{
      domProps:{
        value: this.value.value
      },
      on:{
        input(event){
          vm.$emit('input', {value:event.target.value})
        }
      }
    }, options)
  }
})

Upvotes: 1

Related Questions