Skip to content

Vue

Zen Principles

5 principles across 2 categories, drawn from Vue Style Guide.

Correctness · 4 principles Readability · 1 principle

Rule ID Principle Category Severity Dogma
vue-001 Components should use multi-word names Readability 7 ZEN-UNAMBIGUOUS-NAME
vue-002 Props should declare explicit types Correctness 8 ZEN-EXPLICIT-INTENT
vue-003 v-for directives need a :key binding on the same element Correctness 9 ZEN-EXPLICIT-INTENT, ZEN-VISIBLE-STATE
vue-004 Avoid using v-if and v-for on the same element Correctness 9 ZEN-EXPLICIT-INTENT
vue-005 Props should not be mutated directly Correctness 10 ZEN-VISIBLE-STATE, ZEN-EXPLICIT-INTENT
vue-001 — Components should use multi-word names

Multi-word component names reduce collisions with native HTML elements and improve readability.

Universal Dogmas: ZEN-UNAMBIGUOUS-NAME Common Violations:

  • Components should use multi-word names

Detectable Patterns:

  • re:\bname\s*:\s*[\"\'][A-Z][a-zA-Z0-9]*[\"\']

Recommended Fix

Rename the component to a multi-word name such as UserCard or TodoList.

vue-002 — Props should declare explicit types

Untyped props weaken runtime validation and make component contracts harder to understand.

Universal Dogmas: ZEN-EXPLICIT-INTENT Common Violations:

  • Props should declare explicit types

Detectable Patterns:

  • re:(?:defineProps\(\s*\[[^\]]+\]\s*\)|props\s*:\s*\[[^\]]+\])

Recommended Fix

Declare props with defineProps() or a typed props object.

vue-003 — v-for directives need a :key binding on the same element

Stable keys are required for predictable diffing and component state preservation.

Universal Dogmas: ZEN-EXPLICIT-INTENT, ZEN-VISIBLE-STATE Common Violations:

  • v-for directives need a :key binding on the same element

Detectable Patterns:

  • re:<[^>]+\bv-for\s*=\s*[\"\'][^\"\']+[\"\'](?:(?!:key=)[^>])*>

Recommended Fix

Add a :key binding derived from stable item identity.

vue-004 — Avoid using v-if and v-for on the same element

Combining v-if and v-for on the same node makes rendering intent harder to reason about.

Universal Dogmas: ZEN-EXPLICIT-INTENT Common Violations:

  • Avoid using v-if and v-for on the same element

Detectable Patterns:

  • re:<[^>]+\bv-if\s*=.*\bv-for\s*=|<[^>]+\bv-for\s*=.*\bv-if\s*=

Recommended Fix

Split the conditional wrapper from the looped element or filter the data first.

vue-005 — Props should not be mutated directly

Direct prop mutation breaks one-way data flow and can desynchronize parent and child state.

Universal Dogmas: ZEN-VISIBLE-STATE, ZEN-EXPLICIT-INTENT Common Violations:

  • Props should not be mutated directly

Detectable Patterns:

  • re:\bprops\.\w+\s*=

Recommended Fix

Emit an event or derive local state instead of mutating props.

Detector Catalog

Correctness

Detector What It Catches Rule IDs
VueTypedPropsDetector Concrete detector binding for VueTypedPropsDetector vue-002
VueListKeyDetector Concrete detector binding for VueListKeyDetector vue-003
VueConditionalLoopDetector Concrete detector binding for VueConditionalLoopDetector vue-004
VuePropMutationDetector Concrete detector binding for VuePropMutationDetector vue-005

Readability

Detector What It Catches Rule IDs
VueMultiWordNameDetector Concrete detector binding for VueMultiWordNameDetector vue-001
Principle → Detector Wiring
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 40, "rankSpacing": 60}}}%%
graph TD
vue_001["vue-001<br/>Components should use mul..."]
vue_002["vue-002<br/>Props should declare expl..."]
vue_003["vue-003<br/>v-for directives need a :..."]
vue_004["vue-004<br/>Avoid using v-if and v-fo..."]
vue_005["vue-005<br/>Props should not be mutat..."]
det_VueConditionalLoopDetector["Vue Conditional<br/>Loop"]
vue_004 --> det_VueConditionalLoopDetector
det_VueListKeyDetector["Vue List<br/>Key"]
vue_003 --> det_VueListKeyDetector
det_VueMultiWordNameDetector["Vue Multi<br/>Word Name"]
vue_001 --> det_VueMultiWordNameDetector
det_VuePropMutationDetector["Vue Prop<br/>Mutation"]
vue_005 --> det_VuePropMutationDetector
det_VueTypedPropsDetector["Vue Typed<br/>Props"]
vue_002 --> det_VueTypedPropsDetector
Detector Class Hierarchy
%%{init: {"theme": "base"}}%%
classDiagram
    direction TB
    class ViolationDetector {
        <<abstract>>
        +detect(context, config)
    }
    class det_01["Vue Conditional Loop"]
    ViolationDetector <|-- det_01
    class det_02["Vue List Key"]
    ViolationDetector <|-- det_02
    class det_03["Vue Multi Word Name"]
    ViolationDetector <|-- det_03
    class det_04["Vue Prop Mutation"]
    ViolationDetector <|-- det_04
    class det_05["Vue Typed Props"]
    ViolationDetector <|-- det_05
Analysis Pipeline
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 50, "rankSpacing": 70}}}%%
flowchart TD
Source(["Source Code"]) --> Parse["Parse & Tokenize"]
Parse --> Metrics["Compute Metrics"]
Metrics --> Pipeline{"5 Detectors"}
Pipeline --> Collect["Aggregate Violations"]
Collect --> Result(["AnalysisResult<br/>5 principles"])
Analysis States
%%{init: {"theme": "base"}}%%
stateDiagram-v2
    [*] --> Ready
    Ready --> Parsing : analyze(code)
    Parsing --> Computing : AST ready
    Computing --> Detecting : metrics ready
    Detecting --> Reporting : 5 detectors run
    Reporting --> [*] : AnalysisResult
    Parsing --> Reporting : parse error (best-effort)

Configuration

languages:
  vue:
    enabled: true
    pipeline:

See Also

  • TypeScript — Shared frontend type-safety foundations
  • React — Another component-centric UI model for web applications
  • Configuration — Per-language pipeline overrides