Skip to content

Revamp the essential style guide and mark others as legacy#3370

Open
haoqunjiang wants to merge 9 commits intovuejs:mainfrom
haoqunjiang:revamp-essential-style-guide
Open

Revamp the essential style guide and mark others as legacy#3370
haoqunjiang wants to merge 9 commits intovuejs:mainfrom
haoqunjiang:revamp-essential-style-guide

Conversation

@haoqunjiang
Copy link
Copy Markdown
Member

This PR updates the Style Guide in a deliberately narrow way instead of attempting a full rewrite.

The diff:

  • rewrites Priority A: Essential around a small set of human-facing Vue 3 rules
  • updates the style guide overview to reflect that narrower scope
  • marks Priority B, C, and D as legacy reference content
  • removes the old keyed v-for and v-if with v-for entries from the essential section and leaves those checks to tooling
  • drops multi-word-component-names from the essential section
  • does not rewrite Priority B, C, or D beyond legacy notices
  • does not bring the style guide back to the top nav yet, since this PR only revises the essential section

The essential rules in this draft are:

  • Use detailed prop definitions
  • Declare emitted events (new)
  • Keep parent-child data flow explicit (new)
  • Use component-scoped styling
  • Use computed for derived state; use watchers/effects/hooks for side effects (new)

Taken together, these rules define the core boundaries of a Vue component: its contract, its communication model, its styling boundary, and its reactive semantics.

Why This Direction

I think the guide should stay small, stable, and principle-driven, and leave mechanical concerns to tooling.

In practice, that means:

  • keeping the guide small enough that a volunteer team can realistically review and maintain it
  • preferring durable rules over a large set of detailed conventions that may age quickly
  • leaving automatable rules to tools, which are easier to update than the guide itself

This is also partly motivated by vuejs/eslint-plugin-vue#3060: the outdated guide is starting to create friction for tooling and keeps outdated rules in circulation.

It is also informed by the last large style guide revamp attempt in vuejs/v2.vuejs.org#2839, where the scope was broad enough that review became difficult to finish.

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 19, 2026

Deploy Preview for vuejs ready!

Name Link
🔨 Latest commit d3b90dc
🔍 Latest deploy log https://app.netlify.com/projects/vuejs/deploys/69d756bbd570460008280017
😎 Deploy Preview https://deploy-preview-3370--vuejs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@ubugeeei
Copy link
Copy Markdown
Member

I'll definitely check it!

And every team members should check also!
/cc @vuejs/active-team-members @vuejs/core-committers

@ubugeeei
Copy link
Copy Markdown
Member

And since these are important changes, they should ultimately be decided by @yyx990803

@Jinjiang
Copy link
Copy Markdown
Member

Shall we add a style guide link to our menu by this PR?

@haoqunjiang
Copy link
Copy Markdown
Member Author

I don't think so because the other parts of the style guide are still outdated.

@Jinjiang
Copy link
Copy Markdown
Member

What about still leaving the legacy style guide unreachable and creating another page for the new one? So we can make it available right now. Then we can put a link on the legacy docs to let users from there also able to know what happened and be properly navigated.

@haoqunjiang
Copy link
Copy Markdown
Member Author

I think that depends on what we plan to do next: do we stop at this essential guide, or are we going to revise the remaining style guides within a reasonable timeframe?

@serkodev
Copy link
Copy Markdown
Member

Do you think should we seperate the Essential into JavsScript and TypeScript part (in session / different page) ?

like "Declare emitted events"

// BAD
function submit() {
  $emit('submit', { email: form.email })
}

it will never happen $emit in TypeScript

@bencodezen
Copy link
Copy Markdown
Member

bencodezen commented Mar 31, 2026

Thanks for the PR on this @haoqunjiang!

My concern around narrowing the style guide to specific contractual Vue features is that it loses some of the best practices and guidances to avoid anti-patterns. Perhaps I'm mistaken, but I've always been under the impression the style guides are more about a collection of best practices that the team has found to make their apps better as a whole.

If the team feels "avoid single word components" is too high, I'd propose we move it to "strongly recommended" instead of just deleting them since these are still proven conventions for avoiding conflicts in the codebase.

@bencodezen bencodezen self-requested a review March 31, 2026 14:54
- In development, Vue will warn you if a component is ever provided incorrectly formatted props, helping you catch potential sources of error.
:::
::: details Why this matters
Detailed [prop definitions](/guide/components/props#prop-validation) make a component's API easier to understand, easier to use correctly, and easier to change safely.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did the second reason get removed from the explanation?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the rephrased explanation could preserve a bit more nuance without getting into the technical details.
Detailed prop definitions not only let the Vue runtime warn about potential issues, but also help the TypeScript language server, linters, and similar tooling.


</div>

## Avoid `v-if` with `v-for` {#avoid-v-if-with-v-for}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this rule being removed? Isn't it still relevant from a rendering / performance perspective?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but the v-for and v-if rules are so mechanical that a linter can catch them easily. And the ESLint plugin documentation already has dedicated pages for them. Do we really need to repeat the guidance here?

On second thought, I can still see a case for keeping the "keyed v-for" rule here because of the more detailed explanation of object constancy. But I don't really think the avoid-v-if-with-v-for rule belong here. It doesn't seem any more important than the other essential ESLint rules.

- The [`scoped` attribute](/api/sfc-css-features#scoped-css) is not the only option. CSS modules, native [CSS `@scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/@scope), and disciplined class-based conventions such as [BEM](http://getbem.com/) can all work.
- App-level and layout-level styles may be global when they are intentionally shared.

## Use computed for derived state {#use-computed-for-derived-state}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great new essential rule!

This is the official style guide for Vue-specific code. It is meant to help teams make sound architectural, semantic, and maintainability decisions in modern Vue applications. However, no style guide is ideal for every team or project, so mindful deviations are still encouraged when they are deliberate and well understood.

For the most part, we also avoid suggestions about JavaScript or HTML in general. We don't mind whether you use semicolons or trailing commas. We don't mind whether your HTML uses single-quotes or double-quotes for attribute values. Some exceptions will exist however, where we've found that a particular pattern is helpful in the context of Vue.
This guide focuses on a small set of human-facing Vue rules. It is not intended to mirror every rule that lint tooling may enforce. Tools such as [eslint-plugin-vue](https://eslint.vuejs.org/), formatters, and other static analysis can still cover broader mechanical correctness and consistency checks.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it mean for it to be "human-facing Vue rules"?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rules that rely more on human judgment and review, as opposed to ones that can be easily enforced by tools.
In principle, they could be AI-facing too, but I don’t think the current agent harness can reliably follow this many rules yet, and I haven’t found a better term for that distinction.

@haoqunjiang
Copy link
Copy Markdown
Member Author

If the team feels "avoid single word components" is too high, I'd propose we move it to "strongly recommended" instead of just deleting them since these are still proven conventions for avoiding conflicts in the codebase.

Moved. That said, I haven't reviewed the rest of the "strong recommended" rules, so it's still marked as "legacy" overall.

@haoqunjiang
Copy link
Copy Markdown
Member Author

Do you think should we seperate the Essential into JavsScript and TypeScript part (in session / different page) ?

like "Declare emitted events"

// BAD
function submit() {
  $emit('submit', { email: form.email })
}

it will never happen $emit in TypeScript

Yeah I think we'll eventually need that kind of toggle across the documentation, but I feel it would take a substantive amount of work, so it’s out of scope for this style guide revamp PR.

For this particular issue, I changed the code example to show $emit usage in templates, which could still happen even with TypeScript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants