oxc-project/oxc · warning · OxcDiagnostic
You should not use an arrow function to define a watcher.
Error message
You should not use an arrow function to define a watcher.
What it means
Diagnostic from oxlint's vue/no-arrow-functions-in-watch rule (since oxlint 1.39.0). It fires when an Options API `watch` option uses an arrow function as the handler. Arrow functions capture the enclosing `this` (module scope or undefined) instead of the component instance, so `this.foo` inside the watcher breaks at runtime. The help text suggests a regular function or method shorthand.
Source
Thrown at crates/oxc_linter/src/rules/vue/no_arrow_functions_in_watch.rs:17
use oxc_ast::{
AstKind,
ast::{
CallExpression, ExportDefaultDeclarationKind, Expression, ObjectExpression,
ObjectPropertyKind,
},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{
AstNode, context::LintContext, frameworks::FrameworkOptions, rule::Rule, utils::find_property,
};
fn no_arrow_functions_in_watch_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("You should not use an arrow function to define a watcher.")
.with_help("Use a regular function or method shorthand instead of an arrow function.")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoArrowFunctionsInWatch;
declare_oxc_lint!(
/// ### What it does
///
/// This rule disallows using arrow functions when defining a watcher.
///
/// ### Why is this bad?
///
/// Arrow functions bind `this` lexically, which means they don't have access to the Vue component instance.
/// In Vue watchers, you often need access to `this` to interact with component data, methods, or other properties.
/// Using regular functions or method shorthand ensures proper `this` binding.
///View on GitHub (pinned to e1e7af627c)
Solutions
- Use method shorthand: watch: { foo(val, oldVal) { this.doThing(val) } }
- Or reference a named method by string: watch: { foo: 'doThing' }
- Migrate the component to the Composition API watch()/watchEffect() where arrow closures are correct
Example fix
// before
watch: {
query: (val) => { this.search(val) },
}
// after
watch: {
query(val) { this.search(val) },
} Defensive patterns
Strategy: validation
Validate before calling
# rough scan: arrow functions inside watch blocks
grep -rnA6 "watch: *{" --include='*.vue' src | grep "=>" Prevention
- Use method shorthand or method-name strings for all Options API watch handlers
- Consider migrating hot spots to the Composition API watch(), where arrows are safe
When it happens
Trigger: A Vue options object (detected via find_property on the component options) has `watch: { foo: (val, oldVal) => { this.doThing() } }` — any arrow function as the immediate watch handler value.
Common situations: Developers converting methods or computed to watchers using arrow shorthand; class-property-style components where arrows are idiomatic everywhere except watch; copy-paste from Composition API examples into Options API code.
Related errors
- Change to `throw new TypeError(...)`
- TS5081
- The computed property cannot be used in `data()` because it
- Object declaration on `data` property is deprecated.
- Props default value factory functions no longer have access
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/39b406cc007911cd.
Report an issue: GitHub.