{"record":{"id":"e2ff7f5016fb6eca","repo":"Meituan-Dianping/mpvue","slug":"transition-explicit-name-duration-is-nan-th","errorCode":null,"errorMessage":"<transition> explicit ${name} duration is NaN - the duration expression might be incorrect.","messagePattern":"<transition> explicit (.+?) duration is NaN - the duration expression might be incorrect\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/platforms/web/runtime/modules/transition.js","lineNumber":287,"sourceCode":"      })\n    }\n    leave && leave(el, cb)\n    if (!expectsCSS && !userWantsControl) {\n      cb()\n    }\n  }\n}\n\n// only used in dev mode\nfunction checkDuration (val, name, vnode) {\n  if (typeof val !== 'number') {\n    warn(\n      `<transition> explicit ${name} duration is not a valid number - ` +\n      `got ${JSON.stringify(val)}.`,\n      vnode.context\n    )\n  } else if (isNaN(val)) {\n    warn(\n      `<transition> explicit ${name} duration is NaN - ` +\n      'the duration expression might be incorrect.',\n      vnode.context\n    )\n  }\n}\n\nfunction isValidDuration (val) {\n  return typeof val === 'number' && !isNaN(val)\n}\n\n/**\n * Normalize a transition hook's argument length. The hook may be:\n * - a merged hook (invoker) with the original in .fns\n * - a wrapped component method (check ._length)\n * - a plain function (.length)\n */\nfunction getHookArgumentsLength (fn: Function): boolean {","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/Meituan-Dianping/mpvue/blob/6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b/src/platforms/web/runtime/modules/transition.js#L269-L305","documentation":"This is the NaN branch of checkDuration: the duration prop on <transition> is a number type but evaluates to NaN, which usually means the duration expression is computed incorrectly (e.g. Number('abc'), undefined arithmetic). NaN durations make transition timing impossible, so Vue warns in development.","triggerScenarios":"Passing a computed duration to <transition> (or explicit enter/leave hooks) whose value is a number-typed NaN — e.g. :duration=\"parseFloat(str)\" where str is not numeric, or arithmetic like this.delay * 2 when this.delay is undefined.","commonSituations":"Parsing strings from attributes or config without validating; uninitialized reactive data used in the expression; a computed that divides by zero or multiplies undefined; unit strings like '300ms' fed to Number().","solutions":["Fix the expression producing the duration so it yields a real number (validate input before Number()/parseFloat).","Guard against undefined: use :duration=\"Number(str) || 300\" with a sane default.","If parsing '300ms' style strings, strip units first: parseFloat('300ms').","Log the value in dev to find where NaN originates."],"exampleFix":"// before\n<transition :duration=\"parseFloat(this.durationStr)\">...</transition>\n// after\n<transition :duration=\"parseFloat(this.durationStr) || 300\">...</transition>","handlingStrategy":"validation","validationCode":"function toDuration(v, fallback = 300) {\n  const n = typeof v === 'string' ? parseFloat(v) : Number(v)\n  return Number.isFinite(n) ? n : fallback\n}\n// use: :duration=\"toDuration(rawDuration)\"","typeGuard":"function isRealNumber(v) {\n  return typeof v === 'number' && Number.isFinite(v)\n}","tryCatchPattern":null,"preventionTips":["Use Number.isFinite() checks on computed durations before applying them.","Provide default fallbacks with the || operator on parsed values.","Trace NaN sources: log intermediate expressions when duration is computed.","Parse unit strings ('300ms') with parseFloat, not Number."],"tags":["vue","transition","dev-warning","nan"],"backgroundTag":"nan-duration","analyzedSha":"6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b","analyzedAt":"2026-09-02T05:17:40.946Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T11:17:12.671Z"}