From f9caabda236a1d21e4902ba66678d580eea7e439 Mon Sep 17 00:00:00 2001 From: Ubugeeei Date: Fri, 6 Mar 2026 13:09:59 +0900 Subject: [PATCH] feat: ilc --- active-rfcs/0047-ilc.md | 309 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 active-rfcs/0047-ilc.md diff --git a/active-rfcs/0047-ilc.md b/active-rfcs/0047-ilc.md new file mode 100644 index 00000000..c37ee512 --- /dev/null +++ b/active-rfcs/0047-ilc.md @@ -0,0 +1,309 @@ +- Start Date: 2026-03-06 +- Target Major Version: 3.x +- Reference Issues: +- Implementation PR: + +# Summary + +ILC (Inline Local Components) + +Allow defining local components inline within a Single File Component (SFC) using a new top-level `` custom block. This enables authors to co-locate small, single-use helper components alongside the parent component that uses them, without creating separate files. + +# Basic example + +```html + + + + + + + + + +``` + +The `` block defines a local component that is automatically available in the parent's template. Each inline component is a fully isolated Vue component with its own scope, props, emits, slots, and lifecycle. + +
+Compiled Output + +```js +import { ref, defineComponent, h } from 'vue' + +const CountDisplay = defineComponent({ + props: { + count: { type: Number, required: true } + }, + setup(props) { + return () => h('p', null, `Current count: ${props.count}`) + } +}) + +export default defineComponent({ + components: { CountDisplay }, + setup() { + const count = ref(0) + return { count } + } +}) +``` + +
+ +# Motivation + +## Problem + +In real-world Vue applications, it is common to extract small template fragments into separate components for readability and reuse within a single parent. Currently, every component requires its own `.vue` file. This leads to: + +1. **File proliferation**: A feature directory may contain many tiny single-use components (e.g., `UserAvatar.vue`, `UserBadge.vue`, `UserStatusIcon.vue`) that are only used by one parent component. This adds cognitive overhead when navigating the codebase. + +2. **Context switching cost**: When a helper component is tightly coupled to its parent, having them in separate files forces developers to switch between files to understand the full picture. + +3. **Boilerplate friction**: Creating a new `.vue` file for a 5-line template fragment feels disproportionate. Developers often inline complex template logic rather than extract it, harming readability. + +## Prior art + +- **Svelte** provides `{#snippet}` blocks that allow defining reusable template fragments inline. While snippets in Svelte are not full components (no own state/lifecycle), they demonstrate the value of co-location. +- **React** naturally supports this by defining multiple function components in a single file. +- **Vue 2** had `inline-template`, which was removed in Vue 3 (RFC 0016) due to scoping ambiguity. This proposal differs fundamentally: inline local components are fully isolated, with explicit props and their own scope, avoiding the problems that led to the removal of `inline-template`. + +## Expected outcome + +Developers can define small helper components in the same file as their parent, reducing file count and improving co-location of tightly coupled components, while maintaining Vue's clear component boundary semantics. + +# Detailed design + +## Syntax + +A new top-level custom block `` is introduced in SFC: + +```html + + + +``` + +### Rules + +1. **`name` attribute is required.** It determines the component name available in the parent template. It must be a valid PascalCase or kebab-case identifier. + +2. **Each `` block is a self-contained SFC.** It can contain ` + + + + + + + +``` + +## Styles + +Each `` block can have its own ` + +``` + +- `scoped` styles within an inline component are scoped to that component, not the parent. +- Unscoped styles behave the same as in a standalone SFC (global). + +## TypeScript support + +All TypeScript features available in ` + + +``` + +Type-checking and IDE support (Volar/vue-tsc) should treat each `` block as if it were a separate SFC for type inference purposes. + +## Compilation + +The SFC compiler (`@vue/compiler-sfc`) processes each `` block as a nested SFC: + +1. Parse the host SFC and extract `` blocks. +2. Compile each `` block independently, producing a component definition object. +3. Inject the compiled inline components into the parent's `components` option (or equivalent ` +``` + +This works but sacrifices the template syntax, which is a core strength of Vue SFCs. It also lacks scoped styles and hot-module replacement for the inline component. + +## 2. Template-inline snippets (Svelte-style) + +An alternative explored in early drafts of this RFC was defining snippets inside `