| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- /**
- * @fileoverview Disable inheritAttrs when using v-bind="$attrs"
- * @author Hiroki Osame
- */
- 'use strict'
- const utils = require('../utils')
- /** @param {VElement[]} elements */
- function isConditionalGroup(elements) {
- if (elements.length < 2) {
- return false
- }
- const firstElement = elements[0]
- const lastElement = elements[elements.length - 1]
- const inBetweenElements = elements.slice(1, -1)
- return (
- utils.hasDirective(firstElement, 'if') &&
- (utils.hasDirective(lastElement, 'else-if') ||
- utils.hasDirective(lastElement, 'else')) &&
- inBetweenElements.every((element) => utils.hasDirective(element, 'else-if'))
- )
- }
- /** @param {VElement[]} elements */
- function isMultiRootNodes(elements) {
- if (elements.length > 1 && !isConditionalGroup(elements)) {
- return true
- }
- return false
- }
- module.exports = {
- meta: {
- type: 'suggestion',
- docs: {
- description:
- 'enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"`',
- categories: undefined,
- url: 'https://eslint.vuejs.org/rules/no-duplicate-attr-inheritance.html'
- },
- fixable: null,
- schema: [
- {
- type: 'object',
- properties: {
- checkMultiRootNodes: {
- type: 'boolean'
- }
- },
- additionalProperties: false
- }
- ],
- messages: {
- noDuplicateAttrInheritance: 'Set "inheritAttrs" to false.'
- }
- },
- /** @param {RuleContext} context */
- create(context) {
- const options = context.options[0] || {}
- const checkMultiRootNodes = options.checkMultiRootNodes === true
- /** @type {string | number | boolean | RegExp | BigInt | null} */
- let inheritsAttrs = true
- /** @type {VReference[]} */
- const attrsRefs = []
- /** @param {ObjectExpression} node */
- function processOptions(node) {
- const inheritAttrsProp = utils.findProperty(node, 'inheritAttrs')
- if (inheritAttrsProp && inheritAttrsProp.value.type === 'Literal') {
- inheritsAttrs = inheritAttrsProp.value.value
- }
- }
- return utils.compositingVisitors(
- utils.executeOnVue(context, processOptions),
- utils.defineScriptSetupVisitor(context, {
- onDefineOptionsEnter(node) {
- if (node.arguments.length === 0) return
- const define = node.arguments[0]
- if (define.type !== 'ObjectExpression') return
- processOptions(define)
- }
- }),
- utils.defineTemplateBodyVisitor(context, {
- /** @param {VExpressionContainer} node */
- "VAttribute[directive=true][key.name.name='bind'][key.argument=null] > VExpressionContainer"(
- node
- ) {
- if (!inheritsAttrs) {
- return
- }
- const reference = node.references.find((reference) => {
- if (reference.variable != null) {
- // Not vm reference
- return false
- }
- return reference.id.name === '$attrs'
- })
- if (reference) {
- attrsRefs.push(reference)
- }
- }
- }),
- {
- 'Program:exit'(program) {
- const element = program.templateBody
- if (element == null) {
- return
- }
- const rootElements = element.children.filter(utils.isVElement)
- if (!checkMultiRootNodes && isMultiRootNodes(rootElements)) return
- if (attrsRefs.length > 0) {
- for (const attrsRef of attrsRefs) {
- context.report({
- node: attrsRef.id,
- messageId: 'noDuplicateAttrInheritance'
- })
- }
- }
- }
- }
- )
- }
- }
|