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

use*_*142 7 vue.js vue-component vuejs2

我正在尝试使用来自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>
Run Code Online (Sandbox Code Playgroud)

警告说:

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

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

<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)
                    })
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

所以现在代码不起作用,警告说:

"属性或方法"_value"未在实例上定义,但在渲染期间引用.确保在数据选项中声明反应数据属性"

知道如何修复第一个代码来抑制警告吗?(或者如何修复第二个代码?)

Obs.:b-form-input它不是我的组件,这是来自Boostrap-Vue的文本输入(用于b-form-input的文档)

Sar*_*oev 12

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

道具是只读的,但您尝试使用v-model更改其值.在这种情况下,如果更改输入值,则不会修改prop,并在下次更新时恢复该值.

改为使用数据属性或计算的setter:

computed: {
  propModel: {
    get () { return this.prop },
    set (value) { this.$emit('update:prop', value) },
  },
},
Run Code Online (Sandbox Code Playgroud)

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


Roy*_*y J 10

伯特解决了你的直接问题,但我想你也应该知道你的方法有点过时了.由于最终您要发送新值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>
Run Code Online (Sandbox Code Playgroud)


小智 10

一种通用的解决方法是引入一个数据变量并观察更新变量的属性。这是非常微妙的,很容易出错,所以这里有一个使用 Vuetify 模式的示例v-model(理论上,相同的技术应该与<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>
Run Code Online (Sandbox Code Playgroud)


fre*_*ett 9

Vue 官方文档展示了如何v-model在自定义组件上使用:https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components

长话短说:

您只需要有一个专门命名的valueprop,并在实例化组件时发出一个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>
Run Code Online (Sandbox Code Playgroud)
<Input v-model="searchText"></Input>
Run Code Online (Sandbox Code Playgroud)


Ste*_*ado 7

_前缀属性是为Vue的内部属性保留的.

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

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