MomentJS + VueJS:从现在开始相对时间到过去的某一点

时间:2017-06-01 10:07:44

标签: vue.js momentjs

我使用MomentJS。

在我的VueJS-Code中我想知道从现在到过去的相对时间。在我的模板中,我合并了这一小段JavaScript的结果:

<template>
  <div>{{ moment(message.createdAt, 'YYYYMMDD').fromNow() }}</div>
</template>

对象按如下方式接收日期:

message: { createdAt: Date.now() }

结果总是:a few seconds ago ...

我怎样才能得到正确的结果(并非总是“几秒钟前”):

修改

这是我的完整模板:

<template v-for="message in messages">
  <div class="message">
    <div class="text">{{ message.text }}</div>
    <div class="date">{{ moment(message.createdAt).format('D.M.YYYY') }}</div>
    <div class="date">{{ moment(message.createdAt).fromNow() }}</div>
  </div>
</template>

2 个答案:

答案 0 :(得分:3)

嗯,您无法直接在模板中使用片刻,因为它不是白盒子(在模板中无法访问)。

  

模板表达式是沙箱化的,只能访问全局变量白名单,例如Math和Date。您不应尝试在模板表达式中访问用户定义的全局变量。

来源:https://vuejs.org/v2/guide/syntax.html#Using-JavaScript-Expressions

我建议您使用一些过滤器(您也可以使用非常类似的方法)。

这是一个有效的例子。

&#13;
&#13;
new Vue({
	el: "#app",
	data() {
		return {
			messages: [
				{
					text: 'Message1',
					createdAt: new Date() // Now
				},
				{
					text: 'Message2',
					createdAt: new Date(2016, 3, 1) // 1 April 2017
				}
			],
			interval: null
		};
	},
	filters: {
		format(date) {
			return moment(date).format('D.M.YYYY')
		},
		fromNow(date) {
			return moment(date).fromNow();
		}
	},
	created() {
		this.interval = setInterval(() => this.$forceUpdate(), 1000);
        // Trigger an update at least each second
        // You should probably raise this duration as refreshing so often
        // may be not useful 
 		},
	beforeDestroy() {
		clearInterval(this.interval);
	}
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
<div id="app">

	<template v-for="message in messages">
	  <div class="message">
		<div class="text">{{ message.text }}</div>
		<div class="date">{{ message.createdAt | format }}</div>
		<div class="date">{{ message.createdAt | fromNow }}</div>
	  </div>
	</template>
	
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

Cobaltway的回复是有效的,但我建议将整个逻辑提取到自己的一个小组件中,这样就不会强迫Vue每次都重新渲染整个组件。

我刚刚创建了这个例子,请看这个小提琴:

https://jsfiddle.net/Linusborg/meovg84x/

Vue.component('dynamic-from-now',{
    name:'DynamicFromNow',
  props: {
    tag: {type: String, default: 'span'},
    value: {type: String, default: ()=> moment().toISOString() },
    interval: {type: Number, default: 1000}
  },
  data() {
    return { fromNow: moment(this.value).fromNow() }
  },
  mounted () {
    this.intervalId = setInterval(this.updateFromNow, this.interval)
    this.$watch('value', this.updateFromNow)
  },
  beforeDestroy() {
    clearInterval(this.intervalId)
  },
  methods: {
    updateFromNow() {
        var newFromNow = moment(this.value).fromNow(this.dropFixes)
      if (newFromNow !== this.fromNow) {
        this.fromNow = newFromNow
      }
    }
  },
  render(h) {
    return h(this.tag, this.fromNow)
  }
})

用法:

<dynamic-from-now :value="yourTimeStamp" :interval="2000" :tag="span" class="red" />