vue绑定父子组件

Posted

技术标签:

【中文标题】vue绑定父子组件【英文标题】:Vue binding parent and child components 【发布时间】:2018-07-03 22:34:30 【问题描述】:

如何在 Vue.js 中将父模型绑定到子模型?

下面的这些代码可以正常工作。如果我手动填写输入,则子模型将其值返回给父模型。

但问题是,如果来自父级的 AJAX 请求的数据集,输入不会自动填充。

谁能帮我解决这个问题?

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: ''
                
            
        ,
        components:  'form-input': FormInput ,
        created: function() 
            axios.get('http://api.example.com')
                .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>

【问题讨论】:

使用v-bind而不是v-model 在父模板中,绑定 Props=fieldModel。 @Ohgodwhy 我应该更改哪个 v-model? @Sphinx 它实际上是绑定的,我已经更新了代码 还是不行? 【参考方案1】:

如果您利用v-model in components,事情会变得更简单。

如果您将v-model 放在组件上,该组件应采用名为value 的道具,并应发出input 事件以触发其更新。

我喜欢创建一个computed 来隐藏事件发射,并允许我在我的组件中只使用v-model computed

new Vue(
  el: '#app',
  data: 
    o: 
      name: '',
      address: ''
    
  ,
  components: 
    'form-input': 
      template: '#form-input',
      props: ['value'],
      computed: 
        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.com/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>

【讨论】:

非常感谢,您的解释帮助我摆脱了this Vue warning,而不会丢失数据同步,终于!【参考方案2】:

mounted() 挂钩阻止来自父级的后续更新。

移除挂载并将 v-model 更改为 '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>

演示 CodeSandbox

【讨论】:

不要使用v-model,使用valuev-model 是双向的,你想要单向绑定。 如果你在处理返回值,v-model不是,所以它没有做双向绑定。 我在这里评论你的代码,特别是这一行:v-model='fieldModel' @input="forceUpper($event, fieldModel)" 它应该是:value 而不是v-model,因为你正在分别处理input 事件。跨度> 你的两个答案都达到了目标。顺便说一句,RichardMatsen 的回答给我警告说 避免直接改变道具,因为只要父组件重新渲染,该值就会被覆盖。相反,请使用基于道具值的数据或计算属性。。所以我选择了罗伊的答案。 很公平,他有更全面的答案。

以上是关于vue绑定父子组件的主要内容,如果未能解决你的问题,请参考以下文章

Vue2.0父子组件之间的双向数据绑定问题解决方案

vue 父子组件数据的双向绑定大法

Vue中父子组件的双向数据绑定

Vue中父子组件的双向数据绑定

Vue中父子组件的双向数据绑定

Vue父子组件双向数据绑定