Search code examples
vue.jsvuejs2web-componentvue-cli

How to pass an object as a prop to my vue-generated web component


My goal is to create a web component and to use it in a vue app. The creation is not a problem, nor the usage. What I did not succeed to do is to pass an object as a prop to my web component. Passing a boolean or a string seems to work fine though.

My vue component props:

props:{
    user: {
      type: Object,
      required: true,
      default: function() {
        return {
          name: "Default",
          age: 0,
          mail: "[email protected]"
        }
      }
    },
    readOnly:{
      type: Boolean,
      default: function(){
        return false
      }
    }
  }

The script I used to create the web component with vue-cli:

npm run build -- --target wc --inline-vue --name my-web-component

The very simple app I want to use my web component in:

<html>
    <head>
        <meta charset="utf-8">
        <title>my-web-component demo</title>
        <script src="https://unpkg.com/vue"></script>
        <script src="./my-web-component.js"></script>
    </head>
    <body>
        <div id="myapp">
            <my-web-component></my-web-component>
        </div>
    </body>
</html>    
<script>
    new Vue({
        el: "#myapp",
        data: {
            user: {
                name: "John",
                age: 31,
                mail: "[email protected]"
            }
        }
    })
</script>

My attempts to pass an object as the user prop:

1. <my-web-component></my-web-component> //expected

2. <my-web-component v-bind:user="user"></my-web-component> //not expected

3. <my-web-component v-bind:user.prop="user"></my-web-component> //not expected

The results (obtained with a console.log inside the mounted hook of the component):

  1. user = default prop value { name: "Default", age: 0, mail: "[email protected]" }
  2. user = [object Object]
  3. user = default prop value { name: "Default", age: 0, mail: "[email protected]" }

No problem whatsoever with the readOnly prop.

So, do you have any idea how to pass an object as a prop to my vue-generated web component?

Here is a link to the github repo: https://github.com/Miloo25155/my-web-component.git

The built web component is in the dist folder, as well as the simple vue app (dist/demo.html)

Thank you for your time.


Solution

  • The Vue Webcomponent Wrapper does deliver the props to your Vue component, but it will only work with strings. That's why you see [Object object] in example 2. A possible workaround for this is to accept a string value for user and JSON.parse it inside your component (instead of assuming the prop will be an object).

    You probably have good reasons to build a standalone webcomponent version of your component, maybe you want to deliver this as a product to users or clients. If I were to be an end-user of your webcomponent i'd expect to use it like this:

    <html>
    <head>
    <script src="my-web-component.js"></script>
    </head>
    <body>
    <my-web-component user="{name: 'joshua'}"></my-web-component>
    </body>
    </html>
    

    If I look at the code sample you have provided I see that you are trying to use the webcomponent-version of your component inside a small Vue app. As you have experienced and I explained this will not work, unless you JSON.stringify user right before passing it to my-web-component. I guess you have two options to choose from: either develop the component as a regular vue component (and exporting it as a standalone webcomponent when you are done) or treating it like a real webcomponent (including it's limitations, being you will not get the high levels of reactivity you are used to with regular components).