admin管理员组

文章数量:1399976

How to binding parent's model to child in Vue.js?

These codes below is works fine. if i fill the input manually, then child's model return it's value to the parent's model.

But the issue is, if the data set from AJAX request in a parent, the input doesn't automatically filled.

Can anyone help me on this?

Form.vue

<template>
    <form-input v-model="o.name" :fieldModel="o.name" @listenChanges="o.name = $event"/>
    <form-input v-model="o.address" :fieldModel="o.address" @listenChanges="o.address = $event"/>
</template>

<script>
    import FormInput from '../share/FormInput.vue'

    export default {
        data () {
            return {
                o: {
                    name: '',
                    address: ''
                }
            }
        },
        ponents: { 'form-input': FormInput },
        created: function() {
            axios.get('')
                .then(response => { 
                    this.o.name = response.data.name
                    this.o.address = response.data.address
                })
                .catch(e => { console.log(e) })
        }
    }
</script>

FormInput.vue

<template>
    <input type="text" v-model='fieldModelValue' @input="forceUpper($event, fieldModel)">
</template>

<script>
    export default {
        props: ['fieldModel'],
        data() {
            return {
                fieldModelValue: ''
            }
        },
        mounted: function() {
            this.fieldModelValue = this.fieldModel;
        },
        methods: {
            forceUpper(e, m) {
                const start = e.target.selectionStart;
                e.target.value = e.target.value.toUpperCase();
                this.fieldModelValue = e.target.value.toUpperCase();
                this.$emit('listenChanges', this.fieldModelValue)
            }
        }
    }
</script>

How to binding parent's model to child in Vue.js?

These codes below is works fine. if i fill the input manually, then child's model return it's value to the parent's model.

But the issue is, if the data set from AJAX request in a parent, the input doesn't automatically filled.

Can anyone help me on this?

Form.vue

<template>
    <form-input v-model="o.name" :fieldModel="o.name" @listenChanges="o.name = $event"/>
    <form-input v-model="o.address" :fieldModel="o.address" @listenChanges="o.address = $event"/>
</template>

<script>
    import FormInput from '../share/FormInput.vue'

    export default {
        data () {
            return {
                o: {
                    name: '',
                    address: ''
                }
            }
        },
        ponents: { 'form-input': FormInput },
        created: function() {
            axios.get('http://api.example.')
                .then(response => { 
                    this.o.name = response.data.name
                    this.o.address = response.data.address
                })
                .catch(e => { console.log(e) })
        }
    }
</script>

FormInput.vue

<template>
    <input type="text" v-model='fieldModelValue' @input="forceUpper($event, fieldModel)">
</template>

<script>
    export default {
        props: ['fieldModel'],
        data() {
            return {
                fieldModelValue: ''
            }
        },
        mounted: function() {
            this.fieldModelValue = this.fieldModel;
        },
        methods: {
            forceUpper(e, m) {
                const start = e.target.selectionStart;
                e.target.value = e.target.value.toUpperCase();
                this.fieldModelValue = e.target.value.toUpperCase();
                this.$emit('listenChanges', this.fieldModelValue)
            }
        }
    }
</script>
Share Improve this question edited Jan 24, 2018 at 19:28 stkertix asked Jan 24, 2018 at 19:12 stkertixstkertix 811 silver badge10 bronze badges 9
  • 1 use v-bind instead of v-model – Ohgodwhy Commented Jan 24, 2018 at 19:16
  • in parent template, bind Props=fieldModel. <form-input v-model="o.name" fieldModel="o.name" @listenChanges="o.name = $event"/> – Sphinx Commented Jan 24, 2018 at 19:22
  • @Ohgodwhy which v-model should i change? – stkertix Commented Jan 24, 2018 at 19:27
  • @Sphinx it's actually bind, i've update the code – stkertix Commented Jan 24, 2018 at 19:31
  • still not working? – Sphinx Commented Jan 24, 2018 at 19:36
 |  Show 4 more ments

2 Answers 2

Reset to default 4

Things are more straightforward if you take advantage of v-model in ponents.

If you put v-model on a ponent, the ponent should take a prop named value, and should emit input events to trigger it to update.

I like to make a puted to hide the event emitting, and allow me to just v-model the puted inside my ponent.

new Vue({
  el: '#app',
  data: {
    o: {
      name: '',
      address: ''
    }
  },
  ponents: {
    'form-input': {
      template: '#form-input',
      props: ['value'],
      puted: {
        fieldModelValue: {
          get() {
            return this.value;
          },
          set(newValue) {
            this.$emit('input', newValue.toUpperCase());
          }
        }
      }
    }
  },
  // Simulate axios call
  created: function() {
    setTimeout(() => {
      this.o.name = 'the name';
      this.o.address = 'and address';
    }, 500);
  }
});
<script src="//unpkg./vue@latest/dist/vue.js"></script>
<div id="app">
  Name ({{o.name}})
  <form-input v-model="o.name"></form-input>
  Address ({{o.address}})
  <form-input v-model="o.address"></form-input>
</div>

<template id="form-input">
    <input type="text" v-model='fieldModelValue'>
</template>

The mounted() hook is blocking subsequent updates from the parent.

Remove mounted and change v-model to 'fieldModel'

<template>
    <input type="text" :value='fieldModel' @input="forceUpper($event, fieldModel)">
</template>

<script>
  export default {
    props: ['fieldModel'],
    data() {
      return {
          fieldModelValue: ''
      }
    },
    // mounted: function() {
    //   this.fieldModelValue = this.fieldModel;
    // },
    methods: {
      forceUpper(e, m) {
        const start = e.target.selectionStart;
        e.target.value = e.target.value.toUpperCase();
        this.fieldModelValue = e.target.value.toUpperCase();
        this.$emit('listenChanges', this.fieldModelValue)
      }
    }
  }
</script>

Demo CodeSandbox

本文标签: javascriptVue binding parent and child componentsStack Overflow