UNPKG

eslint-plugin-vue

Version:

Official ESLint plugin for Vue.js

63 lines (60 loc) 2.74 kB
'use strict'; const require_runtime = require('../_virtual/_rolldown/runtime.js'); const require_index = require('../utils/index.js'); //#region lib/rules/no-v-for-template-key-on-child.js /** * @author Yosuke Ota * This rule is based on X_V_FOR_TEMPLATE_KEY_PLACEMENT error of Vue 3. * see https://github.com/vuejs/vue-next/blob/b0d01e9db9ffe5781cce5a2d62c8552db3d615b0/packages/compiler-core/src/errors.ts#L70 */ var require_no_v_for_template_key_on_child = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => { const utils = require_index.default; /** * Check whether the given attribute is using the variables which are defined by `v-for` directives. * @param {VDirective} vFor The attribute node of `v-for` to check. * @param {VDirective} vBindKey The attribute node of `v-bind:key` to check. * @returns {boolean} `true` if the node is using the variables which are defined by `v-for` directives. */ function isUsingIterationVar(vFor, vBindKey) { if (vBindKey.value == null) return false; const references = vBindKey.value.references; const variables = vFor.parent.parent.variables; return references.some((reference) => variables.some((variable) => variable.id.name === reference.id.name && variable.kind === "v-for")); } module.exports = { meta: { type: "problem", docs: { description: "disallow key of `<template v-for>` placed on child elements", categories: ["vue3-essential"], url: "https://eslint.vuejs.org/rules/no-v-for-template-key-on-child.html" }, fixable: null, schema: [], messages: { vForTemplateKeyPlacement: "`<template v-for>` key should be placed on the `<template>` tag." } }, create(context) { return utils.defineTemplateBodyVisitor(context, { "VElement[name='template'] > VStartTag > VAttribute[directive=true][key.name.name='for']"(node) { const template = node.parent.parent; const vBindKeyOnTemplate = utils.getDirective(template, "bind", "key"); if (vBindKeyOnTemplate && isUsingIterationVar(node, vBindKeyOnTemplate)) return; for (const child of template.children.filter(utils.isVElement)) { if (utils.hasDirective(child, "if") || utils.hasDirective(child, "else-if") || utils.hasDirective(child, "else") || utils.hasDirective(child, "for")) continue; const vBindKeyOnChild = utils.getDirective(child, "bind", "key"); if (vBindKeyOnChild && isUsingIterationVar(node, vBindKeyOnChild)) context.report({ node: vBindKeyOnChild, loc: vBindKeyOnChild.loc, messageId: "vForTemplateKeyPlacement" }); } } }); } }; })); //#endregion Object.defineProperty(exports, 'default', { enumerable: true, get: function () { return require_no_v_for_template_key_on_child(); } });