karol-f / vue-custom-element

Vue Custom Element - Web Components' Custom Elements for Vue.js
https://karol-f.github.io/vue-custom-element/
MIT License
1.97k stars 187 forks source link

Empty boolean prop not recognised #128

Closed woubuc closed 6 years ago

woubuc commented 6 years ago

Hi! We've been using vue-custom-element the last couple of weeks on our new project and we love it! Custom elements are so much more flexible than regular Vue components, and not having to include the Vue runtime is so great.

Unfortunately I did find an inconsistency in how props are handled between Vue and vue-custom-element.

If I have the following prop:

props: {
    required: { type: Boolean, default: false }
}

With this HTML code:

<component required></component>

In regular Vue, this code works as expected (this.required is true), but when doing the same on a custom element, the boolean remained false.

The following is needed to make it work:

<component required="true"></component>

But this pattern actually generates an error in regular Vue (Invalid prop: type check failed), so it's not really consistent or intuitive.

karol-f commented 6 years ago

Ok, thanks for the issue. I'll look at it. Regards.

dennisbaskin commented 6 years ago

I have found that for Booleans all I need is the type without a default:

props: {
  required: Boolean,
},

This will get you the desired result. By default it will not be present, and when adding a valueless attribute it will be true.

woubuc commented 6 years ago

This solution does not appear to work for me @dennisbaskin

props: {
    required: { type: Boolean },
}
<component required></component>

With this code, required will still be false

dennisbaskin commented 6 years ago

@woubuc here's a jsfiddle: https://jsfiddle.net/kaLe610e/7/. Maybe share how you are using it through another fiddle?

woubuc commented 6 years ago

Curious, it seems prop: Boolean works, but prop: { type: Boolean } does not. https://jsfiddle.net/g5p6zs89/4/

I wonder if this is different on purpose? Cause my understanding is that both versions should be functionally the same.

Anyway, this does give me a solution, so thanks for your help @dennisbaskin! Although I think the inconsistent API should still be looked at further.

dennisbaskin commented 6 years ago

The way I tend to look at it is that for Boolean properties I never need to set defaults. By default it’s either added or not. If it needs to be a negated property I name the attribute appropriately. For example show-comments would not show comments by default and would need the user to add the attribute. And in reverse, if I want to show comments by default I would provide an option to pass the attribute hide-comments.

For me following this pattern made the problem of not being consistent with Vue a non issue.

woubuc commented 6 years ago

My problem is that omitting a default value will make it default to undefined rather than false, so while it's a falsy value (matching !prop) it won't match prop === false. JSFiddle illustrating this.

karol-f commented 6 years ago

Fixed in https://github.com/karol-f/vue-custom-element/releases/tag/v3.2.2, thanks for reporting!