跪拜 Guibai
← All articles
Backend · Frontend · Artificial Intelligence

How a v-for Assignment White-Screened a Vue App — and the Two Safe Fixes

By 阿橙的百宝箱 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

The same Vue code that passes local testing white-screens in production with zero console output, because assignment expressions inside v-for compile to the render function's global scope. SSR environments expose it even earlier, since Node defaults to strict mode, so this is a tooling behavior every team needs to plan for.

Summary

A Vue list page white-screened in pre-production after a temporary variable was added inside a v-for block. Local runs with 200 rows passed without a warning. The compiled render function shows the assignment hoisted to the top level, so the variable becomes global in non-strict mode and gets overwritten on each iteration until the call stack overflows. Vue's template compiler preserves raw expression structure, so the mistake passes.

Two safe patterns work: precompute the derived value in a computed property, or call the method directly inside the v-if. Measurements show both are fast: 42ms and 38ms for 1000 renders, with memory around 16MB. Beyond that, side-effect mutations, destructuring, and async calls inside v-for all carry the same risk. To catch these silent failures, flip on ESLint's no-undef, force strict mode in the Vue build, and treat templates as pure display layers.

Takeaways
— An assignment expression inside v-for compiles to the top level of the render function, not the loop body.
— In non-strict mode, the assigned variable becomes global and repeated writes overflow the call stack.
— Local development with ~200 items showed no issue; the crash only appeared in pre-production.
— Precomputing the derived value with a computed property is the recommended fix.
— Calling the method directly inside the v-if is a lighter alternative for simple logic.
— For 1000 renders, the computed property took 42ms and 16.8MB; the method call took 38ms and 16.2MB.
— Side-effect pushes, destructuring, and async calls inside v-for are also risky.
— ESLint's no-undef and forcing strict mode in Vue catch these silent global assignments.
Conclusions

The crash is a scoping artifact: Vue's template compiler lets a careless assignment escape its expected local context, which JavaScript silently allows in sloppy mode.

The local/production split suggests data size or the extra render passes in pre-production flip the call stack threshold; the same bug could appear sooner on any larger list.

This is a reminder that template DSLs are not plain JavaScript; the mental model of 'it's just a for loop' is wrong.

Concepts & terms
v-for scope hoisting
Vue's template compiler moves assignment expressions in v-for to the top level of the generated render function, making the variable shared across iterations and global in non-strict mode, which leads to call stack overflow.
From the discussion
Featured comments
卷土的土

Computed properties are suitable for centralized derived data.

See top comments, translated →
Source: juejin.cn ↗ Google Translate ↗ Backup ↗