Subscribe on changes!

Custom element 'Array/Object' props Bug

avatar
Aug 18th 2021

Version

3.2.4

Reproduction link

https://codesandbox.io/s/vue-3-2-custom-element-array-bug-sqpip

Steps to reproduce

  1. Define component
const CustomSelect = Vue.defineCustomElement({
    props: {
        options: Array
    },
    template: `
      <select :value="value" @input="clicked">
        <option
            v-for="option in options"
            :key="option"
            :value="option"
        >
          {{ option }}
        </option>
      </select>`,
});

customElements.define('custom-select', CustomSelect);
  1. Use component
<custom-select options="['1', '2', '3']" value="1"/>
  1. Show in console
[Vue warn]: Invalid prop: type check failed for prop "options". Expected Array, got String with value "['1', '2', '3']". 
  at <CustomSelect options="['1', '2', '3']" value="1" >

What is expected?

Convert the value of the 'options' prop to an Array.

What is actually happening?

The prop type 'Array' is ignored.

avatar
Aug 18th 2021

you are passing a string, so you get a string.

the recommended best practice for custom elements seems to be to use DOM properties for passing object/arrays values. Which Vue already does.

https://developers.google.com/web/fundamentals/web-components/best-practices#always-accept-primitive-data-strings,-numbers,-booleans-as-either-attributes-or-properties.

https://developers.google.com/web/fundamentals/web-components/best-practices#aim-to-only-accept-rich-data-objects,-arrays-as-properties.

So this will work if used in a Vue app:

<custom-select :options="['1', '2', '3']" value="1"/>

Other frameworks may have other ways of setting a DOM property. And yes, in vanilla JS you would have to use JS to set that prop and can't use an attribute.

avatar
Aug 18th 2021

Probably worth adding a note to docs at https://v3.vuejs.org/guide/web-components.html#definecustomelement. Could you open a PR or issue in the vuejs/docs repo?