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

时间:2017-03-10 09:45:26

标签: javascript vue.js vuejs2 vue-component

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

  

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

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

app.js

ng-init="myoptions=mainList[0]"

ProjectCountdown.vue

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
    });
},
});

Countdown.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>

3 个答案:

答案 0 :(得分:6)

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

<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

答案 1 :(得分:0)

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

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

声明:

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

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

使用数字存储日期不是最好的主意(它可以工作,但有更好的方法)。

答案 2 :(得分:-1)

VueJs 2倒计时组件 - &gt; ** 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 - 替代方案 - 如果您想在抵达日期后停止反击

    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