0
votes

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.

1
You'll get more feedback if you create a small gist instead of linking to a git repo. A repo is not appropriate for stackoverflow since the code will change over time. A gist can more easily remain intact and still keep working for a long time.snowcode
How exactly you are logging the info? Because you know [object Object] is not very useful. You can use JSON.stringify to serialize the object and log it ......Michal Levý
@snowcode this repo has only been created in order to share the code. I do not intend to update it, but thanks for the advice !Miloo
@MichalLevý I am directly logging the prop value with a console.log(). In the 2nd example the value is the string "[object Object]", not very useful indeed but no need to serialize itMiloo
A jsfiddle means I can instantly know if your code is able to run and show the problem you're talking about. I click 1 link to the fiddle, and within seconds I'm literally running the sample and can see the problem. With git, I have to check it out and then run it somehow, which I wont do, that's just too much effort, so you'll lose a lot of people looking at the code and helping you with your problem.snowcode

1 Answers

2
votes

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).