diff --git a/docs/rules/README.md b/docs/rules/README.md
index dd5718b08..f3e2bfdf6 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -147,6 +147,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
|:--------|:------------|:---|
| [vue/attributes-order](./attributes-order.md) | enforce order of attributes | :wrench: |
| [vue/component-tags-order](./component-tags-order.md) | enforce order of component top-level elements | |
+| [vue/no-multiple-slot-args](./no-multiple-slot-args.md) | disallow to pass multiple arguments to scoped slots | |
| [vue/no-v-html](./no-v-html.md) | disallow use of v-html to prevent XSS attack | |
| [vue/order-in-components](./order-in-components.md) | enforce order of properties in components | :wrench: |
| [vue/this-in-template](./this-in-template.md) | disallow usage of `this` in template | |
@@ -254,6 +255,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
|:--------|:------------|:---|
| [vue/attributes-order](./attributes-order.md) | enforce order of attributes | :wrench: |
| [vue/component-tags-order](./component-tags-order.md) | enforce order of component top-level elements | |
+| [vue/no-multiple-slot-args](./no-multiple-slot-args.md) | disallow to pass multiple arguments to scoped slots | |
| [vue/no-v-html](./no-v-html.md) | disallow use of v-html to prevent XSS attack | |
| [vue/order-in-components](./order-in-components.md) | enforce order of properties in components | :wrench: |
| [vue/this-in-template](./this-in-template.md) | disallow usage of `this` in template | |
diff --git a/docs/rules/no-multiple-slot-args.md b/docs/rules/no-multiple-slot-args.md
new file mode 100644
index 000000000..d0d319458
--- /dev/null
+++ b/docs/rules/no-multiple-slot-args.md
@@ -0,0 +1,49 @@
+---
+pageClass: rule-details
+sidebarDepth: 0
+title: vue/no-multiple-slot-args
+description: disallow to pass multiple arguments to scoped slots
+---
+# vue/no-multiple-slot-args
+> disallow to pass multiple arguments to scoped slots
+
+- :gear: This rule is included in `"plugin:vue/vue3-recommended"` and `"plugin:vue/recommended"`.
+
+## :book: Rule Details
+
+This rule disallows to pass multiple arguments to scoped slots.
+In details, it reports call expressions if a call of `this.$scopedSlots` members has 2 or more arguments.
+
+
+
+```vue
+
+```
+
+
+
+## :wrench: Options
+
+Nothing.
+
+## :books: Further reading
+
+- [vuejs/vue#9468](https://github.com/vuejs/vue/issues/9468#issuecomment-462210146)
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-multiple-slot-args.js)
+- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-multiple-slot-args.js)
diff --git a/lib/configs/recommended.js b/lib/configs/recommended.js
index e3ca8eba7..e6388e158 100644
--- a/lib/configs/recommended.js
+++ b/lib/configs/recommended.js
@@ -8,6 +8,7 @@ module.exports = {
rules: {
'vue/attributes-order': 'warn',
'vue/component-tags-order': 'warn',
+ 'vue/no-multiple-slot-args': 'warn',
'vue/no-v-html': 'warn',
'vue/order-in-components': 'warn',
'vue/this-in-template': 'warn'
diff --git a/lib/configs/vue3-recommended.js b/lib/configs/vue3-recommended.js
index 700f0f8f5..318690c33 100644
--- a/lib/configs/vue3-recommended.js
+++ b/lib/configs/vue3-recommended.js
@@ -8,6 +8,7 @@ module.exports = {
rules: {
'vue/attributes-order': 'warn',
'vue/component-tags-order': 'warn',
+ 'vue/no-multiple-slot-args': 'warn',
'vue/no-v-html': 'warn',
'vue/order-in-components': 'warn',
'vue/this-in-template': 'warn'
diff --git a/lib/index.js b/lib/index.js
index f41be8ba7..c0041525f 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -71,6 +71,7 @@ module.exports = {
'no-irregular-whitespace': require('./rules/no-irregular-whitespace'),
'no-lifecycle-after-await': require('./rules/no-lifecycle-after-await'),
'no-multi-spaces': require('./rules/no-multi-spaces'),
+ 'no-multiple-slot-args': require('./rules/no-multiple-slot-args'),
'no-multiple-template-root': require('./rules/no-multiple-template-root'),
'no-mutating-props': require('./rules/no-mutating-props'),
'no-parsing-error': require('./rules/no-parsing-error'),
diff --git a/lib/rules/no-multiple-slot-args.js b/lib/rules/no-multiple-slot-args.js
new file mode 100644
index 000000000..e8bcae96c
--- /dev/null
+++ b/lib/rules/no-multiple-slot-args.js
@@ -0,0 +1,127 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+const utils = require('../utils')
+const { findVariable } = require('eslint-utils')
+
+/**
+ * @typedef {import('vue-eslint-parser').AST.ESLintMemberExpression} MemberExpression
+ * @typedef {import('vue-eslint-parser').AST.ESLintIdentifier} Identifier
+ */
+
+// ------------------------------------------------------------------------------
+// Rule Definition
+// ------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ type: 'problem',
+ docs: {
+ description: 'disallow to pass multiple arguments to scoped slots',
+ categories: ['vue3-recommended', 'recommended'],
+ url: 'https://eslint.vuejs.org/rules/no-multiple-slot-args.html'
+ },
+ fixable: null,
+ schema: [],
+ messages: {
+ unexpected: 'Unexpected multiple arguments.',
+ unexpectedSpread: 'Unexpected spread argument.'
+ }
+ },
+
+ create(context) {
+ /**
+ * Verify the given node
+ * @param {MemberExpression | Identifier} node The node to verify
+ */
+ function verify(node) {
+ const parent = node.parent
+
+ if (
+ parent.type === 'VariableDeclarator' &&
+ parent.id.type === 'Identifier'
+ ) {
+ // const foo = this.$scopedSlots.foo
+ verifyReferences(parent.id)
+ return
+ }
+
+ if (
+ parent.type === 'AssignmentExpression' &&
+ parent.right === node &&
+ parent.left.type === 'Identifier'
+ ) {
+ // foo = this.$scopedSlots.foo
+ verifyReferences(parent.left)
+ return
+ }
+
+ if (parent.type !== 'CallExpression' || parent.arguments.includes(node)) {
+ return
+ }
+
+ if (!parent.arguments.length) {
+ return
+ }
+ if (parent.arguments.length > 1) {
+ context.report({
+ node: parent.arguments[1],
+ messageId: 'unexpected'
+ })
+ }
+ if (parent.arguments[0].type === 'SpreadElement') {
+ context.report({
+ node: parent.arguments[0],
+ messageId: 'unexpectedSpread'
+ })
+ }
+ }
+ /**
+ * Verify the references of the given node.
+ * @param {Identifier} node The node to verify
+ */
+ function verifyReferences(node) {
+ // @ts-ignore
+ const variable = findVariable(context.getScope(), node)
+ if (!variable) {
+ return
+ }
+ for (const reference of variable.references) {
+ if (!reference.isRead()) {
+ continue
+ }
+ /** @type {Identifier} */
+ const id = reference.identifier
+ verify(id)
+ }
+ }
+
+ return utils.defineVueVisitor(context, {
+ /** @param {MemberExpression} node */
+ MemberExpression(node) {
+ const object = node.object
+ if (object.type !== 'MemberExpression') {
+ return
+ }
+ if (
+ object.property.type !== 'Identifier' ||
+ (object.property.name !== '$slots' &&
+ object.property.name !== '$scopedSlots')
+ ) {
+ return
+ }
+ if (!utils.isThis(object.object, context)) {
+ return
+ }
+ verify(node)
+ }
+ })
+ }
+}
diff --git a/tests/lib/rules/no-multiple-slot-args.js b/tests/lib/rules/no-multiple-slot-args.js
new file mode 100644
index 000000000..fb42767b9
--- /dev/null
+++ b/tests/lib/rules/no-multiple-slot-args.js
@@ -0,0 +1,164 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+const rule = require('../../../lib/rules/no-multiple-slot-args')
+
+const RuleTester = require('eslint').RuleTester
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({
+ parser: require.resolve('vue-eslint-parser'),
+ parserOptions: { ecmaVersion: 2018, sourceType: 'module' }
+})
+ruleTester.run('no-multiple-slot-args', rule, {
+ valid: [
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ }
+ ],
+
+ invalid: [
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ errors: [
+ {
+ message: 'Unexpected multiple arguments.',
+ line: 5,
+ column: 42,
+ endLine: 5,
+ endColumn: 45
+ },
+ {
+ message: 'Unexpected multiple arguments.',
+ line: 6,
+ column: 38,
+ endLine: 6,
+ endColumn: 41
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ errors: [
+ {
+ message: 'Unexpected multiple arguments.',
+ line: 7,
+ column: 42,
+ endLine: 7,
+ endColumn: 49
+ },
+ {
+ message: 'Unexpected spread argument.',
+ line: 10,
+ column: 34,
+ endLine: 10,
+ endColumn: 40
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ errors: [
+ 'Unexpected multiple arguments.',
+ 'Unexpected multiple arguments.'
+ ]
+ }
+ ]
+})