diff --git a/docs/rules/README.md b/docs/rules/README.md
index 735dc87d0..49a6c6389 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -349,6 +349,7 @@ For example:
| [vue/no-use-computed-property-like-method](./no-use-computed-property-like-method.md) | disallow use computed property like method | |
| [vue/no-useless-mustaches](./no-useless-mustaches.md) | disallow unnecessary mustache interpolations | :wrench: |
| [vue/no-useless-v-bind](./no-useless-v-bind.md) | disallow unnecessary `v-bind` directives | :wrench: |
+| [vue/no-v-text-v-html-on-component](./no-v-text-v-html-on-component.md) | disallow v-text / v-html on component | |
| [vue/no-v-text](./no-v-text.md) | disallow use of v-text | |
| [vue/padding-line-between-blocks](./padding-line-between-blocks.md) | require or disallow padding lines between blocks | :wrench: |
| [vue/prefer-separate-static-class](./prefer-separate-static-class.md) | require static class names in template to be in a separate `class` attribute | :wrench: |
diff --git a/docs/rules/no-v-text-v-html-on-component.md b/docs/rules/no-v-text-v-html-on-component.md
new file mode 100644
index 000000000..5d8c8c434
--- /dev/null
+++ b/docs/rules/no-v-text-v-html-on-component.md
@@ -0,0 +1,43 @@
+---
+pageClass: rule-details
+sidebarDepth: 0
+title: vue/no-v-text-v-html-on-component
+description: disallow v-text / v-html on component
+---
+# vue/no-v-text-v-html-on-component
+
+> disallow v-text / v-html on component
+
+- :exclamation: ***This rule has not been released yet.***
+
+## :book: Rule Details
+
+This rule disallows the use of v-text / v-html on component.
+
+If you use v-text / v-html on a component, it will overwrite the component's content and may break the component.
+
+
+
+```vue
+
+
+
+
+ {{content}}
+
+
+
+
+
+```
+
+
+
+## :wrench: Options
+
+Nothing.
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-v-text-v-html-on-component.js)
+- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-v-text-v-html-on-component.js)
diff --git a/lib/index.js b/lib/index.js
index 3c628c559..021710984 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -145,6 +145,7 @@ module.exports = {
'no-v-for-template-key': require('./rules/no-v-for-template-key'),
'no-v-html': require('./rules/no-v-html'),
'no-v-model-argument': require('./rules/no-v-model-argument'),
+ 'no-v-text-v-html-on-component': require('./rules/no-v-text-v-html-on-component'),
'no-v-text': require('./rules/no-v-text'),
'no-watch-after-await': require('./rules/no-watch-after-await'),
'object-curly-newline': require('./rules/object-curly-newline'),
diff --git a/lib/rules/no-v-text-v-html-on-component.js b/lib/rules/no-v-text-v-html-on-component.js
new file mode 100644
index 000000000..4a208627d
--- /dev/null
+++ b/lib/rules/no-v-text-v-html-on-component.js
@@ -0,0 +1,59 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+const utils = require('../utils')
+
+// ------------------------------------------------------------------------------
+// Rule Definition
+// ------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ type: 'problem',
+ docs: {
+ description: 'disallow v-text / v-html on component',
+ // TODO We will change it in the next major version.
+ // categories: ['essential', 'vue3-essential'],
+ categories: undefined,
+ url: 'https://eslint.vuejs.org/rules/no-v-text-v-html-on-component.html'
+ },
+ fixable: null,
+ schema: [],
+ messages: {
+ disallow:
+ "Using {{directiveName}} on component may break component's content."
+ }
+ },
+ /** @param {RuleContext} context */
+ create(context) {
+ /**
+ * Verify for v-text and v-html directive
+ * @param {VDirective} node
+ */
+ function verify(node) {
+ const element = node.parent.parent
+ if (utils.isCustomComponent(element)) {
+ context.report({
+ node,
+ loc: node.loc,
+ messageId: 'disallow',
+ data: {
+ directiveName: `v-${node.key.name.name}`
+ }
+ })
+ }
+ }
+
+ return utils.defineTemplateBodyVisitor(context, {
+ "VAttribute[directive=true][key.name.name='text']": verify,
+ "VAttribute[directive=true][key.name.name='html']": verify
+ })
+ }
+}
diff --git a/tests/lib/rules/no-v-text-v-html-on-component.js b/tests/lib/rules/no-v-text-v-html-on-component.js
new file mode 100644
index 000000000..c50071346
--- /dev/null
+++ b/tests/lib/rules/no-v-text-v-html-on-component.js
@@ -0,0 +1,137 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+const RuleTester = require('eslint').RuleTester
+const rule = require('../../../lib/rules/no-v-text-v-html-on-component')
+
+const tester = new RuleTester({
+ parser: require.resolve('vue-eslint-parser'),
+ parserOptions: {
+ ecmaVersion: 2020,
+ sourceType: 'module'
+ }
+})
+
+tester.run('no-v-text-v-html-on-component', rule, {
+ valid: [
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `
+ }
+ ],
+ invalid: [
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `,
+ errors: [
+ {
+ message: "Using v-text on component may break component's content.",
+ line: 3,
+ column: 22
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `,
+ errors: [
+ {
+ message: "Using v-html on component may break component's content.",
+ line: 3,
+ column: 22
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `,
+ errors: [
+ {
+ message: "Using v-text on component may break component's content.",
+ line: 3,
+ column: 36
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `,
+ errors: [
+ {
+ message: "Using v-html on component may break component's content.",
+ line: 3,
+ column: 36
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `,
+ errors: [
+ {
+ message: "Using v-text on component may break component's content.",
+ line: 3,
+ column: 30
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+ `,
+ errors: [
+ {
+ message: "Using v-html on component may break component's content.",
+ line: 3,
+ column: 30
+ }
+ ]
+ }
+ ]
+})