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

Function / Objects as attribute not working #127

Closed do-web closed 6 years ago

do-web commented 6 years ago

Check out the exmaple:

https://codesandbox.io/s/n5mrnq5z04

if i try this with objects this does also not work:

karol-f commented 6 years ago

@do-web Passing arrays, objects and functions should be done using JS, e.g.:

document.querySelector('test-component').func = function(){alert('test')};

//and then

document.querySelector('test-component').getVueInstance().func();

Feel free to ask more questions. Regards!

do-web commented 6 years ago

Maybe this can be a new feature? So it shoud be possible to check the type when it is defined in the vue component.

karol-f commented 6 years ago

I think that passing Object/Arrays as props, with defined prop type will be doable.

But I don't think that eval on strings to execute functions is a good idea.

So my proposition is to do it for Objects/Arrays.

karol-f commented 6 years ago

Hi, I've fiddled with some possible solution but I don't think it's good enough. What I did is JSON.parse(...) props of type Object/Array, if value is a string.

Unfortunately JSON.parse is strict so you have to pass valid JSON - I don't think it's a good fit for us because, in many cases, conversion will fail. I don't want to introduce separate library just to parse JS Objects/Arrays from string.

Regards!

thomasaull commented 3 years ago

@karol-f Do you have an example of how I'd integrate this on a low level? Basically what I need to do is to pass an object of data via the attribute in the markup:

<my-custom-element confg='{"data": "test"}'><my-custom-element>

This works when I do JSON.parse(this.config) in my component. However I'd like to add this on a lower level

karol-f commented 3 years ago

@thomasaull When You pass something using HTML it will always be string. Just use JS for that:

document.querySelector('my-custom-element').confg = {"data": "test"}

You can also use lifecycle methods of vue custom element:

thomasaull commented 3 years ago

Thanks for your input @karol-f, I'll give it a try :)

thomasaull commented 3 years ago

@karol-f I'ts working good, thanks again for your help1 I did try it with synchronous loading first and was able to check the component for Object/Array Props and try to JSON.parse those if there was data. Now I'm trying to do the same with lazy loaded components and I was wondering if, I could access the types of the props in the beforeCreateVueInstance callback:

 beforeCreateVueInstance(RootComponentDefinition) {
  console.log(RootComponentDefinition.props.config); // props.config is there, but props.config.type is `null`
  return RootComponentDefinition
},

With the synchronous loading I just extracted this information from the imported component, but that's not possible with the lazy loaded one of course.

I guess it would be the best approach to export the props from the component since I need this information for registration of props for the lazy component as in your example

karol-f commented 3 years ago

@thomasaull You should have, even when lazy loading, access to component's props. This callback is executed when lazy loaded component is already loaded (unless You forgot to return).

Example would help (e.g. on CodeSandbox).

thomasaull commented 3 years ago

@karol-f I created an example on Codesandbox: https://codesandbox.io/s/nifty-thompson-327l2?file=/src/main.js

jcupps commented 1 year ago

Interestingly, the function prop works in the OP example by changing it to <test-component func="alert('test')"></test-component>. Not sure how to pass arguments though; event is available but I don't see how to access the payload.