3

I'm trying to create this component:

<template>
  <option v-for="(text, value) in options" :value="value">
    {{ text }}
  </option>
</template>

But I get this error message:

template syntax error Cannot use v-for on stateful component root element because it renders multiple elements

How could I create this kind of component? I'm using vue 2.0.5

Here are some relevant docs: https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats

5
  • 1
    How does your options variable looks, can you add this in the question and which version of Vue you are using? Commented Nov 11, 2016 at 12:18
  • 1
    I created a jsfiddle, It seems working fine in this, whats the issue here? Commented Nov 11, 2016 at 13:03
  • 1
    Now try to convert option into a component Commented Nov 11, 2016 at 13:10
  • 1
    You should have a single root element for components, v-for renders multiple elements obviously. Wrap it in a parent element. Commented Nov 11, 2016 at 13:13
  • 1
    Sure, but a option tag CAN'T be wrapped, is there any workaround for this? Maybe some way to unwrap after rendering. Commented Nov 11, 2016 at 13:21

1 Answer 1

3

You can't do that inside a component, you need one top level element so you're going to need to wrap that in a select and have the entire select box as your component. You will then need to pass any options as props, so:

Template:

<template id="my-select">
  <select>
    <option v-for="(text, value) in options" :value="value">
      {{ text }}
    </option>
  </select>
</template>

Component:

Vue.component('my-select', {
  props: ['options'],
  template: "#my-select"
});

View Model:

new Vue({
  el: "#app",
  data: {
    options: {
      "1": "foo",
      "2": "bar",
      "3": "baz"
    }
  }
});

Now in your root page, just pass the options as a prop:

<my-select :options="options"></my-select>

Here's the JSFiddle: https://jsfiddle.net/zL6woLa2/

Sign up to request clarification or add additional context in comments.

2 Comments

Since that's the only way, is this the right way to make v-model work again? jsfiddle.net/neves/zL6woLa2/1 and why slot doesn't work inside select?
I think that looks pretty good. Personally, I try to keep everything associated with the component inside the component, so I would probably keep v-model in the component and $emit to a bus on an event. I'm not sure why the slot doesn't work here, but it's probably easier to just pass the default option as a prop and show it if a value was passed. Here's my updated version of your fiddle, but as I say, this is how I would do it, so stick with your solution if you prefer: jsfiddle.net/08qr3rL9

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.