alexjoverm / v-runtime-template

Vue component for compiling templates on the fly using a v-html like API
MIT License
605 stars 72 forks source link

Is it possible to modify the parent model from the runtime template? It currently generates a vue warning and does not work. #55

Closed fuzzzerd closed 3 years ago

fuzzzerd commented 5 years ago

I took the sample and moved the <input v-model="name"/> tag

<template>
    <div id="app">
    <h3>Template code: </h3>
    <code v-html="template"></code>
    <br><br><br><br>
    <h3>As you can see, the v-runtime-template component has access to this component scope, and updates accordingly. </h3>    
    <input v-model="name"/> {{name}}
        <v-runtime-template :template="template"></v-runtime-template>
    </div>
</template>

<script>
import VRuntimeTemplate from "v-runtime-template";
import AppMessage from "./AppMessage";

export default {
  data: () => ({
    name: "Mellow",
    template: `
      <app-message>Hello {{ name }}!
      <input v-model="name"/>
      </app-message>
    `
  }),
  components: {
    AppMessage,
    VRuntimeTemplate
  }
};
</script>

and moved it inline with the template. This does work does not work and Vue spits out this warning:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "name"

I'm wondering if there's any way around this warning or can this component only be used for read-only scenarios? I'm trying to allow customization of an input form.

fuzzzerd commented 5 years ago

After some further digging. It seems the root of my problem is that $emit() is not propogated up to the real parent. Since v-runtime-template actually creates its own child. Any $emit() fired in the template is swallowed up by v-runtime-template.

Perhaps the more appropriate question would be, is it possible to get two way data binding (vue2 style, using events) with this component?

lillem4n commented 5 years ago

Any news on this? Just hit a wall with this as well.

fuzzzerd commented 5 years ago

I had to back burner this project shortly after discovering this issue. I do not have a work around or proposed upstream change that would help -- though I suspect something is possible.

lillem4n commented 5 years ago

Hear hear, I'm doing this job for a client where this is needed. I switched to build a homegrown dynamic component to make this work... and I think I gathered enough knowledge to maybe give this a try. I will if I have the time before the deadline. :)

fuzzzerd commented 5 years ago

I'd love to see how you attacked it if you care to update this issue with your version.

lillem4n commented 5 years ago

I turned it all around, actually. Using a wrapper-component that only was responsible for creating the dynamic template string, then all functionality, methods, data etc lives in a new component instance. So the whole solution is "backwards". Not sure if that helps at all in the scope of this module, but it was a fun take and I learned a lot doing it. :)

lillem4n commented 5 years ago

Also it is all entangled in a clients proprietary solution, so I'll have to write a "clean" version here later.

yellow1912 commented 4 years ago

@fuzzzerd What if you add a method to update the model to the parent component? Inside that method you can somehow update the model? If $emit does not work then use your own event dispatcher or vuex or anything similar? I haven't tried it yet but I think it's possible.

andyyyyy commented 3 years ago

I am new to this but having the same issue in my project, and found similar project have a solution on this... gonna try it later

https://github.com/JonWatkins/vue-runtime-template-compiler/issues/2