{"record":{"id":"7cf9da7dd2d6dfef","repo":"Meituan-Dianping/mpvue","slug":"key-does-not-work-on-slot-because-slots-are-ab","errorCode":null,"errorMessage":"`key` does not work on <slot> because slots are abstract outlets and can possibly expand into multiple elements. Use the key on a wrapping element instead.","messagePattern":"`key` does not work on <slot> because slots are abstract outlets and can possibly expand into multiple elements\\. Use the key on a wrapping element instead\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/weex-template-compiler/build.js","lineNumber":1736,"sourceCode":"function addIfCondition (el, condition) {\n  if (!el.ifConditions) {\n    el.ifConditions = [];\n  }\n  el.ifConditions.push(condition);\n}\n\nfunction processOnce (el) {\n  var once$$1 = getAndRemoveAttr(el, 'v-once');\n  if (once$$1 != null) {\n    el.once = true;\n  }\n}\n\nfunction processSlot (el) {\n  if (el.tag === 'slot') {\n    el.slotName = getBindingAttr(el, 'name');\n    if (process.env.NODE_ENV !== 'production' && el.key) {\n      warn(\n        \"`key` does not work on <slot> because slots are abstract outlets \" +\n        \"and can possibly expand into multiple elements. \" +\n        \"Use the key on a wrapping element instead.\"\n      );\n    }\n  } else {\n    var slotTarget = getBindingAttr(el, 'slot');\n    if (slotTarget) {\n      el.slotTarget = slotTarget === '\"\"' ? '\"default\"' : slotTarget;\n    }\n    if (el.tag === 'template') {\n      el.slotScope = getAndRemoveAttr(el, 'scope');\n    }\n  }\n}\n\nfunction processComponent (el) {\n  var binding;","sourceCodeStart":1718,"sourceCodeEnd":1754,"githubUrl":"https://github.com/Meituan-Dianping/mpvue/blob/6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b/packages/weex-template-compiler/build.js#L1718-L1754","documentation":"A <slot> element received a key binding. Slots are abstract outlets that may expand into multiple elements, so a per-node key is meaningless; the compiler warns and suggests keying a wrapping real element instead.","triggerScenarios":"Writing <slot :key=\"x\"> (or key=\"x\") in a template — processSlot detects el.tag === 'slot' with el.key set in dev mode, typically after processKey has already assigned el.key.","commonSituations":"Keying slots inside v-for loops to force re-render, or habitually adding :key to every repeated element including <slot> placeholders.","solutions":["Remove the key from <slot>","Wrap the slot in a keyed real element (e.g. a keyed <div>) if re-render control is needed","Place the key on the parent element that consumes the slot content"],"exampleFix":"// before\n<slot :key=\"item.id\">fallback</slot>\n// after\n<div :key=\"item.id\"><slot>fallback</slot></div>","handlingStrategy":"validation","validationCode":"function keyOnSlot(template) {\n  return /<slot[^>]*\\s(?::key|v-bind:key|key)\\s*=/.test(template)\n    ? 'key on <slot>; use a wrapping element instead'\n    : null;\n}","typeGuard":"function hasNoSlotKey(template) {\n  return typeof template === 'string' && !/<slot[^>]*\\s(?::key|v-bind:key|key)\\s*=/.test(template);\n}","tryCatchPattern":null,"preventionTips":["Never add :key directly to <slot>","Wrap slots in a keyed real element when re-render control is needed","Grep templates for <slot with key attributes in CI"],"tags":["slot","key","template","vue","weex"],"backgroundTag":"key-on-slot-element","analyzedSha":"6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b","analyzedAt":"2026-09-02T05:17:40.946Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T11:17:12.671Z"}