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

Cannot reuse element after it's detached #178

Closed dsuryd closed 4 years ago

dsuryd commented 4 years ago

After an element is detached and then sometimes later reattached, the inner Vue component isn't recreated. It's caused by the this.__detached__ value remains true after the component is destroyed.

Shouldn't the following function set the this.__detached__ back to false at the end?

https://github.com/karol-f/vue-custom-element/blob/10fe7a091948f2e14f093f77ebff44a06c9917c9/src/vue-custom-element.js#L51-L56

karol-f commented 4 years ago

Hi, it's defined there - https://github.com/karol-f/vue-custom-element/blob/10fe7a091948f2e14f093f77ebff44a06c9917c9/src/vue-custom-element.js#L39 . Is something not working?

dsuryd commented 4 years ago

Thank you for responding quickly. I am aware of that line, but here's the scenario where it fails: when the component is detached, __detached__ is set to true. After the destroy timeout occurs, it is still true. Therefore when the element is re-attached, the logic that will recreate the Vue component if __detached__ is false will not execute because the variable is still true at this point, and is only set to false at the end of the connectedCallback.

karol-f commented 4 years ago

You are right, thank You for bringing this up! Fixed in vue-custom-element@3.2.9 - https://github.com/karol-f/vue-custom-element/releases/tag/v3.2.9

pixelbits-mk commented 4 years ago

After an element is detached and then sometimes later reattached, the inner Vue component isn't recreated. It's caused by the this.__detached__ value remains true after the component is destroyed.

Shouldn't the following function set the this.__detached__ back to false at the end?

https://github.com/karol-f/vue-custom-element/blob/10fe7a091948f2e14f093f77ebff44a06c9917c9/src/vue-custom-element.js#L51-L56

We are getting an undefined instance error because the above code is not completely cleaning up after itself. In the following lines of code, the vue element instance property getter and setter has been defined/overwritten: https://github.com/karol-f/vue-custom-element/blob/master/src/utils/props.js#L93-#L106

If this is not cleaned up (i.e. delete element.prop after destroyTimeout), then accessing the property will cause an undefined error because __vue_custom_element__ is no longer defined:

https://github.com/karol-f/vue-custom-element/blob/master/src/utils/props.js#L95

Can this issue please be fixed? For right now, we are fixing this by deleting the property explicitly after the element is destroyed.

options.destroyTimeout !== null && setTimeout(() => { 
   if (this.__detached__ && this.__vue_custom_element__) { 
     this.__vue_custom_element__.$destroy(true); 
     delete this.__vue_custom_element__; 
     delete this.__vue_custom_element_props__; 
     delete this['someProp'];
   }