diff --git a/lib/rules/no-invalid-model-keys.js b/lib/rules/no-invalid-model-keys.js
index 7985fd25d..f86587ff1 100644
--- a/lib/rules/no-invalid-model-keys.js
+++ b/lib/rules/no-invalid-model-keys.js
@@ -6,10 +6,6 @@
const utils = require('../utils')
-/**
- * @typedef {import('../utils').GroupName} GroupName
- */
-
// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
diff --git a/lib/rules/no-unused-properties.js b/lib/rules/no-unused-properties.js
index 9a38c2a75..0e5b0b3e7 100644
--- a/lib/rules/no-unused-properties.js
+++ b/lib/rules/no-unused-properties.js
@@ -53,6 +53,7 @@ const GROUP_COMPUTED_PROPERTY = 'computed'
const GROUP_METHODS = 'methods'
const GROUP_SETUP = 'setup'
const GROUP_WATCHER = 'watch'
+const GROUP_EXPOSE = 'expose'
const PROPERTY_LABEL = {
props: 'property',
@@ -60,7 +61,12 @@ const PROPERTY_LABEL = {
computed: 'computed property',
methods: 'method',
setup: 'property returned from `setup()`',
- watch: 'watch'
+
+ // not use
+ watch: 'watch',
+ provide: 'provide',
+ inject: 'inject',
+ expose: 'expose'
}
// ------------------------------------------------------------------------------
@@ -900,51 +906,57 @@ module.exports = {
onVueObjectEnter(node) {
const container = getVueComponentPropertiesContainer(node)
- for (const watcher of utils.iterateProperties(
+ for (const watcherOrExpose of utils.iterateProperties(
node,
- new Set([GROUP_WATCHER])
+ new Set([GROUP_WATCHER, GROUP_EXPOSE])
)) {
- // Process `watch: { foo /* <- this */ () {} }`
- const segments = watcher.name.split('.')
- container.usedProperties.addUsed(segments[0], (context) => {
- return buildChainTracker(segments)(context)
- /**
- * @param {string[]} baseSegments
- * @returns {UsedPropertiesTracker}
- */
- function buildChainTracker(baseSegments) {
- return () => {
- const subSegments = baseSegments.slice(1)
- const usedProps = new UsedProperties()
- if (subSegments.length) {
- usedProps.addUsed(
- subSegments[0],
- buildChainTracker(subSegments)
- )
+ if (watcherOrExpose.groupName === GROUP_WATCHER) {
+ const watcher = watcherOrExpose
+ // Process `watch: { foo /* <- this */ () {} }`
+ const segments = watcher.name.split('.')
+ container.usedProperties.addUsed(segments[0], (context) => {
+ return buildChainTracker(segments)(context)
+ /**
+ * @param {string[]} baseSegments
+ * @returns {UsedPropertiesTracker}
+ */
+ function buildChainTracker(baseSegments) {
+ return () => {
+ const subSegments = baseSegments.slice(1)
+ const usedProps = new UsedProperties()
+ if (subSegments.length) {
+ usedProps.addUsed(
+ subSegments[0],
+ buildChainTracker(subSegments)
+ )
+ }
+ return usedProps
}
- return usedProps
}
- }
- })
+ })
- // Process `watch: { x: 'foo' /* <- this */ }`
- if (watcher.type === 'object') {
- const property = watcher.property
- if (property.kind === 'init') {
- for (const handlerValueNode of utils.iterateWatchHandlerValues(
- property
- )) {
- if (
- handlerValueNode.type === 'Literal' ||
- handlerValueNode.type === 'TemplateLiteral'
- ) {
- const name = utils.getStringLiteralValue(handlerValueNode)
- if (name != null) {
- container.usedProperties.addUsed(name, null)
+ // Process `watch: { x: 'foo' /* <- this */ }`
+ if (watcher.type === 'object') {
+ const property = watcher.property
+ if (property.kind === 'init') {
+ for (const handlerValueNode of utils.iterateWatchHandlerValues(
+ property
+ )) {
+ if (
+ handlerValueNode.type === 'Literal' ||
+ handlerValueNode.type === 'TemplateLiteral'
+ ) {
+ const name = utils.getStringLiteralValue(handlerValueNode)
+ if (name != null) {
+ container.usedProperties.addUsed(name, null)
+ }
}
}
}
}
+ } else if (watcherOrExpose.groupName === GROUP_EXPOSE) {
+ const expose = watcherOrExpose
+ container.usedProperties.addUsed(expose.name, null)
}
}
container.properties.push(...utils.iterateProperties(node, groups))
diff --git a/lib/utils/index.js b/lib/utils/index.js
index b697a0d6b..7ad21ec4c 100644
--- a/lib/utils/index.js
+++ b/lib/utils/index.js
@@ -23,7 +23,7 @@
* @typedef { {key: string | null, value: BlockStatement | null} } ComponentComputedProperty
*/
/**
- * @typedef { 'props' | 'data' | 'computed' | 'setup' | 'watch' | 'methods' } GroupName
+ * @typedef { 'props' | 'data' | 'computed' | 'setup' | 'watch' | 'methods' | 'provide' | 'inject' | 'expose' } GroupName
* @typedef { { type: 'array', name: string, groupName: GroupName, node: Literal | TemplateLiteral } } ComponentArrayPropertyData
* @typedef { { type: 'object', name: string, groupName: GroupName, node: Identifier | Literal | TemplateLiteral, property: Property } } ComponentObjectPropertyData
* @typedef { ComponentArrayPropertyData | ComponentObjectPropertyData } ComponentPropertyData
diff --git a/tests/lib/rules/no-unused-properties.js b/tests/lib/rules/no-unused-properties.js
index f9d61e4b0..4af8091af 100644
--- a/tests/lib/rules/no-unused-properties.js
+++ b/tests/lib/rules/no-unused-properties.js
@@ -1535,6 +1535,33 @@ tester.run('no-unused-properties', rule, {
ignorePublicMembers: true
}
]
+ },
+
+ // expose
+ {
+ filename: 'test.vue',
+ code: `
+
+ {{a}}
+
+ `,
+ options: allOptions
}
],
@@ -2412,6 +2439,42 @@ tester.run('no-unused-properties', rule, {
props.b
`,
errors: ["'c' of property found, but never used."]
+ },
+
+ // expose
+ {
+ filename: 'test.vue',
+ code: `
+
+ {{a}}
+
+ `,
+ options: allOptions,
+ errors: [
+ "'b' of property found, but never used.",
+ "'d' of data found, but never used.",
+ "'f' of computed property found, but never used.",
+ "'h' of method found, but never used."
+ ]
}
]
})