diff --git a/docs/rules/max-lines-per-block.md b/docs/rules/max-lines-per-block.md
new file mode 100644
index 000000000..02fd2be41
--- /dev/null
+++ b/docs/rules/max-lines-per-block.md
@@ -0,0 +1,54 @@
+---
+pageClass: rule-details
+sidebarDepth: 0
+title: vue/max-lines-per-block
+description: enforce maximum number of lines in Vue SFC blocks
+---
+# vue/max-lines-per-block
+
+> enforce maximum number of lines in Vue SFC blocks
+
+- :exclamation: ***This rule has not been released yet.***
+
+## :book: Rule Details
+
+This rule enforces a maximum number of lines per block, in order to aid in maintainability and reduce complexity.
+
+## :wrench: Options
+
+This rule takes an object, where you can specify the maximum number of lines in each type of SFC block and customize the line counting behavior.
+The following properties can be specified for the object.
+
+- `script` ... Specify the maximum number of lines in `
+```
+
+
diff --git a/lib/rules/max-lines-per-block.js b/lib/rules/max-lines-per-block.js
new file mode 100644
index 000000000..bcb82d563
--- /dev/null
+++ b/lib/rules/max-lines-per-block.js
@@ -0,0 +1,110 @@
+/**
+ * @author lsdsjy
+ * @fileoverview Rule for checking the maximum number of lines in Vue SFC blocks.
+ */
+'use strict'
+
+const { SourceCode } = require('eslint')
+const utils = require('../utils')
+
+/**
+ * @param {string} text
+ */
+function isEmptyLine(text) {
+ return !text.trim()
+}
+
+module.exports = {
+ meta: {
+ type: 'problem',
+ docs: {
+ description: 'enforce maximum number of lines in Vue SFC blocks',
+ categories: undefined,
+ url: 'https://eslint.vuejs.org/rules/max-lines-per-block.html'
+ },
+ fixable: null,
+ schema: [
+ {
+ type: 'object',
+ properties: {
+ style: {
+ type: 'integer',
+ minimum: 1
+ },
+ template: {
+ type: 'integer',
+ minimum: 1
+ },
+ script: {
+ type: 'integer',
+ minimum: 1
+ },
+ skipBlankLines: {
+ type: 'boolean',
+ minimum: 0
+ }
+ },
+ additionalProperties: false
+ }
+ ],
+ messages: {
+ tooManyLines:
+ 'Block has too many lines ({{lineCount}}). Maximum allowed is {{limit}}.'
+ }
+ },
+ /** @param {RuleContext} context */
+ create(context) {
+ const option = context.options[0] || {}
+ /**
+ * @type {Record}
+ */
+ const limits = {
+ template: option.template,
+ script: option.script,
+ style: option.style
+ }
+
+ const code = context.getSourceCode()
+ const documentFragment =
+ context.parserServices.getDocumentFragment &&
+ context.parserServices.getDocumentFragment()
+
+ function getTopLevelHTMLElements() {
+ if (documentFragment) {
+ return documentFragment.children.filter(utils.isVElement)
+ }
+ return []
+ }
+
+ return {
+ /** @param {Program} node */
+ Program(node) {
+ if (utils.hasInvalidEOF(node)) {
+ return
+ }
+ for (const block of getTopLevelHTMLElements()) {
+ if (limits[block.name]) {
+ // We suppose the start tag and end tag occupy one single line respectively
+ let lineCount = block.loc.end.line - block.loc.start.line - 1
+
+ if (option.skipBlankLines) {
+ const lines = SourceCode.splitLines(code.getText(block))
+ lineCount -= lines.filter(isEmptyLine).length
+ }
+
+ if (lineCount > limits[block.name]) {
+ context.report({
+ node: block,
+ messageId: 'tooManyLines',
+ data: {
+ limit: limits[block.name],
+ lineCount
+ }
+ })
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/lib/rules/max-lines-per-block.js b/tests/lib/rules/max-lines-per-block.js
new file mode 100644
index 000000000..01d868e62
--- /dev/null
+++ b/tests/lib/rules/max-lines-per-block.js
@@ -0,0 +1,84 @@
+/**
+ * @author lsdsjy
+ */
+'use strict'
+
+const RuleTester = require('eslint').RuleTester
+const rule = require('../../../lib/rules/max-lines-per-block')
+
+const tester = new RuleTester({
+ parser: require.resolve('vue-eslint-parser'),
+ parserOptions: {
+ ecmaVersion: 2020,
+ sourceType: 'module'
+ }
+})
+
+tester.run('max-lines-per-block', rule, {
+ valid: [
+ {
+ code: `
+
+
+
+
+ `,
+ options: [{ template: 1 }]
+ },
+ {
+ code: `
+
+
+
+
+ `,
+ options: [{ template: 1, skipBlankLines: true }]
+ },
+ {
+ code: `
+
+
+
+
+ `,
+ options: [{ script: 1, style: 1 }]
+ }
+ ],
+ invalid: [
+ {
+ code: `
+
+
+
+
+ `,
+ options: [{ template: 1 }],
+ errors: [
+ {
+ message: 'Block has too many lines (2). Maximum allowed is 1.',
+ line: 2,
+ column: 7
+ }
+ ]
+ },
+ {
+ code: `
+
+ `,
+ options: [{ script: 1, skipBlankLines: true }],
+ errors: [
+ {
+ message: 'Block has too many lines (2). Maximum allowed is 1.',
+ line: 2,
+ column: 7
+ }
+ ]
+ }
+ ]
+})