为什么vue.js不使用moment.js使用datepicker更新dom [英] Why does vue.js not update the dom with datepicker using moment.js

查看:142
本文介绍了为什么vue.js不使用moment.js使用datepicker更新dom的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在vue.js中编写一个(非常)简单的datepicker控件,使用moment.js进行格式化并改变日期。



我遇到的问题即使单击任一按钮时组件中的日期实例被修改,显示也不会更新。



我尝试将其更改为简单的整数一个日期实例,并按预期工作(DOM正确更新)



这是我的源代码:



App.js

  Vue.component(datePicker,{
props: [value],
数据:function(){
return {selectedDate:moment(this.value)};
},
模板:< div>< ;按钮v-on:click ='减量'>& lt;< / button> {{formattedSelectedDate}}< button v-on:click ='increment'>& gt;< / button> < / div>,
方法:{
increment:function(){
this.selectedDate.add( 1,days);
this。$ emit('input',this.selectedDate);
},
减少:function(){
this.selectedDate.subtract(1,days);
this。$ emit('input',this.selectedDate);
}
},
计算:{
formattedSelectedDate:function(){
return this.selectedDate.format(YYYY-MM-DD);
}
}
});

var PointTracker = new Vue({
el:#pointTracker,
data:{
selectedDate:moment(),
todoItems:{ }
}
});

Index.html

 < HTML> 
< head>
< meta charset =utf-8>
< title> Point Tracker< / title>
< link rel =stylesheethref =style.css>
< / head>
< body>

< div id =PointTracker>
< date-picker v-model =selectedDate>
< / div>

< script src =node_modules / moment / moment.js>< / script>
< script src =node_modules / vue / dist / vue.js>< / script>
< script src =node_modules / vue-resource / dist / vue-resource.js>< / script>
< script src =app.js>< / script>
< / body>
< / html>


解决方案

您必须更改<$ c $的参考c> selectedDate ,因为它是从时刻函数返回的,它们总是具有相同的引用,因此不会触发这些vue观察者。



您必须进行以下更改才能更改参考:

 方法: {
increment:function(){
this.selectedDate = moment(this.selectedDate).add(1,days)
},
减少:function(){
this.selectedDate = moment(this.selectedDate).subtract(1,days)
}
},

工作小提琴: http://jsfiddle.net/ mimani / pLcfyrvy / 1 /






以下是加/减来自时刻库:

 功能addSubtract(持续时间,输入,值,方向){
var other = createDuration(input,value);

duration._milliseconds + = direction * other._milliseconds;
duration._days + = direction * other._days;
duration._months + = direction * other._months;

return duration._bubble();
}

//仅支持2.0风格的添加(1,'s')或添加(持续时间)
导出功能添加(输入,值){
return addSubtract(this,input,value,1);
}

//仅支持2.0式减法(1,'s')或减去(持续时间)
导出函数减法(输入,值){
return addSubtract(this,input,value,-1);
}

它返回相同的对象,因此日期对象的引用相同。 / p>




为什么会发生



这是因为moment.js是不是不可变 ,这意味着当你在一个时刻对象上调用加/减函数时,它会在更改属性后返回相同的对象



有一些警告 -Caveats vue的rel =noreferrer>反应性和 Object.observe 现在已经过时,它无法跟踪javasc ript对象已在内部更改,除非您克隆对象并创建一个在您的情况下需要的新对象。



还有其他workarounds 也包括使用冻结时刻库。


I am writing a (very) simple datepicker control in vue.js, using moment.js for formatting and mutating the date.

The problem I'm having is that even though the date instance in the component is modified when I click either button, the display does not update.

I've tried changing this to a simple integer instead of a date instance, and that works as expected (the DOM is updated properly)

Here is the source code that I have for this:

App.js

Vue.component("datePicker", {
    props: ["value"],
    data: function() {
        return { selectedDate: moment(this.value) };
    },
    template: "<div><button v-on:click='decrement'>&lt;</button>{{formattedSelectedDate}}<button v-on:click='increment'>&gt;</button></div>",
    methods: {
        increment: function () {
            this.selectedDate.add(1, "days");
            this.$emit('input', this.selectedDate);
        },
        decrement: function () {
            this.selectedDate.subtract(1, "days");
            this.$emit('input', this.selectedDate);
        }
    },
    computed: {
        formattedSelectedDate: function() {
            return this.selectedDate.format("YYYY-MM-DD");
        }
    }
});

var PointTracker = new Vue({
    el: "#PointTracker",
    data: {
        selectedDate: moment(),
        todoItems: {}
    }
});

Index.html

<html>
    <head>
        <meta charset="utf-8">
        <title>Point Tracker</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>

        <div id="PointTracker">
            <date-picker v-model="selectedDate">
        </div>

        <script src="node_modules/moment/moment.js"></script>
        <script src="node_modules/vue/dist/vue.js"></script>
        <script src="node_modules/vue-resource/dist/vue-resource.js"></script>
        <script src="app.js"></script>
    </body>
</html>

解决方案

You have to change the reference of selectedDate, as it is returned from moment functions, they are always of same reference, so vue watchers are not triggered for these.

You have to make following changes to change the reference:

methods: {
    increment: function () {
        this.selectedDate = moment(this.selectedDate).add(1, "days")
    },
    decrement: function () {
        this.selectedDate = moment(this.selectedDate).subtract(1, "days")
    }
},

Working fiddle: http://jsfiddle.net/mimani/pLcfyrvy/1/


Following is implementation of add/subtract from moment library:

function addSubtract (duration, input, value, direction) {
    var other = createDuration(input, value);

    duration._milliseconds += direction * other._milliseconds;
    duration._days         += direction * other._days;
    duration._months       += direction * other._months;

    return duration._bubble();
}

// supports only 2.0-style add(1, 's') or add(duration)
export function add (input, value) {
    return addSubtract(this, input, value, 1);
}

// supports only 2.0-style subtract(1, 's') or subtract(duration)
export function subtract (input, value) {
    return addSubtract(this, input, value, -1);
}

It returns the same object so the reference is same for the date object.


Why It happened

It happens because moment.js is a isn't immutable, what it means is when you call add/subtract function on a moment object, it returns the same object, with after changing the properties.

There are some caveats on reactivity of vue and as Object.observe is obsolete now, it can not track if an javascript object has changed internally, unless you clone the object and create a new object which is needed in your case.

There are other workarounds also for this including using frozen-moment library.

这篇关于为什么vue.js不使用moment.js使用datepicker更新dom的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