oxc-project/oxc · error · OxcDiagnostic
`data` property in component must be a function.
Error message
`data` property in component must be a function.
What it means
The vue/no-shared-component-data rule enforces that a component's `data` option is a function. When `data` is a plain object, every instance of the component shares the same object, so state mutations in one instance leak into all others. The rule checks objects recognized as component definitions while excluding root instances (is_vue_component_options_object_excluding_instance), because `new Vue({ data: {...} })` legitimately allows an object at the app root.
Source
Thrown at crates/oxc_linter/src/rules/vue/no_shared_component_data.rs:12
use oxc_ast::{AstKind, ast::Expression};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{
AstNode, context::LintContext, rule::Rule,
utils::is_vue_component_options_object_excluding_instance,
};
fn no_shared_component_data_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`data` property in component must be a function.").with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoSharedComponentData;
declare_oxc_lint!(
/// ### What it does
///
/// Enforce that the `data` property of a Vue component definition is a
/// function.
///
/// ### Why is this bad?
///
/// When `data` is declared as an object literal, the same object is shared
/// across every instance of the component, which causes cross-instance
/// state pollution. Returning a fresh object from a function avoids that.
///
/// This rule targets component definitions reached throughView on GitHub (pinned to e1e7af627c)
Solutions
- Convert `data` to a function returning the object: `data() { return { count: 0 }; }`.
- Audit sibling components for the same object-data pattern.
- Keep object data only at the true root instance if you rely on it, and note the rule intentionally skips that case.
- Re-run oxlint to confirm.
Example fix
// before
export default {
data: { count: 0 } // shared across all instances
}
// after
export default {
data() {
return { count: 0 };
}
} Defensive patterns
Strategy: validation
Validate before calling
// sanity check component options before registration
function registerComponent(opts) {
if (opts.data && typeof opts.data !== 'function') {
throw new TypeError('component `data` must be a function');
}
// ...register
} Prevention
- Always author component `data` as a function returning a fresh object.
- Remember only the root instance (`new Vue({ data })`) may use an object.
- When a list of components mysteriously share state, check for object-data first.
When it happens
Trigger: An Options-API component with `data: { ... }` (object literal) instead of `data() { return {...} }`, or `defineComponent({ data: {...} })` — anywhere the object is recognized as a component definition rather than a root instance.
Common situations: Quick prototypes written with object data then reused in lists; copy-pasting the root-instance pattern into child components; code migrated from Vue 1 where object data was allowed; bugs that look like 'all rows in my table update together'.
Related errors
- The computed property cannot be used in `data()` because it
- Object declaration on `data` property is deprecated.
- TS5081
- You should not use an arrow function to define a watcher.
- Prop "{prop_name}" should be optional.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/d794612183ee05a4.
Report an issue: GitHub.