NuxtJS中使用Moment.js时出现Cannot read properties of undefined错误
NuxtJS中Moment.js时区功能错误修复
问题现象
在NuxtJS中编写了一个获取全球各地当前时间的Composable,创建复用组件调用该Composable时,出现错误:Cannot read properties of undefined (reading 'format')。
原Composable代码:
import moment from 'moment-timezone'; export function useOrologio(paese) { const citta = ref(moment()) setInterval(() => { citta.value = moment().tz(paese).format('H:mm:s dddd MMM D')},1000); const utc = ref(moment().tz(paese).format('Z')) const local = ref( moment().tz(paese).format('z')) moment.updateLocale('it', { weekdays : [ "Lunedì", "Martedì", "Marcoledì","giovedì", "Venerdì", "Sabato", "Domenica" ]}) return {citta , utc , local} }
原组件代码:
<template> <div class="flex flex-row p-5 font-[Kenit] font-[600] text-slate-800"> <div class="text-3xl border-slate-900 rounded-2xl p-5 bg-slate-200 w-4/12 flex flex-col"> <p>{{ title }}</p> <p>{{ citta }}</p> <div class="text-base"> <p>Ore rispetto a Greenwich {{ utc }}</p> </div> </div> </div> </template> <script setup> import { useOrologio } from '~/composable/orologio'; const {citta} = useOrologio() const { props } = defineProps([ 'title' ]) </script>
错误原因
- 参数缺失:组件调用
useOrologio()时未传入paese参数,导致moment().tz(undefined)返回undefined,调用format()方法触发报错。 - 初始值逻辑不统一:
citta初始赋值为无时区的moment()实例,后续定时器直接覆盖为格式化字符串,逻辑不一致。 - 无时区有效性校验:未处理传入无效时区的情况,同样会导致
moment.tz()返回undefined。 - 本地化文本拼写错误:意大利语周几的拼写有误(
Marcoledì应为Mercoledì,giovedì首字母需大写)。
修复方案
1. 修正Composable代码
import moment from 'moment-timezone'; export function useOrologio(paese = 'Europe/Rome') { // 校验时区有效性,无效则使用默认值 if (!moment.tz.zone(paese)) { console.warn(`时区 ${paese} 无效,将使用默认时区 Europe/Rome`); paese = 'Europe/Rome'; } // 初始值直接使用带时区的格式化结果 const citta = ref(moment().tz(paese).format('H:mm:s dddd MMM D')); // 定时器更新时间 setInterval(() => { citta.value = moment().tz(paese).format('H:mm:s dddd MMM D'); }, 1000); const utc = ref(moment().tz(paese).format('Z')); const local = ref(moment().tz(paese).format('z')); // 修正意大利语周几拼写 moment.updateLocale('it', { weekdays: [ "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato", "Domenica" ] }); return { citta, utc, local }; }
2. 修正组件代码
<template> <div class="flex flex-row p-5 font-[Kenit] font-[600] text-slate-800"> <div class="text-3xl border-slate-900 rounded-2xl p-5 bg-slate-200 w-4/12 flex flex-col"> <p>{{ title }}</p> <p>{{ citta }}</p> <div class="text-base"> <p>Ore rispetto a Greenwich {{ utc }}</p> </div> </div> </div> </template> <script setup> import { useOrologio } from '~/composable/orologio'; // 传入有效时区参数,示例为欧洲罗马时区 const { citta, utc } = useOrologio('Europe/Rome'); // 简化props定义 defineProps(['title']); </script>
关键修复点说明
- 组件调用时必须传入有效时区参数(如'Europe/Rome'、'Asia/Shanghai'等),或依赖Composable的默认值
- 增加时区有效性校验,避免无效参数导致的错误
- 统一
citta的初始值和定时器更新逻辑,确保始终基于带时区的moment实例格式化 - 修正意大利语本地化文本的拼写错误,保证显示正确
内容的提问来源于stack exchange,提问作者Federico
相关产品推荐
相关产品推荐

