首页 文章

无效道具:道具类型检查失败

提问于
浏览
2

我用Vue.js创建了一个倒计时,但是我无法显示我得到的值 . 我有两个组件,我已经阅读了Vue的单个文件组件指南,但我似乎并不明白我做错了什么 . 在控制台中,我收到以下错误:

[Vue警告]:无效道具:道具“日期”的类型检查失败 . 预期的数字,得到字符串 .

虽然在我的代码中它被定义为数字 .

app.js

import './bootstrap.js';

import Echo from 'laravel-echo';
import Vue from 'vue';

import CurrentTime from './components/CurrentTime';
import Bitbucket from './components/Bitbucket';
import InternetConnection from './components/InternetConnection';
import LastFm from './components/LastFm';
import PackagistStatistics from './components/PackagistStatistics';
import RainForecast from './components/RainForecast';
import Placeholder from './components/Placeholder';
import Youtube from './components/Youtube';
import ProjectCountdown from './components/ProjectCountdown';
import Countdown from './components/Countdown';


Vue.component('countdown', Countdown);

new Vue({

el: '#dashboard',

components: {
    CurrentTime,
    InternetConnection,
    Bitbucket,
    LastFm,
    PackagistStatistics,
    RainForecast,
    Placeholder,
    Youtube,
    ProjectCountdown,
    Countdown
},

created() {
    this.echo = new Echo({
        broadcaster: 'pusher',
        key: window.dashboard.pusherKey,
        cluster: 'eu',
        encrypted: true
    });
},
});

ProjectCountdown.vue

<template>
<div id="dashboard">
    <Countdown date="March 20, 2017 12:00"></Countdown>
    {{days}}
</div>
</template>

<script>
import Grid from './Grid';
import Vue from 'vue';
import Countdown from './Countdown';

export default {

components: {
    Grid,
    Countdown,
},

props: {
    grid: {
        type: String,
    },
},

data() {
    return {

    }
}
}



// Vue.filter('two_digits', function (value) {
//     if(value.toString().length <= 1)
//     {
//         return "0" + value.toString()
//     }
//     return value.toString();
// });
</script>

Countdown.vue

<template>
<div>
    {{ seconds }}
</div>
</template>


<script>
import Vue from 'vue';
export default {

props: {
    date: {
        type: Number,
        coerce: str => Math.trunc(Date.parse(str) / 1000)
    },
},
data() {
    return {
        now: Math.trunc((new Date()).getTime() / 1000)
    }
},
ready() {
    window.setInterval(() => {
        this.now = Math.trunc((new Date()).getTime() / 1000);
    },1000);


},
computed: {
    seconds() {
        return (this.date - this.now) % 60;
    },
    minutes() {
        return Math.trunc((this.date - this.now) / 60) % 60;
    },
    hours() {
        return Math.trunc((this.date - this.now) / 60 / 60) % 24;
    },
    days() {
        return Math.trunc((this.date - this.now) / 60 / 60 / 24);
    },
},
}
</script>

