[{"data":1,"prerenderedAt":3225},["ShallowReactive",2],{"page-\u002Fvue\u002F13-slots-and-scoped-slots":3},{"id":4,"title":5,"body":6,"description":3218,"extension":3219,"meta":3220,"navigation":87,"path":3221,"seo":3222,"stem":3223,"__hash__":3224},"content\u002Fvue\u002F13-slots-and-scoped-slots.md","Vue 3 Engineering Reference — Slots & Scoped Slots",{"type":7,"value":8,"toc":3207},"minimark",[9,14,19,976,980,1917,1921,2159,2163,2969,3203],[10,11,13],"h1",{"id":12},"_13-slots-scoped-slots","13 — Slots & Scoped Slots",[15,16,18],"h2",{"id":17},"default-and-named-slots","Default and Named Slots",[20,21,24,320,504,508],"code-wrapper",{"filename":22,"language":23},"Card.vue","vue",[25,26,30],"pre",{"className":27,"code":28,"language":23,"meta":29,"style":29},"language-vue shiki shiki-themes github-light github-dark","\u003Cscript setup>\n\u002F\u002F ── Slots are defined in the child, filled by the parent ──\n\u002F\u002F Default slot: \u003Cslot \u002F> — unnamed content from parent goes here\n\u002F\u002F Named slots: \u003Cslot name=\"header\" \u002F> — content with matching slot attribute\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"card\">\n    \u003C!-- Named slot: parent fills this with \u003Ctemplate #header> -->\n    \u003Cheader class=\"card-header\">\n      \u003Cslot name=\"header\" \u002F>\n    \u003C\u002Fheader>\n\n    \u003C!-- Default slot: unnamed content from parent -->\n    \u003Cdiv class=\"card-body\">\n      \u003Cslot \u002F>  \u003C!-- fallback content: shown if parent provides nothing -->\n    \u003C\u002Fdiv>\n\n    \u003Cfooter class=\"card-footer\">\n      \u003Cslot name=\"footer\">\n        \u003Cp>Default footer — shown if parent doesn't fill this slot\u003C\u002Fp>\n      \u003C\u002Fslot>\n    \u003C\u002Ffooter>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","",[31,32,33,53,60,66,72,82,89,99,120,126,144,167,177,182,188,204,219,228,233,250,266,282,292,301,311],"code",{"__ignoreMap":29},[34,35,38,42,46,50],"span",{"class":36,"line":37},"line",1,[34,39,41],{"class":40},"ssxIu","\u003C",[34,43,45],{"class":44},"sk71V","script",[34,47,49],{"class":48},"sIsaT"," setup",[34,51,52],{"class":40},">\n",[34,54,56],{"class":36,"line":55},2,[34,57,59],{"class":58},"sdCPZ","\u002F\u002F ── Slots are defined in the child, filled by the parent ──\n",[34,61,63],{"class":36,"line":62},3,[34,64,65],{"class":58},"\u002F\u002F Default slot: \u003Cslot \u002F> — unnamed content from parent goes here\n",[34,67,69],{"class":36,"line":68},4,[34,70,71],{"class":58},"\u002F\u002F Named slots: \u003Cslot name=\"header\" \u002F> — content with matching slot attribute\n",[34,73,75,78,80],{"class":36,"line":74},5,[34,76,77],{"class":40},"\u003C\u002F",[34,79,45],{"class":44},[34,81,52],{"class":40},[34,83,85],{"class":36,"line":84},6,[34,86,88],{"emptyLinePlaceholder":87},true,"\n",[34,90,92,94,97],{"class":36,"line":91},7,[34,93,41],{"class":40},[34,95,96],{"class":44},"template",[34,98,52],{"class":40},[34,100,102,105,108,111,114,118],{"class":36,"line":101},8,[34,103,104],{"class":40},"  \u003C",[34,106,107],{"class":44},"div",[34,109,110],{"class":48}," class",[34,112,113],{"class":40},"=",[34,115,117],{"class":116},"sJ6F3","\"card\"",[34,119,52],{"class":40},[34,121,123],{"class":36,"line":122},9,[34,124,125],{"class":58},"    \u003C!-- Named slot: parent fills this with \u003Ctemplate #header> -->\n",[34,127,129,132,135,137,139,142],{"class":36,"line":128},10,[34,130,131],{"class":40},"    \u003C",[34,133,134],{"class":44},"header",[34,136,110],{"class":48},[34,138,113],{"class":40},[34,140,141],{"class":116},"\"card-header\"",[34,143,52],{"class":40},[34,145,147,150,153,156,158,161,165],{"class":36,"line":146},11,[34,148,149],{"class":40},"      \u003C",[34,151,152],{"class":44},"slot",[34,154,155],{"class":48}," name",[34,157,113],{"class":40},[34,159,160],{"class":116},"\"header\"",[34,162,164],{"class":163},"sMKGj"," \u002F",[34,166,52],{"class":40},[34,168,170,173,175],{"class":36,"line":169},12,[34,171,172],{"class":40},"    \u003C\u002F",[34,174,134],{"class":44},[34,176,52],{"class":40},[34,178,180],{"class":36,"line":179},13,[34,181,88],{"emptyLinePlaceholder":87},[34,183,185],{"class":36,"line":184},14,[34,186,187],{"class":58},"    \u003C!-- Default slot: unnamed content from parent -->\n",[34,189,191,193,195,197,199,202],{"class":36,"line":190},15,[34,192,131],{"class":40},[34,194,107],{"class":44},[34,196,110],{"class":48},[34,198,113],{"class":40},[34,200,201],{"class":116},"\"card-body\"",[34,203,52],{"class":40},[34,205,207,209,211,213,216],{"class":36,"line":206},16,[34,208,149],{"class":40},[34,210,152],{"class":44},[34,212,164],{"class":163},[34,214,215],{"class":40},">  ",[34,217,218],{"class":58},"\u003C!-- fallback content: shown if parent provides nothing -->\n",[34,220,222,224,226],{"class":36,"line":221},17,[34,223,172],{"class":40},[34,225,107],{"class":44},[34,227,52],{"class":40},[34,229,231],{"class":36,"line":230},18,[34,232,88],{"emptyLinePlaceholder":87},[34,234,236,238,241,243,245,248],{"class":36,"line":235},19,[34,237,131],{"class":40},[34,239,240],{"class":44},"footer",[34,242,110],{"class":48},[34,244,113],{"class":40},[34,246,247],{"class":116},"\"card-footer\"",[34,249,52],{"class":40},[34,251,253,255,257,259,261,264],{"class":36,"line":252},20,[34,254,149],{"class":40},[34,256,152],{"class":44},[34,258,155],{"class":48},[34,260,113],{"class":40},[34,262,263],{"class":116},"\"footer\"",[34,265,52],{"class":40},[34,267,269,272,275,278,280],{"class":36,"line":268},21,[34,270,271],{"class":40},"        \u003C",[34,273,274],{"class":44},"p",[34,276,277],{"class":40},">Default footer — shown if parent doesn't fill this slot\u003C\u002F",[34,279,274],{"class":44},[34,281,52],{"class":40},[34,283,285,288,290],{"class":36,"line":284},22,[34,286,287],{"class":40},"      \u003C\u002F",[34,289,152],{"class":44},[34,291,52],{"class":40},[34,293,295,297,299],{"class":36,"line":294},23,[34,296,172],{"class":40},[34,298,240],{"class":44},[34,300,52],{"class":40},[34,302,304,307,309],{"class":36,"line":303},24,[34,305,306],{"class":40},"  \u003C\u002F",[34,308,107],{"class":44},[34,310,52],{"class":40},[34,312,314,316,318],{"class":36,"line":313},25,[34,315,77],{"class":40},[34,317,96],{"class":44},[34,319,52],{"class":40},[20,321,323],{"filename":322,"language":23},"CardUsage.vue",[25,324,326],{"className":27,"code":325,"language":23,"meta":29,"style":29},"\u003Cscript setup>\nimport Card from '.\u002FCard.vue'\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CCard>\n    \u003C!-- ── Named slot: #header is shorthand for v-slot:header ── -->\n    \u003Ctemplate #header>\n      \u003Ch2>User Profile\u003C\u002Fh2>\n    \u003C\u002Ftemplate>\n\n    \u003C!-- ── Default slot: content NOT wrapped in \u003Ctemplate #default> ── -->\n    \u003Cp>This goes into the unnamed \u003Cslot \u002F> in Card.\u003C\u002Fp>\n\n    \u003Ctemplate #footer>\n      \u003Cbutton>Save\u003C\u002Fbutton>\n    \u003C\u002Ftemplate>\n  \u003C\u002FCard>\n\u003C\u002Ftemplate>\n",[31,327,328,338,353,361,365,373,382,387,400,413,421,425,430,450,454,466,480,488,496],{"__ignoreMap":29},[34,329,330,332,334,336],{"class":36,"line":37},[34,331,41],{"class":40},[34,333,45],{"class":44},[34,335,49],{"class":48},[34,337,52],{"class":40},[34,339,340,344,347,350],{"class":36,"line":55},[34,341,343],{"class":342},"svdQ7","import",[34,345,346],{"class":40}," Card ",[34,348,349],{"class":342},"from",[34,351,352],{"class":116}," '.\u002FCard.vue'\n",[34,354,355,357,359],{"class":36,"line":62},[34,356,77],{"class":40},[34,358,45],{"class":44},[34,360,52],{"class":40},[34,362,363],{"class":36,"line":68},[34,364,88],{"emptyLinePlaceholder":87},[34,366,367,369,371],{"class":36,"line":74},[34,368,41],{"class":40},[34,370,96],{"class":44},[34,372,52],{"class":40},[34,374,375,377,380],{"class":36,"line":84},[34,376,104],{"class":40},[34,378,379],{"class":44},"Card",[34,381,52],{"class":40},[34,383,384],{"class":36,"line":91},[34,385,386],{"class":58},"    \u003C!-- ── Named slot: #header is shorthand for v-slot:header ── -->\n",[34,388,389,391,393,396,398],{"class":36,"line":101},[34,390,131],{"class":40},[34,392,96],{"class":44},[34,394,395],{"class":40}," #",[34,397,134],{"class":48},[34,399,52],{"class":40},[34,401,402,404,406,409,411],{"class":36,"line":122},[34,403,149],{"class":40},[34,405,15],{"class":44},[34,407,408],{"class":40},">User Profile\u003C\u002F",[34,410,15],{"class":44},[34,412,52],{"class":40},[34,414,415,417,419],{"class":36,"line":128},[34,416,172],{"class":40},[34,418,96],{"class":44},[34,420,52],{"class":40},[34,422,423],{"class":36,"line":146},[34,424,88],{"emptyLinePlaceholder":87},[34,426,427],{"class":36,"line":169},[34,428,429],{"class":58},"    \u003C!-- ── Default slot: content NOT wrapped in \u003Ctemplate #default> ── -->\n",[34,431,432,434,436,439,441,443,446,448],{"class":36,"line":179},[34,433,131],{"class":40},[34,435,274],{"class":44},[34,437,438],{"class":40},">This goes into the unnamed \u003C",[34,440,152],{"class":44},[34,442,164],{"class":163},[34,444,445],{"class":40},"> in Card.\u003C\u002F",[34,447,274],{"class":44},[34,449,52],{"class":40},[34,451,452],{"class":36,"line":184},[34,453,88],{"emptyLinePlaceholder":87},[34,455,456,458,460,462,464],{"class":36,"line":190},[34,457,131],{"class":40},[34,459,96],{"class":44},[34,461,395],{"class":40},[34,463,240],{"class":48},[34,465,52],{"class":40},[34,467,468,470,473,476,478],{"class":36,"line":206},[34,469,149],{"class":40},[34,471,472],{"class":44},"button",[34,474,475],{"class":40},">Save\u003C\u002F",[34,477,472],{"class":44},[34,479,52],{"class":40},[34,481,482,484,486],{"class":36,"line":221},[34,483,172],{"class":40},[34,485,96],{"class":44},[34,487,52],{"class":40},[34,489,490,492,494],{"class":36,"line":230},[34,491,306],{"class":40},[34,493,379],{"class":44},[34,495,52],{"class":40},[34,497,498,500,502],{"class":36,"line":235},[34,499,77],{"class":40},[34,501,96],{"class":44},[34,503,52],{"class":40},[15,505,507],{"id":506},"scoped-slots-child-to-parent-data-passing","Scoped Slots — Child-to-Parent Data Passing",[20,509,511,797],{"filename":510,"language":23},"DataTable.vue",[25,512,514],{"className":27,"code":513,"language":23,"meta":29,"style":29},"\u003Cscript setup>\nconst props = defineProps\u003C{\n  rows: Array\u003C{ id: number; name: string; status: string }>\n}>()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Ctable>\n    \u003Ctbody>\n      \u003Ctr v-for=\"row in rows\" :key=\"row.id\">\n        \u003C!-- ── Scoped slot: child passes row data to parent's slot content ── -->\n        \u003C!-- The parent decides HOW to render each row — child provides the data -->\n        \u003Cslot name=\"row\" :row=\"row\" :index=\"$index\" \u002F>\n        \u003C!-- If parent doesn't fill #row, show default rendering: -->\n        \u003Ctemplate #row=\"{ row }\">\n          \u003Ctd>{{ row.name }}\u003C\u002Ftd>\n          \u003Ctd>{{ row.status }}\u003C\u002Ftd>\n        \u003C\u002Ftemplate>\n      \u003C\u002Ftr>\n    \u003C\u002Ftbody>\n  \u003C\u002Ftable>\n\u003C\u002Ftemplate>\n",[31,515,516,526,544,590,595,603,607,615,624,633,658,663,668,700,705,728,743,756,765,773,781,789],{"__ignoreMap":29},[34,517,518,520,522,524],{"class":36,"line":37},[34,519,41],{"class":40},[34,521,45],{"class":44},[34,523,49],{"class":48},[34,525,52],{"class":40},[34,527,528,531,535,538,541],{"class":36,"line":55},[34,529,530],{"class":342},"const",[34,532,534],{"class":533},"snvgF"," props",[34,536,537],{"class":342}," =",[34,539,540],{"class":48}," defineProps",[34,542,543],{"class":40},"\u003C{\n",[34,545,546,550,553,556,559,562,564,567,570,573,575,578,580,583,585,587],{"class":36,"line":62},[34,547,549],{"class":548},"sCrzJ","  rows",[34,551,552],{"class":342},":",[34,554,555],{"class":48}," Array",[34,557,558],{"class":40},"\u003C{ ",[34,560,561],{"class":548},"id",[34,563,552],{"class":342},[34,565,566],{"class":533}," number",[34,568,569],{"class":40},"; ",[34,571,572],{"class":548},"name",[34,574,552],{"class":342},[34,576,577],{"class":533}," string",[34,579,569],{"class":40},[34,581,582],{"class":548},"status",[34,584,552],{"class":342},[34,586,577],{"class":533},[34,588,589],{"class":40}," }>\n",[34,591,592],{"class":36,"line":68},[34,593,594],{"class":40},"}>()\n",[34,596,597,599,601],{"class":36,"line":74},[34,598,77],{"class":40},[34,600,45],{"class":44},[34,602,52],{"class":40},[34,604,605],{"class":36,"line":84},[34,606,88],{"emptyLinePlaceholder":87},[34,608,609,611,613],{"class":36,"line":91},[34,610,41],{"class":40},[34,612,96],{"class":44},[34,614,52],{"class":40},[34,616,617,619,622],{"class":36,"line":101},[34,618,104],{"class":40},[34,620,621],{"class":44},"table",[34,623,52],{"class":40},[34,625,626,628,631],{"class":36,"line":122},[34,627,131],{"class":40},[34,629,630],{"class":44},"tbody",[34,632,52],{"class":40},[34,634,635,637,640,643,645,648,651,653,656],{"class":36,"line":128},[34,636,149],{"class":40},[34,638,639],{"class":44},"tr",[34,641,642],{"class":48}," v-for",[34,644,113],{"class":40},[34,646,647],{"class":116},"\"row in rows\"",[34,649,650],{"class":48}," :key",[34,652,113],{"class":40},[34,654,655],{"class":116},"\"row.id\"",[34,657,52],{"class":40},[34,659,660],{"class":36,"line":146},[34,661,662],{"class":58},"        \u003C!-- ── Scoped slot: child passes row data to parent's slot content ── -->\n",[34,664,665],{"class":36,"line":169},[34,666,667],{"class":58},"        \u003C!-- The parent decides HOW to render each row — child provides the data -->\n",[34,669,670,672,674,676,678,681,684,686,688,691,693,696,698],{"class":36,"line":179},[34,671,271],{"class":40},[34,673,152],{"class":44},[34,675,155],{"class":48},[34,677,113],{"class":40},[34,679,680],{"class":116},"\"row\"",[34,682,683],{"class":48}," :row",[34,685,113],{"class":40},[34,687,680],{"class":116},[34,689,690],{"class":48}," :index",[34,692,113],{"class":40},[34,694,695],{"class":116},"\"$index\"",[34,697,164],{"class":163},[34,699,52],{"class":40},[34,701,702],{"class":36,"line":184},[34,703,704],{"class":58},"        \u003C!-- If parent doesn't fill #row, show default rendering: -->\n",[34,706,707,709,711,713,716,718,721,724,726],{"class":36,"line":190},[34,708,271],{"class":40},[34,710,96],{"class":44},[34,712,395],{"class":40},[34,714,715],{"class":48},"row",[34,717,113],{"class":40},[34,719,720],{"class":116},"\"",[34,722,723],{"class":40},"{ row }",[34,725,720],{"class":116},[34,727,52],{"class":40},[34,729,730,733,736,739,741],{"class":36,"line":206},[34,731,732],{"class":40},"          \u003C",[34,734,735],{"class":44},"td",[34,737,738],{"class":40},">{{ row.name }}\u003C\u002F",[34,740,735],{"class":44},[34,742,52],{"class":40},[34,744,745,747,749,752,754],{"class":36,"line":221},[34,746,732],{"class":40},[34,748,735],{"class":44},[34,750,751],{"class":40},">{{ row.status }}\u003C\u002F",[34,753,735],{"class":44},[34,755,52],{"class":40},[34,757,758,761,763],{"class":36,"line":230},[34,759,760],{"class":40},"        \u003C\u002F",[34,762,96],{"class":44},[34,764,52],{"class":40},[34,766,767,769,771],{"class":36,"line":235},[34,768,287],{"class":40},[34,770,639],{"class":44},[34,772,52],{"class":40},[34,774,775,777,779],{"class":36,"line":252},[34,776,172],{"class":40},[34,778,630],{"class":44},[34,780,52],{"class":40},[34,782,783,785,787],{"class":36,"line":268},[34,784,306],{"class":40},[34,786,621],{"class":44},[34,788,52],{"class":40},[34,790,791,793,795],{"class":36,"line":284},[34,792,77],{"class":40},[34,794,96],{"class":44},[34,796,52],{"class":40},[20,798,800],{"filename":799,"language":23},"DataTableUsage.vue",[25,801,803],{"className":27,"code":802,"language":23,"meta":29,"style":29},"\u003Ctemplate>\n  \u003C!-- ── Parent receives row data via slot props (destructured) ── -->\n  \u003CDataTable :rows=\"users\">\n    \u003Ctemplate #row=\"{ row, index }\">\n      \u003Ctd>{{ index + 1 }}\u003C\u002Ftd>\n      \u003Ctd class=\"font-bold\">{{ row.name }}\u003C\u002Ftd>\n      \u003Ctd>\n        \u003Cspan :class=\"row.status\">{{ row.status }}\u003C\u002Fspan>\n        \u003Cbutton @click=\"edit(row)\">Edit\u003C\u002Fbutton>\n      \u003C\u002Ftd>\n    \u003C\u002Ftemplate>\n  \u003C\u002FDataTable>\n\u003C\u002Ftemplate>\n",[31,804,805,813,818,842,863,876,895,903,923,944,952,960,968],{"__ignoreMap":29},[34,806,807,809,811],{"class":36,"line":37},[34,808,41],{"class":40},[34,810,96],{"class":44},[34,812,52],{"class":40},[34,814,815],{"class":36,"line":55},[34,816,817],{"class":58},"  \u003C!-- ── Parent receives row data via slot props (destructured) ── -->\n",[34,819,820,822,825,828,831,833,835,838,840],{"class":36,"line":62},[34,821,104],{"class":40},[34,823,824],{"class":44},"DataTable",[34,826,827],{"class":40}," :",[34,829,830],{"class":48},"rows",[34,832,113],{"class":40},[34,834,720],{"class":116},[34,836,837],{"class":40},"users",[34,839,720],{"class":116},[34,841,52],{"class":40},[34,843,844,846,848,850,852,854,856,859,861],{"class":36,"line":68},[34,845,131],{"class":40},[34,847,96],{"class":44},[34,849,395],{"class":40},[34,851,715],{"class":48},[34,853,113],{"class":40},[34,855,720],{"class":116},[34,857,858],{"class":40},"{ row, index }",[34,860,720],{"class":116},[34,862,52],{"class":40},[34,864,865,867,869,872,874],{"class":36,"line":74},[34,866,149],{"class":40},[34,868,735],{"class":44},[34,870,871],{"class":40},">{{ index + 1 }}\u003C\u002F",[34,873,735],{"class":44},[34,875,52],{"class":40},[34,877,878,880,882,884,886,889,891,893],{"class":36,"line":84},[34,879,149],{"class":40},[34,881,735],{"class":44},[34,883,110],{"class":48},[34,885,113],{"class":40},[34,887,888],{"class":116},"\"font-bold\"",[34,890,738],{"class":40},[34,892,735],{"class":44},[34,894,52],{"class":40},[34,896,897,899,901],{"class":36,"line":91},[34,898,149],{"class":40},[34,900,735],{"class":44},[34,902,52],{"class":40},[34,904,905,907,909,912,914,917,919,921],{"class":36,"line":101},[34,906,271],{"class":40},[34,908,34],{"class":44},[34,910,911],{"class":48}," :class",[34,913,113],{"class":40},[34,915,916],{"class":116},"\"row.status\"",[34,918,751],{"class":40},[34,920,34],{"class":44},[34,922,52],{"class":40},[34,924,925,927,929,932,934,937,940,942],{"class":36,"line":122},[34,926,271],{"class":40},[34,928,472],{"class":44},[34,930,931],{"class":48}," @click",[34,933,113],{"class":40},[34,935,936],{"class":116},"\"edit(row)\"",[34,938,939],{"class":40},">Edit\u003C\u002F",[34,941,472],{"class":44},[34,943,52],{"class":40},[34,945,946,948,950],{"class":36,"line":128},[34,947,287],{"class":40},[34,949,735],{"class":44},[34,951,52],{"class":40},[34,953,954,956,958],{"class":36,"line":146},[34,955,172],{"class":40},[34,957,96],{"class":44},[34,959,52],{"class":40},[34,961,962,964,966],{"class":36,"line":169},[34,963,306],{"class":40},[34,965,824],{"class":44},[34,967,52],{"class":40},[34,969,970,972,974],{"class":36,"line":179},[34,971,77],{"class":40},[34,973,96],{"class":44},[34,975,52],{"class":40},[15,977,979],{"id":978},"renderless-component-logic-encapsulation-via-slots","Renderless Component — Logic Encapsulation via Slots",[20,981,983,1222,1376,1380],{"filename":982,"language":23},"useMouseTracker.vue",[25,984,986],{"className":27,"code":985,"language":23,"meta":29,"style":29},"\u003Cscript setup>\nimport { ref, onMounted, onUnmounted, computed } from 'vue'\n\n\u002F\u002F ── Renderless component: provides data via scoped slot, renders nothing itself ──\n\u002F\u002F Parent has full control over the template — this component only provides state.\nconst x = ref(0)\nconst y = ref(0)\n\nfunction handler(e) { x.value = e.clientX; y.value = e.clientY }\n\nonMounted(() => window.addEventListener('mousemove', handler))\nonUnmounted(() => window.removeEventListener('mousemove', handler))\n\n\u002F\u002F ── Expose computed\u002Fstate to parent via default slot props ──\n\u002F\u002F Parent destructures { x, y } in the slot template.\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003C!-- The slot receives x, y, and a distance computed -->\n  \u003Cslot :x=\"x\" :y=\"y\" :distance=\"Math.sqrt(x**2 + y**2)\" \u002F>\n\u003C\u002Ftemplate>\n",[31,987,988,998,1010,1014,1019,1024,1045,1062,1066,1092,1096,1121,1141,1145,1150,1155,1163,1167,1175,1180,1214],{"__ignoreMap":29},[34,989,990,992,994,996],{"class":36,"line":37},[34,991,41],{"class":40},[34,993,45],{"class":44},[34,995,49],{"class":48},[34,997,52],{"class":40},[34,999,1000,1002,1005,1007],{"class":36,"line":55},[34,1001,343],{"class":342},[34,1003,1004],{"class":40}," { ref, onMounted, onUnmounted, computed } ",[34,1006,349],{"class":342},[34,1008,1009],{"class":116}," 'vue'\n",[34,1011,1012],{"class":36,"line":62},[34,1013,88],{"emptyLinePlaceholder":87},[34,1015,1016],{"class":36,"line":68},[34,1017,1018],{"class":58},"\u002F\u002F ── Renderless component: provides data via scoped slot, renders nothing itself ──\n",[34,1020,1021],{"class":36,"line":74},[34,1022,1023],{"class":58},"\u002F\u002F Parent has full control over the template — this component only provides state.\n",[34,1025,1026,1028,1031,1033,1036,1039,1042],{"class":36,"line":84},[34,1027,530],{"class":342},[34,1029,1030],{"class":533}," x",[34,1032,537],{"class":342},[34,1034,1035],{"class":48}," ref",[34,1037,1038],{"class":40},"(",[34,1040,1041],{"class":533},"0",[34,1043,1044],{"class":40},")\n",[34,1046,1047,1049,1052,1054,1056,1058,1060],{"class":36,"line":91},[34,1048,530],{"class":342},[34,1050,1051],{"class":533}," y",[34,1053,537],{"class":342},[34,1055,1035],{"class":48},[34,1057,1038],{"class":40},[34,1059,1041],{"class":533},[34,1061,1044],{"class":40},[34,1063,1064],{"class":36,"line":101},[34,1065,88],{"emptyLinePlaceholder":87},[34,1067,1068,1071,1074,1076,1079,1082,1084,1087,1089],{"class":36,"line":122},[34,1069,1070],{"class":342},"function",[34,1072,1073],{"class":48}," handler",[34,1075,1038],{"class":40},[34,1077,1078],{"class":548},"e",[34,1080,1081],{"class":40},") { x.value ",[34,1083,113],{"class":342},[34,1085,1086],{"class":40}," e.clientX; y.value ",[34,1088,113],{"class":342},[34,1090,1091],{"class":40}," e.clientY }\n",[34,1093,1094],{"class":36,"line":128},[34,1095,88],{"emptyLinePlaceholder":87},[34,1097,1098,1101,1104,1107,1110,1113,1115,1118],{"class":36,"line":146},[34,1099,1100],{"class":48},"onMounted",[34,1102,1103],{"class":40},"(() ",[34,1105,1106],{"class":342},"=>",[34,1108,1109],{"class":40}," window.",[34,1111,1112],{"class":48},"addEventListener",[34,1114,1038],{"class":40},[34,1116,1117],{"class":116},"'mousemove'",[34,1119,1120],{"class":40},", handler))\n",[34,1122,1123,1126,1128,1130,1132,1135,1137,1139],{"class":36,"line":169},[34,1124,1125],{"class":48},"onUnmounted",[34,1127,1103],{"class":40},[34,1129,1106],{"class":342},[34,1131,1109],{"class":40},[34,1133,1134],{"class":48},"removeEventListener",[34,1136,1038],{"class":40},[34,1138,1117],{"class":116},[34,1140,1120],{"class":40},[34,1142,1143],{"class":36,"line":179},[34,1144,88],{"emptyLinePlaceholder":87},[34,1146,1147],{"class":36,"line":184},[34,1148,1149],{"class":58},"\u002F\u002F ── Expose computed\u002Fstate to parent via default slot props ──\n",[34,1151,1152],{"class":36,"line":190},[34,1153,1154],{"class":58},"\u002F\u002F Parent destructures { x, y } in the slot template.\n",[34,1156,1157,1159,1161],{"class":36,"line":206},[34,1158,77],{"class":40},[34,1160,45],{"class":44},[34,1162,52],{"class":40},[34,1164,1165],{"class":36,"line":221},[34,1166,88],{"emptyLinePlaceholder":87},[34,1168,1169,1171,1173],{"class":36,"line":230},[34,1170,41],{"class":40},[34,1172,96],{"class":44},[34,1174,52],{"class":40},[34,1176,1177],{"class":36,"line":235},[34,1178,1179],{"class":58},"  \u003C!-- The slot receives x, y, and a distance computed -->\n",[34,1181,1182,1184,1186,1189,1191,1194,1197,1199,1202,1205,1207,1210,1212],{"class":36,"line":252},[34,1183,104],{"class":40},[34,1185,152],{"class":44},[34,1187,1188],{"class":48}," :x",[34,1190,113],{"class":40},[34,1192,1193],{"class":116},"\"x\"",[34,1195,1196],{"class":48}," :y",[34,1198,113],{"class":40},[34,1200,1201],{"class":116},"\"y\"",[34,1203,1204],{"class":48}," :distance",[34,1206,113],{"class":40},[34,1208,1209],{"class":116},"\"Math.sqrt(x**2 + y**2)\"",[34,1211,164],{"class":163},[34,1213,52],{"class":40},[34,1215,1216,1218,1220],{"class":36,"line":268},[34,1217,77],{"class":40},[34,1219,96],{"class":44},[34,1221,52],{"class":40},[20,1223,1225],{"filename":1224,"language":23},"RenderlessUsage.vue",[25,1226,1228],{"className":27,"code":1227,"language":23,"meta":29,"style":29},"\u003Ctemplate>\n  \u003C!-- ── v-slot (or #default) receives the slot props ── -->\n  \u003CMouseTracker v-slot=\"{ x, y, distance }\">\n    \u003Cdiv class=\"cursor-indicator\">\n      Position: {{ x }}, {{ y }} (distance from origin: {{ distance.toFixed(0) }}px)\n    \u003C\u002Fdiv>\n  \u003C\u002FMouseTracker>\n\n  \u003C!-- ── Equivalent: explicit default slot name ── -->\n  \u003CMouseTracker>\n    \u003Ctemplate #default=\"{ x, y }\">\n      \u003Cdiv>X: {{ x }}, Y: {{ y }}\u003C\u002Fdiv>\n    \u003C\u002Ftemplate>\n  \u003C\u002FMouseTracker>\n\u003C\u002Ftemplate>\n",[31,1229,1230,1238,1243,1264,1279,1284,1292,1300,1304,1309,1317,1339,1352,1360,1368],{"__ignoreMap":29},[34,1231,1232,1234,1236],{"class":36,"line":37},[34,1233,41],{"class":40},[34,1235,96],{"class":44},[34,1237,52],{"class":40},[34,1239,1240],{"class":36,"line":55},[34,1241,1242],{"class":58},"  \u003C!-- ── v-slot (or #default) receives the slot props ── -->\n",[34,1244,1245,1247,1250,1253,1255,1257,1260,1262],{"class":36,"line":62},[34,1246,104],{"class":40},[34,1248,1249],{"class":44},"MouseTracker",[34,1251,1252],{"class":48}," v-slot",[34,1254,113],{"class":40},[34,1256,720],{"class":116},[34,1258,1259],{"class":40},"{ x, y, distance }",[34,1261,720],{"class":116},[34,1263,52],{"class":40},[34,1265,1266,1268,1270,1272,1274,1277],{"class":36,"line":68},[34,1267,131],{"class":40},[34,1269,107],{"class":44},[34,1271,110],{"class":48},[34,1273,113],{"class":40},[34,1275,1276],{"class":116},"\"cursor-indicator\"",[34,1278,52],{"class":40},[34,1280,1281],{"class":36,"line":74},[34,1282,1283],{"class":40},"      Position: {{ x }}, {{ y }} (distance from origin: {{ distance.toFixed(0) }}px)\n",[34,1285,1286,1288,1290],{"class":36,"line":84},[34,1287,172],{"class":40},[34,1289,107],{"class":44},[34,1291,52],{"class":40},[34,1293,1294,1296,1298],{"class":36,"line":91},[34,1295,306],{"class":40},[34,1297,1249],{"class":44},[34,1299,52],{"class":40},[34,1301,1302],{"class":36,"line":101},[34,1303,88],{"emptyLinePlaceholder":87},[34,1305,1306],{"class":36,"line":122},[34,1307,1308],{"class":58},"  \u003C!-- ── Equivalent: explicit default slot name ── -->\n",[34,1310,1311,1313,1315],{"class":36,"line":128},[34,1312,104],{"class":40},[34,1314,1249],{"class":44},[34,1316,52],{"class":40},[34,1318,1319,1321,1323,1325,1328,1330,1332,1335,1337],{"class":36,"line":146},[34,1320,131],{"class":40},[34,1322,96],{"class":44},[34,1324,395],{"class":40},[34,1326,1327],{"class":48},"default",[34,1329,113],{"class":40},[34,1331,720],{"class":116},[34,1333,1334],{"class":40},"{ x, y }",[34,1336,720],{"class":116},[34,1338,52],{"class":40},[34,1340,1341,1343,1345,1348,1350],{"class":36,"line":169},[34,1342,149],{"class":40},[34,1344,107],{"class":44},[34,1346,1347],{"class":40},">X: {{ x }}, Y: {{ y }}\u003C\u002F",[34,1349,107],{"class":44},[34,1351,52],{"class":40},[34,1353,1354,1356,1358],{"class":36,"line":179},[34,1355,172],{"class":40},[34,1357,96],{"class":44},[34,1359,52],{"class":40},[34,1361,1362,1364,1366],{"class":36,"line":184},[34,1363,306],{"class":40},[34,1365,1249],{"class":44},[34,1367,52],{"class":40},[34,1369,1370,1372,1374],{"class":36,"line":190},[34,1371,77],{"class":40},[34,1373,96],{"class":44},[34,1375,52],{"class":40},[15,1377,1379],{"id":1378},"slot-props-with-dynamic-slots-v-slot-with-v-for","Slot Props with Dynamic Slots — v-slot with v-for",[20,1381,1383,1782],{"filename":1382,"language":23},"VirtualList.vue",[25,1384,1386],{"className":27,"code":1385,"language":23,"meta":29,"style":29},"\u003Cscript setup>\nimport { ref, computed } from 'vue'\n\nconst props = defineProps\u003C{\n  items: Array\u003C{ id: string; [key: string]: any }>\n  pageSize?: number\n}>()\n\n\u002F\u002F ── Virtual list: only renders visible items ────────────\n\u002F\u002F Slot props include: item, index, isVisible (for lazy rendering)\nconst scrollTop = ref(0)\nconst visibleRange = computed(() => {\n  const start = Math.floor(scrollTop.value \u002F 40)  \u002F\u002F 40px per row\n  const end = Math.min(start + (props.pageSize ?? 20), props.items.length)\n  return { start, end }\n})\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"virtual-list\" @scroll.passive=\"scrollTop = $event.target.scrollTop\" :style=\"{ height: items.length * 40 + 'px' }\">\n    \u003C!-- ── Scoped slot for each visible item: parent controls rendering ── -->\n    \u003Cdiv\n      v-for=\"item in items.slice(visibleRange.start, visibleRange.end)\"\n      :key=\"item.id\"\n      :style=\"{ transform: `translateY(${visibleRange.start * 40}px)` }\"\n    >\n      \u003Cslot\n        name=\"item\"\n        :item=\"item\"\n        :index=\"items.indexOf(item)\"\n      \u002F>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[31,1387,1388,1398,1409,1413,1425,1462,1473,1477,1481,1486,1491,1508,1527,1558,1595,1603,1608,1616,1620,1628,1659,1664,1671,1681,1691,1701,1707,1715,1726,1736,1747,1755,1764,1773],{"__ignoreMap":29},[34,1389,1390,1392,1394,1396],{"class":36,"line":37},[34,1391,41],{"class":40},[34,1393,45],{"class":44},[34,1395,49],{"class":48},[34,1397,52],{"class":40},[34,1399,1400,1402,1405,1407],{"class":36,"line":55},[34,1401,343],{"class":342},[34,1403,1404],{"class":40}," { ref, computed } ",[34,1406,349],{"class":342},[34,1408,1009],{"class":116},[34,1410,1411],{"class":36,"line":62},[34,1412,88],{"emptyLinePlaceholder":87},[34,1414,1415,1417,1419,1421,1423],{"class":36,"line":68},[34,1416,530],{"class":342},[34,1418,534],{"class":533},[34,1420,537],{"class":342},[34,1422,540],{"class":48},[34,1424,543],{"class":40},[34,1426,1427,1430,1432,1434,1436,1438,1440,1442,1445,1448,1450,1452,1455,1457,1460],{"class":36,"line":74},[34,1428,1429],{"class":548},"  items",[34,1431,552],{"class":342},[34,1433,555],{"class":48},[34,1435,558],{"class":40},[34,1437,561],{"class":548},[34,1439,552],{"class":342},[34,1441,577],{"class":533},[34,1443,1444],{"class":40},"; [",[34,1446,1447],{"class":548},"key",[34,1449,552],{"class":342},[34,1451,577],{"class":533},[34,1453,1454],{"class":40},"]",[34,1456,552],{"class":342},[34,1458,1459],{"class":533}," any",[34,1461,589],{"class":40},[34,1463,1464,1467,1470],{"class":36,"line":84},[34,1465,1466],{"class":548},"  pageSize",[34,1468,1469],{"class":342},"?:",[34,1471,1472],{"class":533}," number\n",[34,1474,1475],{"class":36,"line":91},[34,1476,594],{"class":40},[34,1478,1479],{"class":36,"line":101},[34,1480,88],{"emptyLinePlaceholder":87},[34,1482,1483],{"class":36,"line":122},[34,1484,1485],{"class":58},"\u002F\u002F ── Virtual list: only renders visible items ────────────\n",[34,1487,1488],{"class":36,"line":128},[34,1489,1490],{"class":58},"\u002F\u002F Slot props include: item, index, isVisible (for lazy rendering)\n",[34,1492,1493,1495,1498,1500,1502,1504,1506],{"class":36,"line":146},[34,1494,530],{"class":342},[34,1496,1497],{"class":533}," scrollTop",[34,1499,537],{"class":342},[34,1501,1035],{"class":48},[34,1503,1038],{"class":40},[34,1505,1041],{"class":533},[34,1507,1044],{"class":40},[34,1509,1510,1512,1515,1517,1520,1522,1524],{"class":36,"line":169},[34,1511,530],{"class":342},[34,1513,1514],{"class":533}," visibleRange",[34,1516,537],{"class":342},[34,1518,1519],{"class":48}," computed",[34,1521,1103],{"class":40},[34,1523,1106],{"class":342},[34,1525,1526],{"class":40}," {\n",[34,1528,1529,1532,1535,1537,1540,1543,1546,1549,1552,1555],{"class":36,"line":179},[34,1530,1531],{"class":342},"  const",[34,1533,1534],{"class":533}," start",[34,1536,537],{"class":342},[34,1538,1539],{"class":40}," Math.",[34,1541,1542],{"class":48},"floor",[34,1544,1545],{"class":40},"(scrollTop.value ",[34,1547,1548],{"class":342},"\u002F",[34,1550,1551],{"class":533}," 40",[34,1553,1554],{"class":40},")  ",[34,1556,1557],{"class":58},"\u002F\u002F 40px per row\n",[34,1559,1560,1562,1565,1567,1569,1572,1575,1578,1581,1584,1587,1590,1593],{"class":36,"line":184},[34,1561,1531],{"class":342},[34,1563,1564],{"class":533}," end",[34,1566,537],{"class":342},[34,1568,1539],{"class":40},[34,1570,1571],{"class":48},"min",[34,1573,1574],{"class":40},"(start ",[34,1576,1577],{"class":342},"+",[34,1579,1580],{"class":40}," (props.pageSize ",[34,1582,1583],{"class":342},"??",[34,1585,1586],{"class":533}," 20",[34,1588,1589],{"class":40},"), props.items.",[34,1591,1592],{"class":533},"length",[34,1594,1044],{"class":40},[34,1596,1597,1600],{"class":36,"line":190},[34,1598,1599],{"class":342},"  return",[34,1601,1602],{"class":40}," { start, end }\n",[34,1604,1605],{"class":36,"line":206},[34,1606,1607],{"class":40},"})\n",[34,1609,1610,1612,1614],{"class":36,"line":221},[34,1611,77],{"class":40},[34,1613,45],{"class":44},[34,1615,52],{"class":40},[34,1617,1618],{"class":36,"line":230},[34,1619,88],{"emptyLinePlaceholder":87},[34,1621,1622,1624,1626],{"class":36,"line":235},[34,1623,41],{"class":40},[34,1625,96],{"class":44},[34,1627,52],{"class":40},[34,1629,1630,1632,1634,1636,1638,1641,1644,1646,1649,1652,1654,1657],{"class":36,"line":252},[34,1631,104],{"class":40},[34,1633,107],{"class":44},[34,1635,110],{"class":48},[34,1637,113],{"class":40},[34,1639,1640],{"class":116},"\"virtual-list\"",[34,1642,1643],{"class":48}," @scroll.passive",[34,1645,113],{"class":40},[34,1647,1648],{"class":116},"\"scrollTop = $event.target.scrollTop\"",[34,1650,1651],{"class":48}," :style",[34,1653,113],{"class":40},[34,1655,1656],{"class":116},"\"{ height: items.length * 40 + 'px' }\"",[34,1658,52],{"class":40},[34,1660,1661],{"class":36,"line":268},[34,1662,1663],{"class":58},"    \u003C!-- ── Scoped slot for each visible item: parent controls rendering ── -->\n",[34,1665,1666,1668],{"class":36,"line":284},[34,1667,131],{"class":40},[34,1669,1670],{"class":44},"div\n",[34,1672,1673,1676,1678],{"class":36,"line":294},[34,1674,1675],{"class":48},"      v-for",[34,1677,113],{"class":40},[34,1679,1680],{"class":116},"\"item in items.slice(visibleRange.start, visibleRange.end)\"\n",[34,1682,1683,1686,1688],{"class":36,"line":303},[34,1684,1685],{"class":48},"      :key",[34,1687,113],{"class":40},[34,1689,1690],{"class":116},"\"item.id\"\n",[34,1692,1693,1696,1698],{"class":36,"line":313},[34,1694,1695],{"class":48},"      :style",[34,1697,113],{"class":40},[34,1699,1700],{"class":116},"\"{ transform: `translateY(${visibleRange.start * 40}px)` }\"\n",[34,1702,1704],{"class":36,"line":1703},26,[34,1705,1706],{"class":40},"    >\n",[34,1708,1710,1712],{"class":36,"line":1709},27,[34,1711,149],{"class":40},[34,1713,1714],{"class":44},"slot\n",[34,1716,1718,1721,1723],{"class":36,"line":1717},28,[34,1719,1720],{"class":48},"        name",[34,1722,113],{"class":40},[34,1724,1725],{"class":116},"\"item\"\n",[34,1727,1729,1732,1734],{"class":36,"line":1728},29,[34,1730,1731],{"class":48},"        :item",[34,1733,113],{"class":40},[34,1735,1725],{"class":116},[34,1737,1739,1742,1744],{"class":36,"line":1738},30,[34,1740,1741],{"class":48},"        :index",[34,1743,113],{"class":40},[34,1745,1746],{"class":116},"\"items.indexOf(item)\"\n",[34,1748,1750,1753],{"class":36,"line":1749},31,[34,1751,1752],{"class":163},"      \u002F",[34,1754,52],{"class":40},[34,1756,1758,1760,1762],{"class":36,"line":1757},32,[34,1759,172],{"class":40},[34,1761,107],{"class":44},[34,1763,52],{"class":40},[34,1765,1767,1769,1771],{"class":36,"line":1766},33,[34,1768,306],{"class":40},[34,1770,107],{"class":44},[34,1772,52],{"class":40},[34,1774,1776,1778,1780],{"class":36,"line":1775},34,[34,1777,77],{"class":40},[34,1779,96],{"class":44},[34,1781,52],{"class":40},[20,1783,1785],{"filename":1784,"language":23},"VirtualListUsage.vue",[25,1786,1788],{"className":27,"code":1787,"language":23,"meta":29,"style":29},"\u003Ctemplate>\n  \u003CVirtualList :items=\"products\" :page-size=\"50\">\n    \u003Ctemplate #item=\"{ item, index }\">\n      \u003Cdiv class=\"product-row\">\n        \u003Cspan>{{ index + 1 }}. {{ item.name }} — ${{ item.price }}\u003C\u002Fspan>\n      \u003C\u002Fdiv>\n    \u003C\u002Ftemplate>\n  \u003C\u002FVirtualList>\n\u003C\u002Ftemplate>\n",[31,1789,1790,1798,1835,1857,1872,1885,1893,1901,1909],{"__ignoreMap":29},[34,1791,1792,1794,1796],{"class":36,"line":37},[34,1793,41],{"class":40},[34,1795,96],{"class":44},[34,1797,52],{"class":40},[34,1799,1800,1802,1805,1807,1810,1812,1814,1817,1819,1821,1824,1826,1828,1831,1833],{"class":36,"line":55},[34,1801,104],{"class":40},[34,1803,1804],{"class":44},"VirtualList",[34,1806,827],{"class":40},[34,1808,1809],{"class":48},"items",[34,1811,113],{"class":40},[34,1813,720],{"class":116},[34,1815,1816],{"class":40},"products",[34,1818,720],{"class":116},[34,1820,827],{"class":40},[34,1822,1823],{"class":48},"page-size",[34,1825,113],{"class":40},[34,1827,720],{"class":116},[34,1829,1830],{"class":533},"50",[34,1832,720],{"class":116},[34,1834,52],{"class":40},[34,1836,1837,1839,1841,1843,1846,1848,1850,1853,1855],{"class":36,"line":62},[34,1838,131],{"class":40},[34,1840,96],{"class":44},[34,1842,395],{"class":40},[34,1844,1845],{"class":48},"item",[34,1847,113],{"class":40},[34,1849,720],{"class":116},[34,1851,1852],{"class":40},"{ item, index }",[34,1854,720],{"class":116},[34,1856,52],{"class":40},[34,1858,1859,1861,1863,1865,1867,1870],{"class":36,"line":68},[34,1860,149],{"class":40},[34,1862,107],{"class":44},[34,1864,110],{"class":48},[34,1866,113],{"class":40},[34,1868,1869],{"class":116},"\"product-row\"",[34,1871,52],{"class":40},[34,1873,1874,1876,1878,1881,1883],{"class":36,"line":74},[34,1875,271],{"class":40},[34,1877,34],{"class":44},[34,1879,1880],{"class":40},">{{ index + 1 }}. {{ item.name }} — ${{ item.price }}\u003C\u002F",[34,1882,34],{"class":44},[34,1884,52],{"class":40},[34,1886,1887,1889,1891],{"class":36,"line":84},[34,1888,287],{"class":40},[34,1890,107],{"class":44},[34,1892,52],{"class":40},[34,1894,1895,1897,1899],{"class":36,"line":91},[34,1896,172],{"class":40},[34,1898,96],{"class":44},[34,1900,52],{"class":40},[34,1902,1903,1905,1907],{"class":36,"line":101},[34,1904,306],{"class":40},[34,1906,1804],{"class":44},[34,1908,52],{"class":40},[34,1910,1911,1913,1915],{"class":36,"line":122},[34,1912,77],{"class":40},[34,1914,96],{"class":44},[34,1916,52],{"class":40},[15,1918,1920],{"id":1919},"slot-compilation-render-function-equivalents","Slot Compilation — Render Function Equivalents",[20,1922,1925],{"filename":1923,"language":1924},"slot-compilation.ts","typescript",[25,1926,1929],{"className":1927,"code":1928,"language":1924,"meta":29,"style":29},"language-typescript shiki shiki-themes github-light github-dark","import { h, defineComponent } from 'vue'\n\n\u002F\u002F ── Template slots compile to slots object in render functions ──\n\u002F\u002F The slots object: { default: () => VNode[], header: () => VNode[], ... }\n\n\u002F\u002F ── Template: ──────────────────────────────────────────\n\u002F\u002F \u003CCard>\n\u002F\u002F   \u003Ctemplate #header>\u003Ch2>Title\u003C\u002Fh2>\u003C\u002Ftemplate>\n\u002F\u002F   \u003Cp>Body\u003C\u002Fp>\n\u002F\u002F \u003C\u002FCard>\n\u002F\u002F\n\u002F\u002F ── Compiles to (render function equivalent): ──────────\nh(Card, null, {\n  header: () => h('h2', null, 'Title'),\n  default: () => h('p', null, 'Body'),\n})\n\n\u002F\u002F ── Scoped slot in render function: ─────────────────────\n\u002F\u002F Template: \u003CDataTable v-slot:row=\"{ row }\">{{ row.name }}\u003C\u002Ftemplate>\n\u002F\u002F Render fn: h(DataTable, null, { row: ({ row }) => h('td', null, row.name) })\n\u002F\u002F The slot prop is passed as a parameter to the render function.\n\n\u002F\u002F ── Accessing slots in \u003Cscript setup>: ─────────────────\nimport { useSlots } from 'vue'\nconst slots = useSlots()\n\u002F\u002F slots.default?.()       → VNode[] or undefined\n\u002F\u002F slots.header?.()        → VNode[] or undefined\n\u002F\u002F Useful for conditional rendering based on whether a slot was filled.\nif (slots.header) { \u002F* render header slot *\u002F }\n",[31,1930,1931,1942,1946,1951,1956,1960,1965,1970,1975,1980,1985,1990,1995,2009,2040,2067,2071,2075,2080,2085,2090,2095,2099,2104,2115,2130,2135,2140,2145],{"__ignoreMap":29},[34,1932,1933,1935,1938,1940],{"class":36,"line":37},[34,1934,343],{"class":342},[34,1936,1937],{"class":40}," { h, defineComponent } ",[34,1939,349],{"class":342},[34,1941,1009],{"class":116},[34,1943,1944],{"class":36,"line":55},[34,1945,88],{"emptyLinePlaceholder":87},[34,1947,1948],{"class":36,"line":62},[34,1949,1950],{"class":58},"\u002F\u002F ── Template slots compile to slots object in render functions ──\n",[34,1952,1953],{"class":36,"line":68},[34,1954,1955],{"class":58},"\u002F\u002F The slots object: { default: () => VNode[], header: () => VNode[], ... }\n",[34,1957,1958],{"class":36,"line":74},[34,1959,88],{"emptyLinePlaceholder":87},[34,1961,1962],{"class":36,"line":84},[34,1963,1964],{"class":58},"\u002F\u002F ── Template: ──────────────────────────────────────────\n",[34,1966,1967],{"class":36,"line":91},[34,1968,1969],{"class":58},"\u002F\u002F \u003CCard>\n",[34,1971,1972],{"class":36,"line":101},[34,1973,1974],{"class":58},"\u002F\u002F   \u003Ctemplate #header>\u003Ch2>Title\u003C\u002Fh2>\u003C\u002Ftemplate>\n",[34,1976,1977],{"class":36,"line":122},[34,1978,1979],{"class":58},"\u002F\u002F   \u003Cp>Body\u003C\u002Fp>\n",[34,1981,1982],{"class":36,"line":128},[34,1983,1984],{"class":58},"\u002F\u002F \u003C\u002FCard>\n",[34,1986,1987],{"class":36,"line":146},[34,1988,1989],{"class":58},"\u002F\u002F\n",[34,1991,1992],{"class":36,"line":169},[34,1993,1994],{"class":58},"\u002F\u002F ── Compiles to (render function equivalent): ──────────\n",[34,1996,1997,2000,2003,2006],{"class":36,"line":179},[34,1998,1999],{"class":48},"h",[34,2001,2002],{"class":40},"(Card, ",[34,2004,2005],{"class":533},"null",[34,2007,2008],{"class":40},", {\n",[34,2010,2011,2014,2017,2019,2022,2024,2027,2030,2032,2034,2037],{"class":36,"line":184},[34,2012,2013],{"class":48},"  header",[34,2015,2016],{"class":40},": () ",[34,2018,1106],{"class":342},[34,2020,2021],{"class":48}," h",[34,2023,1038],{"class":40},[34,2025,2026],{"class":116},"'h2'",[34,2028,2029],{"class":40},", ",[34,2031,2005],{"class":533},[34,2033,2029],{"class":40},[34,2035,2036],{"class":116},"'Title'",[34,2038,2039],{"class":40},"),\n",[34,2041,2042,2045,2047,2049,2051,2053,2056,2058,2060,2062,2065],{"class":36,"line":190},[34,2043,2044],{"class":48},"  default",[34,2046,2016],{"class":40},[34,2048,1106],{"class":342},[34,2050,2021],{"class":48},[34,2052,1038],{"class":40},[34,2054,2055],{"class":116},"'p'",[34,2057,2029],{"class":40},[34,2059,2005],{"class":533},[34,2061,2029],{"class":40},[34,2063,2064],{"class":116},"'Body'",[34,2066,2039],{"class":40},[34,2068,2069],{"class":36,"line":206},[34,2070,1607],{"class":40},[34,2072,2073],{"class":36,"line":221},[34,2074,88],{"emptyLinePlaceholder":87},[34,2076,2077],{"class":36,"line":230},[34,2078,2079],{"class":58},"\u002F\u002F ── Scoped slot in render function: ─────────────────────\n",[34,2081,2082],{"class":36,"line":235},[34,2083,2084],{"class":58},"\u002F\u002F Template: \u003CDataTable v-slot:row=\"{ row }\">{{ row.name }}\u003C\u002Ftemplate>\n",[34,2086,2087],{"class":36,"line":252},[34,2088,2089],{"class":58},"\u002F\u002F Render fn: h(DataTable, null, { row: ({ row }) => h('td', null, row.name) })\n",[34,2091,2092],{"class":36,"line":268},[34,2093,2094],{"class":58},"\u002F\u002F The slot prop is passed as a parameter to the render function.\n",[34,2096,2097],{"class":36,"line":284},[34,2098,88],{"emptyLinePlaceholder":87},[34,2100,2101],{"class":36,"line":294},[34,2102,2103],{"class":58},"\u002F\u002F ── Accessing slots in \u003Cscript setup>: ─────────────────\n",[34,2105,2106,2108,2111,2113],{"class":36,"line":303},[34,2107,343],{"class":342},[34,2109,2110],{"class":40}," { useSlots } ",[34,2112,349],{"class":342},[34,2114,1009],{"class":116},[34,2116,2117,2119,2122,2124,2127],{"class":36,"line":313},[34,2118,530],{"class":342},[34,2120,2121],{"class":533}," slots",[34,2123,537],{"class":342},[34,2125,2126],{"class":48}," useSlots",[34,2128,2129],{"class":40},"()\n",[34,2131,2132],{"class":36,"line":1703},[34,2133,2134],{"class":58},"\u002F\u002F slots.default?.()       → VNode[] or undefined\n",[34,2136,2137],{"class":36,"line":1709},[34,2138,2139],{"class":58},"\u002F\u002F slots.header?.()        → VNode[] or undefined\n",[34,2141,2142],{"class":36,"line":1717},[34,2143,2144],{"class":58},"\u002F\u002F Useful for conditional rendering based on whether a slot was filled.\n",[34,2146,2147,2150,2153,2156],{"class":36,"line":1728},[34,2148,2149],{"class":342},"if",[34,2151,2152],{"class":40}," (slots.header) { ",[34,2154,2155],{"class":58},"\u002F* render header slot *\u002F",[34,2157,2158],{"class":40}," }\n",[15,2160,2162],{"id":2161},"dynamic-slot-names","Dynamic Slot Names",[20,2164,2166,2367,2576,2580,2683,2687,2815,2819,2826],{"filename":2165,"language":23},"DynamicSlots.vue",[25,2167,2169],{"className":27,"code":2168,"language":23,"meta":29,"style":29},"\u003Cscript setup>\nimport { ref, computed } from 'vue'\n\n\u002F\u002F ── Dynamic slot name: slot name can be an expression ──\nconst currentSlot = ref('header')\n\n\u002F\u002F The slot to render is determined at runtime\nconst slots = {\n  header: 'Header Content',\n  body: 'Body Content',\n  footer: 'Footer Content',\n}\n\nconst activeContent = computed(() => slots[currentSlot.value])\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003C!-- ── Dynamic slot binding: #[expression] ── -->\n  \u003CSlotRenderer>\n    \u003Ctemplate #[currentSlot]>\n      {{ activeContent }}\n    \u003C\u002Ftemplate>\n  \u003C\u002FSlotRenderer>\n\u003C\u002Ftemplate>\n",[31,2170,2171,2181,2191,2195,2200,2218,2222,2227,2237,2248,2258,2268,2273,2277,2295,2303,2307,2315,2320,2329,2338,2343,2351,2359],{"__ignoreMap":29},[34,2172,2173,2175,2177,2179],{"class":36,"line":37},[34,2174,41],{"class":40},[34,2176,45],{"class":44},[34,2178,49],{"class":48},[34,2180,52],{"class":40},[34,2182,2183,2185,2187,2189],{"class":36,"line":55},[34,2184,343],{"class":342},[34,2186,1404],{"class":40},[34,2188,349],{"class":342},[34,2190,1009],{"class":116},[34,2192,2193],{"class":36,"line":62},[34,2194,88],{"emptyLinePlaceholder":87},[34,2196,2197],{"class":36,"line":68},[34,2198,2199],{"class":58},"\u002F\u002F ── Dynamic slot name: slot name can be an expression ──\n",[34,2201,2202,2204,2207,2209,2211,2213,2216],{"class":36,"line":74},[34,2203,530],{"class":342},[34,2205,2206],{"class":533}," currentSlot",[34,2208,537],{"class":342},[34,2210,1035],{"class":48},[34,2212,1038],{"class":40},[34,2214,2215],{"class":116},"'header'",[34,2217,1044],{"class":40},[34,2219,2220],{"class":36,"line":84},[34,2221,88],{"emptyLinePlaceholder":87},[34,2223,2224],{"class":36,"line":91},[34,2225,2226],{"class":58},"\u002F\u002F The slot to render is determined at runtime\n",[34,2228,2229,2231,2233,2235],{"class":36,"line":101},[34,2230,530],{"class":342},[34,2232,2121],{"class":533},[34,2234,537],{"class":342},[34,2236,1526],{"class":40},[34,2238,2239,2242,2245],{"class":36,"line":122},[34,2240,2241],{"class":40},"  header: ",[34,2243,2244],{"class":116},"'Header Content'",[34,2246,2247],{"class":40},",\n",[34,2249,2250,2253,2256],{"class":36,"line":128},[34,2251,2252],{"class":40},"  body: ",[34,2254,2255],{"class":116},"'Body Content'",[34,2257,2247],{"class":40},[34,2259,2260,2263,2266],{"class":36,"line":146},[34,2261,2262],{"class":40},"  footer: ",[34,2264,2265],{"class":116},"'Footer Content'",[34,2267,2247],{"class":40},[34,2269,2270],{"class":36,"line":169},[34,2271,2272],{"class":40},"}\n",[34,2274,2275],{"class":36,"line":179},[34,2276,88],{"emptyLinePlaceholder":87},[34,2278,2279,2281,2284,2286,2288,2290,2292],{"class":36,"line":184},[34,2280,530],{"class":342},[34,2282,2283],{"class":533}," activeContent",[34,2285,537],{"class":342},[34,2287,1519],{"class":48},[34,2289,1103],{"class":40},[34,2291,1106],{"class":342},[34,2293,2294],{"class":40}," slots[currentSlot.value])\n",[34,2296,2297,2299,2301],{"class":36,"line":190},[34,2298,77],{"class":40},[34,2300,45],{"class":44},[34,2302,52],{"class":40},[34,2304,2305],{"class":36,"line":206},[34,2306,88],{"emptyLinePlaceholder":87},[34,2308,2309,2311,2313],{"class":36,"line":221},[34,2310,41],{"class":40},[34,2312,96],{"class":44},[34,2314,52],{"class":40},[34,2316,2317],{"class":36,"line":230},[34,2318,2319],{"class":58},"  \u003C!-- ── Dynamic slot binding: #[expression] ── -->\n",[34,2321,2322,2324,2327],{"class":36,"line":235},[34,2323,104],{"class":40},[34,2325,2326],{"class":44},"SlotRenderer",[34,2328,52],{"class":40},[34,2330,2331,2333,2335],{"class":36,"line":252},[34,2332,131],{"class":40},[34,2334,96],{"class":44},[34,2336,2337],{"class":40}," #[currentSlot]>\n",[34,2339,2340],{"class":36,"line":268},[34,2341,2342],{"class":40},"      {{ activeContent }}\n",[34,2344,2345,2347,2349],{"class":36,"line":284},[34,2346,172],{"class":40},[34,2348,96],{"class":44},[34,2350,52],{"class":40},[34,2352,2353,2355,2357],{"class":36,"line":294},[34,2354,306],{"class":40},[34,2356,2326],{"class":44},[34,2358,52],{"class":40},[34,2360,2361,2363,2365],{"class":36,"line":303},[34,2362,77],{"class":40},[34,2364,96],{"class":44},[34,2366,52],{"class":40},[20,2368,2370],{"filename":2369,"language":23},"ConditionalSlots.vue",[25,2371,2373],{"className":27,"code":2372,"language":23,"meta":29,"style":29},"\u003Cscript setup>\nimport { useSlots } from 'vue'\nconst slots = useSlots()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003C!-- ── Check if a slot was provided before rendering its container ── -->\n  \u003Cheader v-if=\"slots.header\" class=\"header\">\n    \u003Cslot name=\"header\" \u002F>\n  \u003C\u002Fheader>\n\n  \u003Cmain>\n    \u003Cslot \u002F>\n  \u003C\u002Fmain>\n\n  \u003Cfooter v-if=\"slots.footer\" class=\"footer\">\n    \u003Cslot name=\"footer\" \u002F>\n  \u003C\u002Ffooter>\n  \u003C!-- ── If parent doesn't fill #header, the \u003Cheader> element isn't rendered ── -->\n  \u003C!-- Avoids empty wrapper elements when slots are unfilled. -->\n\u003C\u002Ftemplate>\n",[31,2374,2375,2385,2395,2407,2415,2419,2427,2432,2454,2470,2478,2482,2491,2501,2509,2513,2534,2550,2558,2563,2568],{"__ignoreMap":29},[34,2376,2377,2379,2381,2383],{"class":36,"line":37},[34,2378,41],{"class":40},[34,2380,45],{"class":44},[34,2382,49],{"class":48},[34,2384,52],{"class":40},[34,2386,2387,2389,2391,2393],{"class":36,"line":55},[34,2388,343],{"class":342},[34,2390,2110],{"class":40},[34,2392,349],{"class":342},[34,2394,1009],{"class":116},[34,2396,2397,2399,2401,2403,2405],{"class":36,"line":62},[34,2398,530],{"class":342},[34,2400,2121],{"class":533},[34,2402,537],{"class":342},[34,2404,2126],{"class":48},[34,2406,2129],{"class":40},[34,2408,2409,2411,2413],{"class":36,"line":68},[34,2410,77],{"class":40},[34,2412,45],{"class":44},[34,2414,52],{"class":40},[34,2416,2417],{"class":36,"line":74},[34,2418,88],{"emptyLinePlaceholder":87},[34,2420,2421,2423,2425],{"class":36,"line":84},[34,2422,41],{"class":40},[34,2424,96],{"class":44},[34,2426,52],{"class":40},[34,2428,2429],{"class":36,"line":91},[34,2430,2431],{"class":58},"  \u003C!-- ── Check if a slot was provided before rendering its container ── -->\n",[34,2433,2434,2436,2438,2441,2443,2446,2448,2450,2452],{"class":36,"line":101},[34,2435,104],{"class":40},[34,2437,134],{"class":44},[34,2439,2440],{"class":48}," v-if",[34,2442,113],{"class":40},[34,2444,2445],{"class":116},"\"slots.header\"",[34,2447,110],{"class":48},[34,2449,113],{"class":40},[34,2451,160],{"class":116},[34,2453,52],{"class":40},[34,2455,2456,2458,2460,2462,2464,2466,2468],{"class":36,"line":122},[34,2457,131],{"class":40},[34,2459,152],{"class":44},[34,2461,155],{"class":48},[34,2463,113],{"class":40},[34,2465,160],{"class":116},[34,2467,164],{"class":163},[34,2469,52],{"class":40},[34,2471,2472,2474,2476],{"class":36,"line":128},[34,2473,306],{"class":40},[34,2475,134],{"class":44},[34,2477,52],{"class":40},[34,2479,2480],{"class":36,"line":146},[34,2481,88],{"emptyLinePlaceholder":87},[34,2483,2484,2486,2489],{"class":36,"line":169},[34,2485,104],{"class":40},[34,2487,2488],{"class":44},"main",[34,2490,52],{"class":40},[34,2492,2493,2495,2497,2499],{"class":36,"line":179},[34,2494,131],{"class":40},[34,2496,152],{"class":44},[34,2498,164],{"class":163},[34,2500,52],{"class":40},[34,2502,2503,2505,2507],{"class":36,"line":184},[34,2504,306],{"class":40},[34,2506,2488],{"class":44},[34,2508,52],{"class":40},[34,2510,2511],{"class":36,"line":190},[34,2512,88],{"emptyLinePlaceholder":87},[34,2514,2515,2517,2519,2521,2523,2526,2528,2530,2532],{"class":36,"line":206},[34,2516,104],{"class":40},[34,2518,240],{"class":44},[34,2520,2440],{"class":48},[34,2522,113],{"class":40},[34,2524,2525],{"class":116},"\"slots.footer\"",[34,2527,110],{"class":48},[34,2529,113],{"class":40},[34,2531,263],{"class":116},[34,2533,52],{"class":40},[34,2535,2536,2538,2540,2542,2544,2546,2548],{"class":36,"line":221},[34,2537,131],{"class":40},[34,2539,152],{"class":44},[34,2541,155],{"class":48},[34,2543,113],{"class":40},[34,2545,263],{"class":116},[34,2547,164],{"class":163},[34,2549,52],{"class":40},[34,2551,2552,2554,2556],{"class":36,"line":230},[34,2553,306],{"class":40},[34,2555,240],{"class":44},[34,2557,52],{"class":40},[34,2559,2560],{"class":36,"line":235},[34,2561,2562],{"class":58},"  \u003C!-- ── If parent doesn't fill #header, the \u003Cheader> element isn't rendered ── -->\n",[34,2564,2565],{"class":36,"line":252},[34,2566,2567],{"class":58},"  \u003C!-- Avoids empty wrapper elements when slots are unfilled. -->\n",[34,2569,2570,2572,2574],{"class":36,"line":268},[34,2571,77],{"class":40},[34,2573,96],{"class":44},[34,2575,52],{"class":40},[15,2577,2579],{"id":2578},"tips-tricks","💡 Tips & Tricks",[20,2581,2583],{"filename":2582,"language":1924},"tips.ts",[25,2584,2586],{"className":1927,"code":2585,"language":1924,"meta":29,"style":29},"import { useSlots } from 'vue'\n\n\u002F\u002F ── 1. useSlots() — check if a slot was provided ──\n\u002F\u002F const slots = useSlots()\n\u002F\u002F v-if=\"slots.header\" — only render the container if the slot has content\n\n\u002F\u002F ── 2. Slot prop defaults — parent can provide defaults in destructure ──\n\u002F\u002F \u003Ctemplate #row=\"{ row, index = 0 }\">{{ index }}\u003C\u002Ftemplate>\n\n\u002F\u002F ── 3. Fallback content in child slot definition ──\n\u002F\u002F \u003Cslot>Default text shown if parent doesn't fill this slot\u003C\u002Fslot>\n\n\u002F\u002F ── 4. Renderless components are powerful but composable are often simpler ──\n\u002F\u002F Before building a renderless component, consider: can a composable do the job?\n\u002F\u002F Composables are lighter (no component instance overhead) and more composable.\n\u002F\u002F Renderless components shine when you need slot-based template injection.\n\n\u002F\u002F ── 5. Named slot shorthand: #name instead of v-slot:name ──\n\u002F\u002F #default is valid but unnecessary — unnamed \u003Ctemplate> is default.\n",[31,2587,2588,2598,2602,2607,2612,2617,2621,2626,2631,2635,2640,2645,2649,2654,2659,2664,2669,2673,2678],{"__ignoreMap":29},[34,2589,2590,2592,2594,2596],{"class":36,"line":37},[34,2591,343],{"class":342},[34,2593,2110],{"class":40},[34,2595,349],{"class":342},[34,2597,1009],{"class":116},[34,2599,2600],{"class":36,"line":55},[34,2601,88],{"emptyLinePlaceholder":87},[34,2603,2604],{"class":36,"line":62},[34,2605,2606],{"class":58},"\u002F\u002F ── 1. useSlots() — check if a slot was provided ──\n",[34,2608,2609],{"class":36,"line":68},[34,2610,2611],{"class":58},"\u002F\u002F const slots = useSlots()\n",[34,2613,2614],{"class":36,"line":74},[34,2615,2616],{"class":58},"\u002F\u002F v-if=\"slots.header\" — only render the container if the slot has content\n",[34,2618,2619],{"class":36,"line":84},[34,2620,88],{"emptyLinePlaceholder":87},[34,2622,2623],{"class":36,"line":91},[34,2624,2625],{"class":58},"\u002F\u002F ── 2. Slot prop defaults — parent can provide defaults in destructure ──\n",[34,2627,2628],{"class":36,"line":101},[34,2629,2630],{"class":58},"\u002F\u002F \u003Ctemplate #row=\"{ row, index = 0 }\">{{ index }}\u003C\u002Ftemplate>\n",[34,2632,2633],{"class":36,"line":122},[34,2634,88],{"emptyLinePlaceholder":87},[34,2636,2637],{"class":36,"line":128},[34,2638,2639],{"class":58},"\u002F\u002F ── 3. Fallback content in child slot definition ──\n",[34,2641,2642],{"class":36,"line":146},[34,2643,2644],{"class":58},"\u002F\u002F \u003Cslot>Default text shown if parent doesn't fill this slot\u003C\u002Fslot>\n",[34,2646,2647],{"class":36,"line":169},[34,2648,88],{"emptyLinePlaceholder":87},[34,2650,2651],{"class":36,"line":179},[34,2652,2653],{"class":58},"\u002F\u002F ── 4. Renderless components are powerful but composable are often simpler ──\n",[34,2655,2656],{"class":36,"line":184},[34,2657,2658],{"class":58},"\u002F\u002F Before building a renderless component, consider: can a composable do the job?\n",[34,2660,2661],{"class":36,"line":190},[34,2662,2663],{"class":58},"\u002F\u002F Composables are lighter (no component instance overhead) and more composable.\n",[34,2665,2666],{"class":36,"line":206},[34,2667,2668],{"class":58},"\u002F\u002F Renderless components shine when you need slot-based template injection.\n",[34,2670,2671],{"class":36,"line":221},[34,2672,88],{"emptyLinePlaceholder":87},[34,2674,2675],{"class":36,"line":230},[34,2676,2677],{"class":58},"\u002F\u002F ── 5. Named slot shorthand: #name instead of v-slot:name ──\n",[34,2679,2680],{"class":36,"line":235},[34,2681,2682],{"class":58},"\u002F\u002F #default is valid but unnecessary — unnamed \u003Ctemplate> is default.\n",[15,2684,2686],{"id":2685},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[20,2688,2690],{"filename":2689,"language":1924},"edge-cases.ts",[25,2691,2693],{"className":1927,"code":2692,"language":1924,"meta":29,"style":29},"\u002F\u002F ── 1. Slot props are not reactive across re-renders ──\n\u002F\u002F Each render, the slot function is called with fresh props.\n\u002F\u002F If the parent uses a ref inside the slot, it updates on parent re-render.\n\n\u002F\u002F ── 2. Default slot content is NOT shown if parent passes empty content ──\n\u002F\u002F \u003CCard>\u003Ctemplate #header>\u003C\u002Ftemplate>\u003C\u002FCard>\n\u002F\u002F The header slot is \"filled\" (with empty content) — fallback is NOT shown.\n\u002F\u002F Fallback only appears when the slot is entirely absent.\n\n\u002F\u002F ── 3. Slot content is compiled in the PARENT's scope ──\n\u002F\u002F \u003CCard>\u003Cslot name=\"header\">{{ parentVar }}\u003C\u002Fslot>\u003C\u002FCard>\n\u002F\u002F `parentVar` comes from the parent's setup, not the child's.\n\u002F\u002F Child can pass data via scoped slot props, but can't expose its own state directly.\n\n\u002F\u002F ── 4. v-slot can only be used on \u003Ctemplate> or component tags ──\n\u002F\u002F ❌ \u003Cdiv v-slot=\"{ item }\"> — invalid\n\u002F\u002F ✅ \u003Ctemplate v-slot=\"{ item }\"> or \u003CMyComp v-slot=\"{ item }\"> — valid\n\n\u002F\u002F ── 5. Scoped slot destructuring loses reactivity if you extract a ref ──\n\u002F\u002F \u003Ctemplate #row=\"{ row }\">{{ row.name }}\u003C\u002Ftemplate>\n\u002F\u002F `row` is the slot prop (an object). Accessing row.name is reactive.\n\u002F\u002F But: const { row } = useSlots() — row is a plain value, not a ref.\n\n\u002F\u002F ── 6. Slot names are case-insensitive ──\n\u002F\u002F #header and #Header are the same slot. Use kebab-case for clarity.\n",[31,2694,2695,2700,2705,2710,2714,2719,2724,2729,2734,2738,2743,2748,2753,2758,2762,2767,2772,2777,2781,2786,2791,2796,2801,2805,2810],{"__ignoreMap":29},[34,2696,2697],{"class":36,"line":37},[34,2698,2699],{"class":58},"\u002F\u002F ── 1. Slot props are not reactive across re-renders ──\n",[34,2701,2702],{"class":36,"line":55},[34,2703,2704],{"class":58},"\u002F\u002F Each render, the slot function is called with fresh props.\n",[34,2706,2707],{"class":36,"line":62},[34,2708,2709],{"class":58},"\u002F\u002F If the parent uses a ref inside the slot, it updates on parent re-render.\n",[34,2711,2712],{"class":36,"line":68},[34,2713,88],{"emptyLinePlaceholder":87},[34,2715,2716],{"class":36,"line":74},[34,2717,2718],{"class":58},"\u002F\u002F ── 2. Default slot content is NOT shown if parent passes empty content ──\n",[34,2720,2721],{"class":36,"line":84},[34,2722,2723],{"class":58},"\u002F\u002F \u003CCard>\u003Ctemplate #header>\u003C\u002Ftemplate>\u003C\u002FCard>\n",[34,2725,2726],{"class":36,"line":91},[34,2727,2728],{"class":58},"\u002F\u002F The header slot is \"filled\" (with empty content) — fallback is NOT shown.\n",[34,2730,2731],{"class":36,"line":101},[34,2732,2733],{"class":58},"\u002F\u002F Fallback only appears when the slot is entirely absent.\n",[34,2735,2736],{"class":36,"line":122},[34,2737,88],{"emptyLinePlaceholder":87},[34,2739,2740],{"class":36,"line":128},[34,2741,2742],{"class":58},"\u002F\u002F ── 3. Slot content is compiled in the PARENT's scope ──\n",[34,2744,2745],{"class":36,"line":146},[34,2746,2747],{"class":58},"\u002F\u002F \u003CCard>\u003Cslot name=\"header\">{{ parentVar }}\u003C\u002Fslot>\u003C\u002FCard>\n",[34,2749,2750],{"class":36,"line":169},[34,2751,2752],{"class":58},"\u002F\u002F `parentVar` comes from the parent's setup, not the child's.\n",[34,2754,2755],{"class":36,"line":179},[34,2756,2757],{"class":58},"\u002F\u002F Child can pass data via scoped slot props, but can't expose its own state directly.\n",[34,2759,2760],{"class":36,"line":184},[34,2761,88],{"emptyLinePlaceholder":87},[34,2763,2764],{"class":36,"line":190},[34,2765,2766],{"class":58},"\u002F\u002F ── 4. v-slot can only be used on \u003Ctemplate> or component tags ──\n",[34,2768,2769],{"class":36,"line":206},[34,2770,2771],{"class":58},"\u002F\u002F ❌ \u003Cdiv v-slot=\"{ item }\"> — invalid\n",[34,2773,2774],{"class":36,"line":221},[34,2775,2776],{"class":58},"\u002F\u002F ✅ \u003Ctemplate v-slot=\"{ item }\"> or \u003CMyComp v-slot=\"{ item }\"> — valid\n",[34,2778,2779],{"class":36,"line":230},[34,2780,88],{"emptyLinePlaceholder":87},[34,2782,2783],{"class":36,"line":235},[34,2784,2785],{"class":58},"\u002F\u002F ── 5. Scoped slot destructuring loses reactivity if you extract a ref ──\n",[34,2787,2788],{"class":36,"line":252},[34,2789,2790],{"class":58},"\u002F\u002F \u003Ctemplate #row=\"{ row }\">{{ row.name }}\u003C\u002Ftemplate>\n",[34,2792,2793],{"class":36,"line":268},[34,2794,2795],{"class":58},"\u002F\u002F `row` is the slot prop (an object). Accessing row.name is reactive.\n",[34,2797,2798],{"class":36,"line":284},[34,2799,2800],{"class":58},"\u002F\u002F But: const { row } = useSlots() — row is a plain value, not a ref.\n",[34,2802,2803],{"class":36,"line":294},[34,2804,88],{"emptyLinePlaceholder":87},[34,2806,2807],{"class":36,"line":303},[34,2808,2809],{"class":58},"\u002F\u002F ── 6. Slot names are case-insensitive ──\n",[34,2811,2812],{"class":36,"line":313},[34,2813,2814],{"class":58},"\u002F\u002F #header and #Header are the same slot. Use kebab-case for clarity.\n",[15,2816,2818],{"id":2817},"spot-the-bug","🧠 Spot the Bug",[274,2820,2821,2822,2825],{},"A parent passes an empty ",[31,2823,2824],{},"\u003Ctemplate #header>"," and expects the child's fallback content to show.",[20,2827,2829,2909],{"filename":2828,"language":23},"SlotBug.vue",[25,2830,2832],{"className":27,"code":2831,"language":23,"meta":29,"style":29},"\u003C!-- Child: Card.vue -->\n\u003Ctemplate>\n  \u003Cheader>\n    \u003Cslot name=\"header\">\n      \u003Ch2>Default Header\u003C\u002Fh2>  \u003C!-- fallback content -->\n    \u003C\u002Fslot>\n  \u003C\u002Fheader>\n\u003C\u002Ftemplate>\n",[31,2833,2834,2839,2847,2855,2869,2885,2893,2901],{"__ignoreMap":29},[34,2835,2836],{"class":36,"line":37},[34,2837,2838],{"class":58},"\u003C!-- Child: Card.vue -->\n",[34,2840,2841,2843,2845],{"class":36,"line":55},[34,2842,41],{"class":40},[34,2844,96],{"class":44},[34,2846,52],{"class":40},[34,2848,2849,2851,2853],{"class":36,"line":62},[34,2850,104],{"class":40},[34,2852,134],{"class":44},[34,2854,52],{"class":40},[34,2856,2857,2859,2861,2863,2865,2867],{"class":36,"line":68},[34,2858,131],{"class":40},[34,2860,152],{"class":44},[34,2862,155],{"class":48},[34,2864,113],{"class":40},[34,2866,160],{"class":116},[34,2868,52],{"class":40},[34,2870,2871,2873,2875,2878,2880,2882],{"class":36,"line":74},[34,2872,149],{"class":40},[34,2874,15],{"class":44},[34,2876,2877],{"class":40},">Default Header\u003C\u002F",[34,2879,15],{"class":44},[34,2881,215],{"class":40},[34,2883,2884],{"class":58},"\u003C!-- fallback content -->\n",[34,2886,2887,2889,2891],{"class":36,"line":84},[34,2888,172],{"class":40},[34,2890,152],{"class":44},[34,2892,52],{"class":40},[34,2894,2895,2897,2899],{"class":36,"line":91},[34,2896,306],{"class":40},[34,2898,134],{"class":44},[34,2900,52],{"class":40},[34,2902,2903,2905,2907],{"class":36,"line":101},[34,2904,77],{"class":40},[34,2906,96],{"class":44},[34,2908,52],{"class":40},[20,2910,2912],{"filename":2911,"language":23},"SlotBugParent.vue",[25,2913,2915],{"className":27,"code":2914,"language":23,"meta":29,"style":29},"\u003Ctemplate>\n  \u003CCard>\n    \u003Ctemplate #header>\u003C\u002Ftemplate>  \u003C!-- empty slot content -->\n  \u003C\u002FCard>\n\u003C\u002Ftemplate>\n",[31,2916,2917,2925,2933,2953,2961],{"__ignoreMap":29},[34,2918,2919,2921,2923],{"class":36,"line":37},[34,2920,41],{"class":40},[34,2922,96],{"class":44},[34,2924,52],{"class":40},[34,2926,2927,2929,2931],{"class":36,"line":55},[34,2928,104],{"class":40},[34,2930,379],{"class":44},[34,2932,52],{"class":40},[34,2934,2935,2937,2939,2941,2943,2946,2948,2950],{"class":36,"line":62},[34,2936,131],{"class":40},[34,2938,96],{"class":44},[34,2940,395],{"class":40},[34,2942,134],{"class":48},[34,2944,2945],{"class":40},">\u003C\u002F",[34,2947,96],{"class":44},[34,2949,215],{"class":40},[34,2951,2952],{"class":58},"\u003C!-- empty slot content -->\n",[34,2954,2955,2957,2959],{"class":36,"line":68},[34,2956,306],{"class":40},[34,2958,379],{"class":44},[34,2960,52],{"class":40},[34,2962,2963,2965,2967],{"class":36,"line":74},[34,2964,77],{"class":40},[34,2966,96],{"class":44},[34,2968,52],{"class":40},[2970,2971,2972,2976,2988,2997,3184],"details",{},[2973,2974,2975],"summary",{},"Answer",[274,2977,2978,2979,2983,2984,2987],{},"The fallback content (\"Default Header\") is only shown when the slot is ",[2980,2981,2982],"strong",{},"completely absent"," from the parent. Passing ",[31,2985,2986],{},"\u003Ctemplate #header>\u003C\u002Ftemplate>"," fills the slot with empty content — the slot is \"provided\" (just with nothing inside), so the fallback is skipped.",[274,2989,2990,2993,2994,552],{},[2980,2991,2992],{},"Fix"," — either omit the slot entirely (let it be absent), or conditionally render based on ",[31,2995,2996],{},"useSlots()",[20,2998,3000],{"filename":2999,"language":23},"SlotFixed.vue",[25,3001,3003],{"className":27,"code":3002,"language":23,"meta":29,"style":29},"\u003C!-- Option 1: Don't pass the slot at all -->\n\u003CCard \u002F>  \u003C!-- #header slot absent → fallback shows -->\n\n\u003C!-- Option 2: Child checks if slot has meaningful content -->\n\u003Cscript setup>\nimport { useSlots } from 'vue'\nconst slots = useSlots()\nconst hasHeader = computed(() => slots.header && slots.header().length > 0)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cheader>\n    \u003Cslot name=\"header\" v-if=\"hasHeader\" \u002F>\n    \u003Ch2 v-else>Default Header\u003C\u002Fh2>\n  \u003C\u002Fheader>\n\u003C\u002Ftemplate>\n",[31,3004,3005,3010,3022,3026,3031,3041,3051,3063,3102,3110,3114,3122,3130,3153,3168,3176],{"__ignoreMap":29},[34,3006,3007],{"class":36,"line":37},[34,3008,3009],{"class":58},"\u003C!-- Option 1: Don't pass the slot at all -->\n",[34,3011,3012,3014,3016,3019],{"class":36,"line":55},[34,3013,41],{"class":40},[34,3015,379],{"class":44},[34,3017,3018],{"class":40}," \u002F>  ",[34,3020,3021],{"class":58},"\u003C!-- #header slot absent → fallback shows -->\n",[34,3023,3024],{"class":36,"line":62},[34,3025,88],{"emptyLinePlaceholder":87},[34,3027,3028],{"class":36,"line":68},[34,3029,3030],{"class":58},"\u003C!-- Option 2: Child checks if slot has meaningful content -->\n",[34,3032,3033,3035,3037,3039],{"class":36,"line":74},[34,3034,41],{"class":40},[34,3036,45],{"class":44},[34,3038,49],{"class":48},[34,3040,52],{"class":40},[34,3042,3043,3045,3047,3049],{"class":36,"line":84},[34,3044,343],{"class":342},[34,3046,2110],{"class":40},[34,3048,349],{"class":342},[34,3050,1009],{"class":116},[34,3052,3053,3055,3057,3059,3061],{"class":36,"line":91},[34,3054,530],{"class":342},[34,3056,2121],{"class":533},[34,3058,537],{"class":342},[34,3060,2126],{"class":48},[34,3062,2129],{"class":40},[34,3064,3065,3067,3070,3072,3074,3076,3078,3081,3084,3087,3089,3092,3094,3097,3100],{"class":36,"line":101},[34,3066,530],{"class":342},[34,3068,3069],{"class":533}," hasHeader",[34,3071,537],{"class":342},[34,3073,1519],{"class":48},[34,3075,1103],{"class":40},[34,3077,1106],{"class":342},[34,3079,3080],{"class":40}," slots.header ",[34,3082,3083],{"class":342},"&&",[34,3085,3086],{"class":40}," slots.",[34,3088,134],{"class":48},[34,3090,3091],{"class":40},"().",[34,3093,1592],{"class":533},[34,3095,3096],{"class":342}," >",[34,3098,3099],{"class":533}," 0",[34,3101,1044],{"class":40},[34,3103,3104,3106,3108],{"class":36,"line":122},[34,3105,77],{"class":40},[34,3107,45],{"class":44},[34,3109,52],{"class":40},[34,3111,3112],{"class":36,"line":128},[34,3113,88],{"emptyLinePlaceholder":87},[34,3115,3116,3118,3120],{"class":36,"line":146},[34,3117,41],{"class":40},[34,3119,96],{"class":44},[34,3121,52],{"class":40},[34,3123,3124,3126,3128],{"class":36,"line":169},[34,3125,104],{"class":40},[34,3127,134],{"class":44},[34,3129,52],{"class":40},[34,3131,3132,3134,3136,3138,3140,3142,3144,3146,3149,3151],{"class":36,"line":179},[34,3133,131],{"class":40},[34,3135,152],{"class":44},[34,3137,155],{"class":48},[34,3139,113],{"class":40},[34,3141,160],{"class":116},[34,3143,2440],{"class":48},[34,3145,113],{"class":40},[34,3147,3148],{"class":116},"\"hasHeader\"",[34,3150,164],{"class":163},[34,3152,52],{"class":40},[34,3154,3155,3157,3159,3162,3164,3166],{"class":36,"line":184},[34,3156,131],{"class":40},[34,3158,15],{"class":44},[34,3160,3161],{"class":48}," v-else",[34,3163,2877],{"class":40},[34,3165,15],{"class":44},[34,3167,52],{"class":40},[34,3169,3170,3172,3174],{"class":36,"line":190},[34,3171,306],{"class":40},[34,3173,134],{"class":44},[34,3175,52],{"class":40},[34,3177,3178,3180,3182],{"class":36,"line":206},[34,3179,77],{"class":40},[34,3181,96],{"class":44},[34,3183,52],{"class":40},[274,3185,3186,3189,3190,3194,3195,3198,3199,3202],{},[2980,3187,3188],{},"The lesson",": slot fallback content appears only when the slot is ",[3191,3192,3193],"em",{},"absent",", not when it's ",[3191,3196,3197],{},"empty",". Passing an empty ",[31,3200,3201],{},"\u003Ctemplate #name>\u003C\u002Ftemplate>"," still counts as \"provided.\"",[3204,3205,3206],"style",{},"html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sk71V, html code.shiki .sk71V{--shiki-default:#22863A;--shiki-github-dark:#85E89D}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sMKGj, html code.shiki .sMKGj{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-github-dark:#FDAEB7;--shiki-github-dark-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":29,"searchDepth":55,"depth":55,"links":3208},[3209,3210,3211,3212,3213,3214,3215,3216,3217],{"id":17,"depth":55,"text":18},{"id":506,"depth":55,"text":507},{"id":978,"depth":55,"text":979},{"id":1378,"depth":55,"text":1379},{"id":1919,"depth":55,"text":1920},{"id":2161,"depth":55,"text":2162},{"id":2578,"depth":55,"text":2579},{"id":2685,"depth":55,"text":2686},{"id":2817,"depth":55,"text":2818},"Default and named slots, scoped slot data passing, renderless component patterns via slots, slot prop destructuring, fallback content, and slot compilation to render functions.","md",{},"\u002Fvue\u002F13-slots-and-scoped-slots",{"title":5,"description":3218},"vue\u002F13-slots-and-scoped-slots","a4I0A9DWDpR4vEQbH8JNjmk862RQXw30AtLdo-Snv0s",1789924655649]