vue.jscoffeescriptv-model

Chain v-model succintly?


Let below code be Child, it is embedded in its Parent, and has a NestedChild which finally features a <input> or <textarea>.

Now, the code below won't work. Parent rerenders and updates value prop and thus the result is only the last letter typed.

// Child.vue
<script lang='coffee'>
  export default
    props: ['value']
    computed:
      edit:
        get: -> @value
        set: (e) -> @$emit 'input', e
    # ...
</script>

<template lang='pug'>
  div
    NestedChild( v-model='edit' )
    //- ...
</template>

Text instead needs to be stored in a proxy var.

...

data: -> proxy: ''
computed:
  edit:
    get: -> @proxy = @value
    set: (e) -> @$emit 'input', @proxy = e
...

Which works for NestedChild -> Child, or Child -> Parent, but not Nested -> Parent, where Parent is in the end storing it in Vuex, disk etc. The value doesn't get updated in Parent.

Simple way to make it work is to pass a propName prop to Child which then directly updates relevant data in Vuex by propName, aka by not using v-model at all. But that

Thus really only solving the problem for Child, but not for Parent -> Child -> NestChild1 -> NestChild2 -> ... -> input

So, how to chain v-model succintly? Thanks.


Solution

  • So, no need to proxy the value in a separate data var. The original code snippet from the question should work, and it will bubble up to parent and parent's parent etc.

    Here's the code again, only converted to javascript and html instead of coffeescript and pug; otherwise identical to the one in the question.

    <template>
      <div>
        <NestedChild v-model='edit'>
        <!-- ... -->
      </div>
    </template>
    
    <script>
    export default {
      props: ['value'],
      computed: {
        edit: {
          get: function()  { this.value },
          set: function(e) { this.$emit('input', e) }
        }
      }
        // ...
    };
    </script>
    

    (Decided to leave the question, maybe it'd be of use to someone)