Vue 数据模型更改未反映在绑定组件中

Posted

技术标签:

【中文标题】Vue 数据模型更改未反映在绑定组件中【英文标题】:Vue data model change not reflected in bound component 【发布时间】:2018-07-08 21:26:15 【问题描述】:

一个 jQuery 日期选择器被包装在一个 Vue 组件中。该组件发出一条更新消息,用于更新应用模型。

该应用有两个日期选择器输入字段:

startDate adjustmentDate

startDate 被修改时,adjustmentDate 将被更新到下一个月初或十五号。但是,adjustmentDate datepicker 组件没有收到更新通知。

预期行为:

startDatedatepickeronSelect触发Vue组件emit被Vue方法updateStartDate捕获

方法updateStartDate设置模型属性adjustmentDate

希望这会触发adjustmentDate 组件更新,因为adjustmentDate 模型属性绑定到具有手表的日期选择器componentDate 属性。

但是更改模型并没有通知组件的效果。

任何建议如何正确执行此操作并在更改startDate 时显示新计算的adjustmentDate

演示代码:

<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">

    <link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

    <script src="https://unpkg.com/vue"></script>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

</head>


<body>

    <div id="app">

        <div><label>Start date</label></div>
        <div>
            <date-picker 
                v-model="startDate"
                v-bind:component-date="startDate"
                date-format="yy-mm-dd"
                @update-date="updateStartDate"
                v-once
            ></date-picker>
        </div>

        <div><label>Adjustment date</label></div>
        <div>
            <date-picker
                v-model="adjustmentDate"
                v-bind:component-date="adjustmentDate"
                date-format="yy-mm-dd"
                @update-date="updateAdjustmentDate"
                v-once
            ></date-picker>
        </div>

    </div>



    <script>

    Vue.component('date-picker', 

        props: ['dateFormat', 'componentDate'],

        template: '<input/>',


        mounted: function() 

        var self = this;

        var _convertDateStringToDate = function(dateString) 
                var dateParts = dateString.split("-");
                var year = dateParts[0];
                var month = dateParts[1];
                var dayOfMonth = dateParts[2];
                return new Date(year, month, dayOfMonth);
        ;


        $(this.$el).datepicker(

                dateFormat: this.dateFormat,

                onSelect: function(date) 
                        self.$emit('update-date', _convertDateStringToDate(date));
                ,

                onClose: function(date) 
                        self.$emit('update-date', _convertDateStringToDate(date));
                

        );

        $(this.$el).datepicker('setDate', this.componentDate);

        ,


        watch: 
            componentDate: function(newValue, oldValue) 
                $(this.$el).datepicker('setDate', this.componentDate);
            
        ,


        beforeDestroy: function() 
            $(this.$el).datepicker('hide').datepicker('destroy');
        

    );



    var _calculateAdjustmentDate = function(date) 

        var year = date.getFullYear();
        var month = date.getMonth();
        var dayOfMonth = date.getDate();

        if (dayOfMonth > 15) 
            month = month + 1;
            dayOfMonth = 1;
         else if (dayOfMonth > 1 && dayOfMonth < 15) 
            dayOfMonth = 15;
        

        return new Date(year, month, dayOfMonth);

    ;


    var data = function() 

        var now = new Date();

        return 
                startDate: now,
                adjustmentDate: _calculateAdjustmentDate(now),
        ;

    ;


    new Vue(

        el: '#app',

        data: data,

        methods: 

                updateStartDate: function(date) 
                        this.startDate = date;
                        this.adjustmentDate = _calculateAdjustmentDate(date);
                ,

                updateAdjustmentDate: function(date) 
                        this.adjustmentDate = date;
                ,

        

    );


    </script>


</body>


</html>

【问题讨论】:

【参考方案1】:

您需要从调整日期组件中删除 v-once 指令,因为它可以防止在数据更改时重新呈现。

此外,您可以简单地将_calculateAdjustmentDate 放入计算属性中,请参阅Computed Properties。

在此处查看更新后的示例:https://codepen.io/anon/pen/VQYarZ

您的代码还有一些其他问题,我建议您查看Vue guide,尤其是方法事件处理程序和计算属性以及深度响应性。

另外,_calculateAdjustmentDate 并没有真正做到你描述的那样,所以你也可以调查一下。你可以考虑Moment.js

【讨论】:

谢谢。您能否详细说明_calculateAdjustmentDate 的行为与预期不符? 2018-01-01 -&gt; 2018-02-01, 2018-01-02 -&gt; 2018-02-15, 2018-01-16 -&gt; 2018-03-01 好像休息一个月了。 _convertDateStringToDate 不正确。应该是return new Date(year, month - 1, dayOfMonth);。是的,我会看看 moment.js。谢谢。

以上是关于Vue 数据模型更改未反映在绑定组件中的主要内容,如果未能解决你的问题,请参考以下文章

Angular 的 Kendo 中未刷新网格数据

vue绑定父子组件

如何在 Vue 中使用 v-bind 和 v-on 绑定自定义命名模型?

Vue + VueX + Typescript + Vue 路由器。组件未销毁

vue简介

在可可中使用绑定时未反映在视图中的更改