Home > Net >  Vue web component prop not being set through html attribute
Vue web component prop not being set through html attribute

Time:05-07

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!

CodePudding user response:

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 drop the data- part and write the attribute like so:

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

CodePudding user response:

You can try to setAttribute for prop converting it to string:

<my-component></my-component>

<script type="module">
  const myComp= document.querySelector("my-component");
  myComp.setAttribute("my-prop", JSON.stringify(40));
</script>

then in your component receive prop as string and convert it to number (or if you need object JSON.parse it):

<template>
  <p>{{ myPropNr }}</p>
</template>

props: {
  myProp: {
     type: String,
     default: 0
  }
},
computed: {
  myPropNr() {
    return Number(this.myProp)
  }
}
  • Related