在VUE.JS上使用v-model和prop

时间:2017-09-11 21:05:52

标签: vue.js vuejs2 vue-component

我试图使用来自v-model的道具的数据,以下代码可以正常工作,但会发出警告。

<template>
<div>
       <b-form-input v-model="value" @change="postPost()"></b-form-input>
</div>
</template>
<script>
    import axios from 'axios';
    export default {
        props: {
            value: String
        },
        methods: {
            postPost() {
                axios.put('/trajectory/inclination', {
                    body: this.value
                })
                    .then(response => {
                    })
                    .catch(e => {
                        this.errors.push(e)
                    })
            }
        }
    }
</script>

警告说:

&#34;避免直接改变道具,因为只要父组件重新渲染,该值就会被覆盖。而是根据prop的值使用数据或计算属性。支持变异:&#34;价值&#34;

所以我改变了,现在我正在使用数据作为警告说。

<template>
<div>
       <b-form-input v-model="_value" @change="postPost()"></b-form-input>
</div>
</template>
<script>
    import axios from 'axios';

    export default {
        props: {
            value: String
        },
        data() {
            return {
                _value: this.value
            }
        },
        methods: {
            postPost() {
                axios.put('/trajectory/inclination', {
                    body: this._value
                })
                    .then(response => {
                    })
                    .catch(e => {
                        this.errors.push(e)
                    })
            }
        }
    }

所以现在代码没有用,警告说:

&#34;属性或方法&#34; _value&#34;未在实例上定义,但在呈现期间引用。确保在数据选项&#34;

中声明反应数据属性

知道如何修复第一个代码来抑制警告吗? (或者关于如何修复第二个代码的一些想法?)

Obs。:b-form-input它不是我的组件,这是来自Boostrap-Vue的文本输入(Doc for b-form-input

7 个答案:

答案 0 :(得分:9)

Bert解决了你的直接问题,但我认为你也应该知道你的方法有点过时了。由于最终您将新值发送到postPost,因此您不需要修改本地副本。使用发送到event处理程序的change对象从输入中获取当前值。

而不是v-model,只需使用:value,并且在指定change处理程序时不要包含调用括号。

<template>
<div>
       <b-form-input :value="value" @change="postPost"></b-form-input>
</div>
</template>
<script>
    import axios from 'axios';
    export default {
        props: {
            value: String
        },
        methods: {
            postPost(event) {
                axios.put('/trajectory/inclination', {
                    body: event.target.value
                })
                    .then(response => {
                    })
                    .catch(e => {
                        this.errors.push(e)
                    })
            }
        }
    }
</script>

答案 1 :(得分:9)

答案来自https://github.com/vuejs/vue/issues/7434

道具是只读的,但是您试图通过v-model更改其值。在这种情况下,如果您更改输入值,则prop不会被修改,并且该值会在下一次更新时恢复。

改为使用数据属性或计算的设置器:

computed: {
  propModel: {
    get () { return this.prop },
    set (value) { this.$emit('update:prop', value) },
  },
},

https://vuejs.org/v2/guide/computed.html#Computed-Setter

答案 2 :(得分:7)

对于Vue的内部属性,

_前缀属性为reserved

  

以_或$开头的属性不会在Vue上代理   实例,因为它们可能与Vue的内部属性冲突   API方法。

尝试将 _value 更改为不以下划线开头的内容。

答案 3 :(得分:0)

一个通用的解决方法是引入数据变量,并观察道具更新变量。这非常微妙,很容易出错,因此下面是一个使用v-model的Vuetify模态示例(理论上,该技术应与<input>等一起使用)

<template>
  <v-dialog v-model="isVisible" max-width="500px" persistent>
  </v-dialog>
</template>

<script>
export default {
  name: 'Blablabla',
  props: {
    visible: { type: Boolean, required: true }
  },
  data() {
    isVisible: false
  },
  watch: {
    // `visible(value) => this.isVisible = value` could work too
    visible() {
      this.isVisible = this.$props.visible
    }
  }
}
</script>

答案 4 :(得分:0)

对于那些仍然需要解决的问题,Vue官方文档显示了如何在自定义组件https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components

上使用v-model

TL; DR:

您只需要拥有一个专门命名的value属性,并发出一个input事件,当您实例化组件映射时,v-model就可以为您映射。

有关如何在上面的链接上工作的更多信息。

<template>
  <input
    type="text"
    :value="value"
    @input="$emit('input', $event.target.value)"
  />
</template>

<script>
export default {
  name: "Input",
  props: {
    value: String,
  },
};
</script>
<Input v-model="searchText"></Input>

答案 5 :(得分:0)

将输入的v-model指令指向名为value_的数据属性(或任何其他不以Vue保留的前缀_$开头的名称)。将数据属性的默认值设置为null。然后,添加方法getValue(),该方法将根据您的value_道具的值设置属性value。最后,在Vue的getValue()生命周期挂钩中调用created()。像这样:

<template>
  <div>
    <b-form-input v-model="value_" @change="postPost()">
    </b-form-input>
  </div>
</template>

<script>
  import axios from 'axios';
  
  export default {
    data: () => ({
      value_: null
    }),
    props: {
      value: String
    },
    methods: {
      postPost() {
        axios.put('/trajectory/inclination', {
          body: this.value_
        })
        .then(response => {
        })
        .catch(e => {
          this.errors.push(e)
        })
      },
      getValue() {
        this.value_ = this.value;
      }
    },
    created() {
      this.getValue()
    }
  }
</script>

答案 6 :(得分:0)

您可以使用以下数据。

<template>
  <input type="text" v-bind:value="value" v-on:input="dValue= $event.target.value" />
</template>
        
 <script>
 export default {
  props: ["value"],
  data: function () {
    return {
      dValue: this.value,
    };
  },
  methods: {
    alertValue() {
     alert("Current Value" + this.dValue);
    },
  },
};
</script>