v-bind v-model或v-bind.sync?

时间:2019-01-04 19:29:21

标签: vue.js

我不知道v-bindv-modelv-bind.sync有什么区别?

也许为时已晚,但在阅读文档后,我无法分辨v-bind.syncv-model之间的区别。

Sync modifier

Passing Data to Child Components with Props

v-model

示例

我使用“ vue-property-decorator”用Typescript编写了以下组件。我不知道如何不必自己编写事件处理程序就可以设法更新传递到组件中的date对象。如果您问我,它应该与v-modelv-bind.sync绑定(以及标记和装饰器中的相应更改)一起使用。

HTML

<Datepicker v-model="date"/>

打字稿

import { Component, Prop, Vue, Model } from "vue-property-decorator";

@Component({})
export default class Datepicker extends Vue {
    @Prop()
    private label!: string;
    @Model()
    private date!: Date;
    private internalDate = new Date().toISOString().substr(0, 10);
    private menu = false;

    private onDateChanged() {
        const isoDate = this.date.toISOString();
        const newDate =
            this.internalDate + this.date.toISOString().substring(10);
        this.date = new Date(newDate);
    }
}

每次更改this.date对象时,都会收到警告:

  

避免直接更改道具,因为该值将被覆盖   每当父组件重新渲染时。而是使用数据或   根据属性值计算属性。道具被突变:   “日期”

1 个答案:

答案 0 :(得分:1)

在Vue.js中,您不应更改组件传递给您的输入prop。例如,根据您的情况,考虑使用label属性。在您的DatePicker中,您不应有任何类似this.label = 'Hello! Change Prop!';的语句。

  

TLDR:请勿在组件内变异道具。让父母对其进行变异。

回到您的组件,您应该拥有一个像这样的组件:

import { Component, Prop, Vue, Watch } from 'vue-property-decorator';

@Component({})
export default class Datepicker extends Vue {

    @Prop()
    private label!: string;

    @Prop()
    private value!: Date;

    private internalDate = new Date().toISOString().substr(0, 10);

    private previouslyEmittedDate: Date;

    private menu = false;

    @Watch('value')
    public onDatePropChange() {

        // Break infinite one-way recursion
        if (this.value !== this.previouslyEmittedDate) {
            const newDate = new Date(this.internalDate + this.value.toISOString().substring(10));

            this.previouslyEmittedDate = newDate;

            // input events created a sugar coated v-model binding
            this.$emit('input', newDate);
        }
    }
}

作为旁注::我在这里注意到某种代码味道。每次更改日期时,您都会添加一些内部日期。它将导致无限的单向绑定递归。 v-model用于由用户(而非以编程方式)更改的inputv-model只是以下内容的糖衣语法:

<Datepicker :value="date" @input="this.date = $event"/>

最后,避免使用.sync修饰符。它有不同的用途,应谨慎使用。