3 回答

  • 4

    正如错误所说,它来自这条线:

    <Countdown date="March 20, 2017 12:00"></Countdown>
    

    您正在传递 date 作为字符串,而在道具中验证它是一个数字 . 这是您的验证:

    props: {
        date: {
            type: Number,
            coerce: str => Math.trunc(Date.parse(str) / 1000)
        },
    },
    

    我认为在新项目中你使用的是vuejs2,其中强制选项是removed . 如上所述here您可以使用如下的计算属性:

    props: {
        date: {
            type: Number
        },
    },
    computed: {
       modifiedDate: function(){
           return Math.trunc(Date.parse(this.date) / 1000)
       }
    }
    

    您现在可以使用 modifiedDate 而不是 date .

  • 0

    Vue没有错 . 问题出在您的代码中 .

    您将日期声明为数字(顺便说一句 . 为什么?)然后您传递字符串...

    宣言:

    props: {
        date: {
            type: Number,
            coerce: str => Math.trunc(Date.parse(str) / 1000)
        },
    },
    

    用法: <Countdown date="March 20, 2017 12:00"></Countdown>

    使用数字来存储日期并不是最好的想法(它可以工作,但有更好的方法) .

  • -1

    VueJs 2 Countdown Component - > ** JSBin ** .

    这是网址:http://jsbin.com/tapuyicefo/edit?html,css,js,output

    index.html

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
      <title>VueJS 2 Countdown</title>
    </head>
    <body>
      <div id="app">
       <Countdown date="October 12, 2017 12:00" inline-template>
         <div class="row">
                <div class="col-xs-6 col-sm-3">
                    <p class="digit">{{ days | two_digits }}</p>
                    <p class="text">Days</p>
                </div>
                <div class="col-xs-6 col-sm-3">
                    <p class="digit">{{ hours | two_digits }}</p>
                    <p class="text">Hours</p>
                </div>
                <div class="col-xs-6 col-sm-3">
                    <p class="digit">{{ minutes | two_digits }}</p>
                    <p class="text">Minutes</p>
                </div>
                <div class="col-xs-6 col-sm-3">
                    <p class="digit">{{ seconds | two_digits }}</p>
                    <p class="text">Seconds</p>
                </div>
            </div>
       </Countdown>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.1/vue.min.js"></script>
    </body>
    </html>
    

    css

    @import url(https://fonts.googleapis.com/css?family=Roboto+Condensed:400|Roboto:100);
    .text {
        color: #999;
        font-size: 25px;
        font-family: 'Roboto Condensed', serif;
        font-weight: 40;
        margin-top:10px;
        margin-bottom: 10px;
        text-align: center;
    }
    
    .digit {
        color: #444;
        font-size: 130px;
        font-weight: 100;
        font-family: 'Roboto', serif;
        margin: 10px;
        text-align: center;
    }
    

    Javascript

    Vue.component('Countdown', {
        props : ['date'],
        data: function() {
            return {
                now: Math.trunc((new Date()).getTime() / 1000),
                modifiedDate: Math.trunc(Date.parse(this.date) / 1000)
            }
        },
        mounted: function() {
          var ctx = this;
            setInterval(function(){
                ctx.now = Math.trunc((new Date()).getTime() / 1000);
            },1000);
        },
        computed: {
            seconds: function() {
                return (this.modifiedDate  - this.now) % 60;
            },
            minutes:function() {
                return Math.trunc((this.modifiedDate  - this.now) / 60) % 60;
            },
            hours:function() {
                return Math.trunc((this.modifiedDate  - this.now) / 60 / 60) % 24;
            },
            days:function() {
                return Math.trunc((this.modifiedDate  - this.now) / 60 / 60 / 24);
            }
        }
    });
    
    new Vue({
        el: '#app',
    });
    
    Vue.filter('two_digits', function (value) {
        return (value.toString().length <= 1) ? "0" + value : value;
    });
    

    Javascript - alternative - if you want to stop counter after he reaches contdown date

    Vue.component('Countdown', {
            props : ['date'],
            data: function() {
                return {
                    now: Math.trunc((new Date()).getTime() / 1000),
                    modifiedDate: Math.trunc(Date.parse(this.date) / 1000)
                }
            },
            mounted: function() {
              var ctx = this;
                var x = setInterval(function(){
                    ctx.now = Math.trunc((new Date()).getTime() / 1000);
                },1000);
            },
            computed: {
                seconds: function() {
                    if ((this.modifiedDate - this.now) <= 0) {
                        clearInterval(this.x);
                        return 0;
                    }
                    return (this.modifiedDate  - this.now) % 60;
                },
                minutes:function() {
                    if ((this.modifiedDate - this.now) <= 0) {
                        clearInterval(this.x);
                        return 0;
                    }
                    return Math.trunc((this.modifiedDate  - this.now) / 60) % 60;
                },
                hours:function() {
                    if ((this.modifiedDate - this.now) <= 0) {
                        clearInterval(this.x);
                        return 0;
                    }
                    return Math.trunc((this.modifiedDate  - this.now) / 60 / 60) % 24;
                },
                days:function() {
                    if ((this.modifiedDate - this.now) <= 0) {
                        clearInterval(this.x);
                        return 0;
                    }
                    return Math.trunc((this.modifiedDate  - this.now) / 60 / 60 / 24);
                }
            }
        });
    
        new Vue({
            el: '#app',
        });
    
        Vue.filter('two_digits', function (value) {
            return (value.toString().length <= 1) ? "0" + value : value;
        });
    

    Original script VueJS v1 - Github

相关问题