Search code examples
javascriptvue.jsweb-component

Vue web component prop not being set through html attribute


I've got a vue web component with a numeric prop on it, and through some testing have found that doing something like this doesn't work in setting the prop value...

<script src="https://unpkg.com/vue@2"></script>
<script src="./mycomponents.js"></script>

<my-component myProp="40"></my-component>

But this will...

<script src="https://unpkg.com/vue@2"></script>
<script src="./mycomponents.js"></script>

<my-component id="mycmp"></my-component>

<script type="module">
const myComponent = document.getElementById("mycmp");
myComponent.myProp = 40;
</script>

Example component code:

<template>
    <p>{{myProp}}</p>
</template>

<script>
export default {
    name: 'MyComponent',
    props: {
        myProp: {
            type: Number,
            default: 0
        }
    }
}
</script>

I'm guessing maybe this is a timing thing, like when doing it through the html attributes the component hasn't finished being properly initialised yet? Though all the examples I saw of other people using vue web-components seemed to suggest that this should be a pretty basic use case. Hopefully it's just me doing something dumb.

Any help greatly appreciated!


Solution

  • HTML attributes often do not match 1 to 1 with JavaScript properties. In this scenario the HTML attribute to Vue.js property translation is similar to that of data-* attributes.

    Name conversion

    dash-style to camelCase conversion

    A custom data attribute name is transformed to a key for the DOMStringMap entry by the following:

    1. Lowercase all ASCII capital letters (A to Z);
    2. Remove the prefix data- (including the dash);
    3. For any dash (U+002D) followed by an ASCII lowercase letter a to z, remove the dash and uppercase the letter;
    4. Other characters (including other dashes) are left unchanged.

    camelCase to dash-style conversion

    The opposite transformation, which maps a key to an attribute name, uses the following:

    1. Restriction: Before transformation, a dash must not be immediately followed by an ASCII lowercase letter a to z;
    2. Add the data- prefix;
    3. Add a dash before any ASCII uppercase letter A to Z, then lowercase the letter;
    4. Other characters are left unchanged.

    For example, a data-abc-def attribute corresponds to dataset.abcDef.

    Applying this to your scenario we can skip step 2 (the data- part) and write the attribute like so:

    <my-component my-prop="40"></my-component>