[{"data":1,"prerenderedAt":982},["ShallowReactive",2],{"page-\u002Fvue\u002Fcomposables":3,"pieces-vue":940,"autour-\u002Fvue\u002Fcomposables":965,"prerequis-\u002Fvue\u002Fcomposables":969,"plan-vue":971},{"id":4,"title":5,"body":6,"description":911,"extension":912,"ligne":295,"meta":913,"motsCles":914,"navigation":98,"niveau":918,"path":919,"prerequis":920,"ressources":922,"seo":931,"sources":932,"stem":938,"__hash__":939},"docs\u002Fvue\u002F06.composables.md","Les composables",{"type":7,"value":8,"toc":900},"minimark",[9,14,32,36,40,59,63,275,286,290,469,476,480,483,528,539,549,553,562,565,569,572,743,746,841,854,858,861,864,868,896],[10,11,13],"h2",{"id":12},"ce-que-tu-vas-apprendre","Ce que tu vas apprendre",[15,16,17,21,29],"ul",{},[18,19,20],"li",{},"Ce qu'est un composable et pourquoi en écrire.",[18,22,23,24,28],{},"Extraire une logique réactive dans une fonction ",[25,26,27],"code",{},"useXxx",".",[18,30,31],{},"Respecter les conventions : nom, valeur de retour, état propre à chaque appel.",[10,33,35],{"id":34},"le-problème-copier-coller-de-logique","Le problème : copier-coller de logique",[37,38,39],"p",{},"Imagine que deux composants ont besoin d'un compteur de portions, avec les mêmes boutons et le même calcul. Tu pourrais recopier le code dans les deux fichiers. Mais au premier correctif, tu devrais penser à modifier les deux.",[37,41,42,43,47,48,51,52,51,55,58],{},"Un ",[44,45,46],"strong",{},"composable"," règle ce problème : c'est une fonction qui utilise l'API de Vue (",[25,49,50],{},"ref",", ",[25,53,54],{},"computed",[25,56,57],{},"onMounted","...) pour encapsuler une logique avec un état, et qui la rend réutilisable.",[10,60,62],{"id":61},"écrire-un-composable","Écrire un composable",[64,65,71],"pre",{"className":66,"code":67,"filename":68,"language":69,"meta":70,"style":70},"language-js shiki shiki-themes github-light-default github-dark-default github-dark-default","import { ref, computed } from 'vue'\n\nexport function usePortions(depart = 4) {\n  const portions = ref(depart)\n\n  const estGrandeTablee = computed(() => portions.value > 8)\n\n  function ajouter() {\n    portions.value++\n  }\n\n  function retirer() {\n    if (portions.value > 1) portions.value--\n  }\n\n  return { portions, estGrandeTablee, ajouter, retirer }\n}\n","src\u002Fcomposables\u002FusePortions.js","js","",[25,72,73,93,100,130,147,152,183,188,200,209,215,220,230,250,255,260,269],{"__ignoreMap":70},[74,75,78,82,86,89],"span",{"class":76,"line":77},"line",1,[74,79,81],{"class":80},"sOnC1","import",[74,83,85],{"class":84},"scfrF"," { ref, computed } ",[74,87,88],{"class":80},"from",[74,90,92],{"class":91},"shWOn"," 'vue'\n",[74,94,96],{"class":76,"line":95},2,[74,97,99],{"emptyLinePlaceholder":98},true,"\n",[74,101,103,106,109,113,116,120,123,127],{"class":76,"line":102},3,[74,104,105],{"class":80},"export",[74,107,108],{"class":80}," function",[74,110,112],{"class":111},"syCW7"," usePortions",[74,114,115],{"class":84},"(",[74,117,119],{"class":118},"sIXEE","depart",[74,121,122],{"class":80}," =",[74,124,126],{"class":125},"s5iOY"," 4",[74,128,129],{"class":84},") {\n",[74,131,133,136,139,141,144],{"class":76,"line":132},4,[74,134,135],{"class":80},"  const",[74,137,138],{"class":125}," portions",[74,140,122],{"class":80},[74,142,143],{"class":111}," ref",[74,145,146],{"class":84},"(depart)\n",[74,148,150],{"class":76,"line":149},5,[74,151,99],{"emptyLinePlaceholder":98},[74,153,155,157,160,162,165,168,171,174,177,180],{"class":76,"line":154},6,[74,156,135],{"class":80},[74,158,159],{"class":125}," estGrandeTablee",[74,161,122],{"class":80},[74,163,164],{"class":111}," computed",[74,166,167],{"class":84},"(() ",[74,169,170],{"class":80},"=>",[74,172,173],{"class":84}," portions.value ",[74,175,176],{"class":80},">",[74,178,179],{"class":125}," 8",[74,181,182],{"class":84},")\n",[74,184,186],{"class":76,"line":185},7,[74,187,99],{"emptyLinePlaceholder":98},[74,189,191,194,197],{"class":76,"line":190},8,[74,192,193],{"class":80},"  function",[74,195,196],{"class":111}," ajouter",[74,198,199],{"class":84},"() {\n",[74,201,203,206],{"class":76,"line":202},9,[74,204,205],{"class":84},"    portions.value",[74,207,208],{"class":80},"++\n",[74,210,212],{"class":76,"line":211},10,[74,213,214],{"class":84},"  }\n",[74,216,218],{"class":76,"line":217},11,[74,219,99],{"emptyLinePlaceholder":98},[74,221,223,225,228],{"class":76,"line":222},12,[74,224,193],{"class":80},[74,226,227],{"class":111}," retirer",[74,229,199],{"class":84},[74,231,233,236,239,241,244,247],{"class":76,"line":232},13,[74,234,235],{"class":80},"    if",[74,237,238],{"class":84}," (portions.value ",[74,240,176],{"class":80},[74,242,243],{"class":125}," 1",[74,245,246],{"class":84},") portions.value",[74,248,249],{"class":80},"--\n",[74,251,253],{"class":76,"line":252},14,[74,254,214],{"class":84},[74,256,258],{"class":76,"line":257},15,[74,259,99],{"emptyLinePlaceholder":98},[74,261,263,266],{"class":76,"line":262},16,[74,264,265],{"class":80},"  return",[74,267,268],{"class":84}," { portions, estGrandeTablee, ajouter, retirer }\n",[74,270,272],{"class":76,"line":271},17,[74,273,274],{"class":84},"}\n",[37,276,277,278,281,282,285],{},"C'est une fonction ordinaire, dans un fichier ",[25,279,280],{},".js"," ou ",[25,283,284],{},".ts",". Elle déclare un état, des valeurs calculées et des fonctions, puis les renvoie.",[10,287,289],{"id":288},"lutiliser-dans-un-composant","L'utiliser dans un composant",[64,291,296],{"className":292,"code":293,"filename":294,"language":295,"meta":70,"style":70},"language-vue shiki shiki-themes github-light-default github-dark-default github-dark-default","\u003Cscript setup>\nimport { usePortions } from '..\u002Fcomposables\u002FusePortions.js'\n\nconst { portions, estGrandeTablee, ajouter, retirer } = usePortions(6)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"retirer\">-\u003C\u002Fbutton>\n  {{ portions }} personnes\n  \u003Cbutton @click=\"ajouter\">+\u003C\u002Fbutton>\n  \u003Cp v-if=\"estGrandeTablee\">Prévois une grande table.\u003C\u002Fp>\n\u003C\u002Ftemplate>\n","src\u002Fcomponents\u002FConvives.vue","vue",[25,297,298,313,325,329,370,379,383,392,415,420,440,461],{"__ignoreMap":70},[74,299,300,303,307,310],{"class":76,"line":77},[74,301,302],{"class":84},"\u003C",[74,304,306],{"class":305},"s5JFL","script",[74,308,309],{"class":125}," setup",[74,311,312],{"class":84},">\n",[74,314,315,317,320,322],{"class":76,"line":95},[74,316,81],{"class":80},[74,318,319],{"class":84}," { usePortions } ",[74,321,88],{"class":80},[74,323,324],{"class":91}," '..\u002Fcomposables\u002FusePortions.js'\n",[74,326,327],{"class":76,"line":102},[74,328,99],{"emptyLinePlaceholder":98},[74,330,331,334,337,340,342,345,347,350,352,355,358,361,363,365,368],{"class":76,"line":132},[74,332,333],{"class":80},"const",[74,335,336],{"class":84}," { ",[74,338,339],{"class":125},"portions",[74,341,51],{"class":84},[74,343,344],{"class":125},"estGrandeTablee",[74,346,51],{"class":84},[74,348,349],{"class":125},"ajouter",[74,351,51],{"class":84},[74,353,354],{"class":125},"retirer",[74,356,357],{"class":84}," } ",[74,359,360],{"class":80},"=",[74,362,112],{"class":111},[74,364,115],{"class":84},[74,366,367],{"class":125},"6",[74,369,182],{"class":84},[74,371,372,375,377],{"class":76,"line":149},[74,373,374],{"class":84},"\u003C\u002F",[74,376,306],{"class":305},[74,378,312],{"class":84},[74,380,381],{"class":76,"line":154},[74,382,99],{"emptyLinePlaceholder":98},[74,384,385,387,390],{"class":76,"line":185},[74,386,302],{"class":84},[74,388,389],{"class":305},"template",[74,391,312],{"class":84},[74,393,394,397,400,403,405,408,411,413],{"class":76,"line":190},[74,395,396],{"class":84},"  \u003C",[74,398,399],{"class":305},"button",[74,401,402],{"class":125}," @click",[74,404,360],{"class":84},[74,406,407],{"class":91},"\"retirer\"",[74,409,410],{"class":84},">-\u003C\u002F",[74,412,399],{"class":305},[74,414,312],{"class":84},[74,416,417],{"class":76,"line":202},[74,418,419],{"class":84},"  {{ portions }} personnes\n",[74,421,422,424,426,428,430,433,436,438],{"class":76,"line":211},[74,423,396],{"class":84},[74,425,399],{"class":305},[74,427,402],{"class":125},[74,429,360],{"class":84},[74,431,432],{"class":91},"\"ajouter\"",[74,434,435],{"class":84},">+\u003C\u002F",[74,437,399],{"class":305},[74,439,312],{"class":84},[74,441,442,444,446,449,451,454,457,459],{"class":76,"line":217},[74,443,396],{"class":84},[74,445,37],{"class":305},[74,447,448],{"class":125}," v-if",[74,450,360],{"class":84},[74,452,453],{"class":91},"\"estGrandeTablee\"",[74,455,456],{"class":84},">Prévois une grande table.\u003C\u002F",[74,458,37],{"class":305},[74,460,312],{"class":84},[74,462,463,465,467],{"class":76,"line":222},[74,464,374],{"class":84},[74,466,389],{"class":305},[74,468,312],{"class":84},[37,470,471,472,475],{},"Le composant récupère exactement ce dont il a besoin. Un deuxième composant peut appeler ",[25,473,474],{},"usePortions()"," de la même façon.",[10,477,479],{"id":478},"les-conventions","Les conventions",[37,481,482],{},"La documentation fixe deux règles simples :",[484,485,486,499],"table",{},[487,488,489],"thead",{},[490,491,492,496],"tr",{},[493,494,495],"th",{},"Règle",[493,497,498],{},"Détail",[500,501,502,520],"tbody",{},[490,503,504,511],{},[505,506,507,508],"td",{},"Le nom commence par ",[25,509,510],{},"use",[505,512,513,51,516,519],{},[25,514,515],{},"usePortions",[25,517,518],{},"useMouse","... en camelCase.",[490,521,522,525],{},[505,523,524],{},"On renvoie un objet ordinaire contenant des refs",[505,526,527],{},"Le composant peut le déstructurer sans perdre la réactivité.",[37,529,530,531,534,535,538],{},"C'est pour cette raison qu'on renvoie ",[25,532,533],{},"{ portions, ajouter }"," et non un objet ",[25,536,537],{},"reactive()"," : déstructurer un objet réactif détache ses propriétés.",[540,541,542],"tip",{},[37,543,544,545,548],{},"Place tes composables dans un dossier ",[25,546,547],{},"src\u002Fcomposables\u002F",". Ce n'est pas une obligation de Vue, mais c'est un usage courant qui rend le projet lisible.",[10,550,552],{"id":551},"chaque-appel-a-son-propre-état","Chaque appel a son propre état",[37,554,555,556,558,559,561],{},"Deux composants qui appellent ",[25,557,474],{}," ne partagent pas leur compteur. Chaque appel de la fonction crée de nouveaux ",[25,560,50],{},", indépendants des autres.",[37,563,564],{},"Si tu veux partager un état entre composants, un composable ne suffit pas tel quel. Il existe pour cela une bibliothèque dédiée, Pinia, que l'outil de création de projet propose d'installer. Ce n'est pas l'objet de ce chapitre.",[10,566,568],{"id":567},"un-composable-avec-le-cycle-de-vie","Un composable avec le cycle de vie",[37,570,571],{},"Un composable peut aussi utiliser les hooks du chapitre précédent. Il nettoie alors lui-même ce qu'il a branché. C'est l'exemple de la documentation, qui suit la position de la souris :",[64,573,576],{"className":66,"code":574,"filename":575,"language":69,"meta":70,"style":70},"import { ref, onMounted, onUnmounted } from 'vue'\n\nexport function useMouse() {\n  const x = ref(0)\n  const y = ref(0)\n\n  function update(event) {\n    x.value = event.pageX\n    y.value = event.pageY\n  }\n\n  onMounted(() => window.addEventListener('mousemove', update))\n  onUnmounted(() => window.removeEventListener('mousemove', update))\n\n  return { x, y }\n}\n","src\u002Fcomposables\u002FuseMouse.js",[25,577,578,589,593,604,622,639,643,657,667,677,681,685,708,728,732,739],{"__ignoreMap":70},[74,579,580,582,585,587],{"class":76,"line":77},[74,581,81],{"class":80},[74,583,584],{"class":84}," { ref, onMounted, onUnmounted } ",[74,586,88],{"class":80},[74,588,92],{"class":91},[74,590,591],{"class":76,"line":95},[74,592,99],{"emptyLinePlaceholder":98},[74,594,595,597,599,602],{"class":76,"line":102},[74,596,105],{"class":80},[74,598,108],{"class":80},[74,600,601],{"class":111}," useMouse",[74,603,199],{"class":84},[74,605,606,608,611,613,615,617,620],{"class":76,"line":132},[74,607,135],{"class":80},[74,609,610],{"class":125}," x",[74,612,122],{"class":80},[74,614,143],{"class":111},[74,616,115],{"class":84},[74,618,619],{"class":125},"0",[74,621,182],{"class":84},[74,623,624,626,629,631,633,635,637],{"class":76,"line":149},[74,625,135],{"class":80},[74,627,628],{"class":125}," y",[74,630,122],{"class":80},[74,632,143],{"class":111},[74,634,115],{"class":84},[74,636,619],{"class":125},[74,638,182],{"class":84},[74,640,641],{"class":76,"line":154},[74,642,99],{"emptyLinePlaceholder":98},[74,644,645,647,650,652,655],{"class":76,"line":185},[74,646,193],{"class":80},[74,648,649],{"class":111}," update",[74,651,115],{"class":84},[74,653,654],{"class":118},"event",[74,656,129],{"class":84},[74,658,659,662,664],{"class":76,"line":190},[74,660,661],{"class":84},"    x.value ",[74,663,360],{"class":80},[74,665,666],{"class":84}," event.pageX\n",[74,668,669,672,674],{"class":76,"line":202},[74,670,671],{"class":84},"    y.value ",[74,673,360],{"class":80},[74,675,676],{"class":84}," event.pageY\n",[74,678,679],{"class":76,"line":211},[74,680,214],{"class":84},[74,682,683],{"class":76,"line":217},[74,684,99],{"emptyLinePlaceholder":98},[74,686,687,690,692,694,697,700,702,705],{"class":76,"line":222},[74,688,689],{"class":111},"  onMounted",[74,691,167],{"class":84},[74,693,170],{"class":80},[74,695,696],{"class":84}," window.",[74,698,699],{"class":111},"addEventListener",[74,701,115],{"class":84},[74,703,704],{"class":91},"'mousemove'",[74,706,707],{"class":84},", update))\n",[74,709,710,713,715,717,719,722,724,726],{"class":76,"line":232},[74,711,712],{"class":111},"  onUnmounted",[74,714,167],{"class":84},[74,716,170],{"class":80},[74,718,696],{"class":84},[74,720,721],{"class":111},"removeEventListener",[74,723,115],{"class":84},[74,725,704],{"class":91},[74,727,707],{"class":84},[74,729,730],{"class":76,"line":252},[74,731,99],{"emptyLinePlaceholder":98},[74,733,734,736],{"class":76,"line":257},[74,735,265],{"class":80},[74,737,738],{"class":84}," { x, y }\n",[74,740,741],{"class":76,"line":262},[74,742,274],{"class":84},[37,744,745],{},"Le composant qui l'utilise n'a rien à savoir de l'écouteur :",[64,747,749],{"className":292,"code":748,"language":295,"meta":70,"style":70},"\u003Cscript setup>\nimport { useMouse } from '..\u002Fcomposables\u002FuseMouse.js'\n\nconst { x, y } = useMouse()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cp>Souris en {{ x }}, {{ y }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[25,750,751,761,773,777,800,808,812,820,833],{"__ignoreMap":70},[74,752,753,755,757,759],{"class":76,"line":77},[74,754,302],{"class":84},[74,756,306],{"class":305},[74,758,309],{"class":125},[74,760,312],{"class":84},[74,762,763,765,768,770],{"class":76,"line":95},[74,764,81],{"class":80},[74,766,767],{"class":84}," { useMouse } ",[74,769,88],{"class":80},[74,771,772],{"class":91}," '..\u002Fcomposables\u002FuseMouse.js'\n",[74,774,775],{"class":76,"line":102},[74,776,99],{"emptyLinePlaceholder":98},[74,778,779,781,783,786,788,791,793,795,797],{"class":76,"line":132},[74,780,333],{"class":80},[74,782,336],{"class":84},[74,784,785],{"class":125},"x",[74,787,51],{"class":84},[74,789,790],{"class":125},"y",[74,792,357],{"class":84},[74,794,360],{"class":80},[74,796,601],{"class":111},[74,798,799],{"class":84},"()\n",[74,801,802,804,806],{"class":76,"line":149},[74,803,374],{"class":84},[74,805,306],{"class":305},[74,807,312],{"class":84},[74,809,810],{"class":76,"line":154},[74,811,99],{"emptyLinePlaceholder":98},[74,813,814,816,818],{"class":76,"line":185},[74,815,302],{"class":84},[74,817,389],{"class":305},[74,819,312],{"class":84},[74,821,822,824,826,829,831],{"class":76,"line":190},[74,823,396],{"class":84},[74,825,37],{"class":305},[74,827,828],{"class":84},">Souris en {{ x }}, {{ y }}\u003C\u002F",[74,830,37],{"class":305},[74,832,312],{"class":84},[74,834,835,837,839],{"class":76,"line":202},[74,836,374],{"class":84},[74,838,389],{"class":305},[74,840,312],{"class":84},[842,843,844],"note",{},[37,845,846,847,850,851,28],{},"Comme les hooks, un composable qui en utilise doit être appelé directement dans ",[25,848,849],{},"\u003Cscript setup>",", pas plus tard dans un ",[25,852,853],{},"setTimeout",[10,855,857],{"id":856},"quand-créer-un-composable","Quand créer un composable ?",[37,859,860],{},"Pas dès la première ligne. Écris d'abord la logique dans le composant. Extrais-la quand tu la retrouves dans un second composant, ou quand le composant devient trop long pour être lu d'un coup.",[37,862,863],{},"Un bon composable a un nom qui dit ce qu'il fait et une courte liste de choses qu'il renvoie.",[10,865,867],{"id":866},"à-retenir","À retenir",[15,869,870,876,887,890,893],{},[18,871,872,873,875],{},"Un composable est une fonction ",[25,874,27],{}," qui encapsule une logique réactive réutilisable.",[18,877,878,879,51,881,51,883,886],{},"Il peut utiliser ",[25,880,50],{},[25,882,54],{},[25,884,885],{},"watch"," et les hooks de cycle de vie.",[18,888,889],{},"Il renvoie un objet ordinaire de refs, que le composant déstructure sans perdre la réactivité.",[18,891,892],{},"Chaque appel crée un état indépendant.",[18,894,895],{},"On extrait un composable quand la logique est répétée ou devient trop longue, pas avant.",[897,898,899],"style",{},"html pre.shiki code .sOnC1, html code.shiki .sOnC1{--shiki-light:#CF222E;--shiki-default:#FF7B72;--shiki-dark:#FF7B72}html pre.shiki code .scfrF, html code.shiki .scfrF{--shiki-light:#1F2328;--shiki-default:#E6EDF3;--shiki-dark:#E6EDF3}html pre.shiki code .shWOn, html code.shiki .shWOn{--shiki-light:#0A3069;--shiki-default:#A5D6FF;--shiki-dark:#A5D6FF}html pre.shiki code .syCW7, html code.shiki .syCW7{--shiki-light:#8250DF;--shiki-default:#D2A8FF;--shiki-dark:#D2A8FF}html pre.shiki code .sIXEE, html code.shiki .sIXEE{--shiki-light:#953800;--shiki-default:#FFA657;--shiki-dark:#FFA657}html pre.shiki code .s5iOY, html code.shiki .s5iOY{--shiki-light:#0550AE;--shiki-default:#79C0FF;--shiki-dark:#79C0FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s5JFL, html code.shiki .s5JFL{--shiki-light:#116329;--shiki-default:#7EE787;--shiki-dark:#7EE787}",{"title":70,"searchDepth":95,"depth":102,"links":901},[902,903,904,905,906,907,908,909,910],{"id":12,"depth":95,"text":13},{"id":34,"depth":95,"text":35},{"id":61,"depth":95,"text":62},{"id":288,"depth":95,"text":289},{"id":478,"depth":95,"text":479},{"id":551,"depth":95,"text":552},{"id":567,"depth":95,"text":568},{"id":856,"depth":95,"text":857},{"id":866,"depth":95,"text":867},"Extraire et réutiliser de la logique réactive entre plusieurs composants avec des fonctions useXxx.","md",{},[46,27,915,50,54,57,916,917],"réutilisation","onUnmounted","Composition API","avance","\u002Fvue\u002Fcomposables",[921],"\u002Fvue\u002Fslots-watch-et-cycle-de-vie",[923,927],{"nom":924,"url":925,"type":926},"Vue.js, composables (documentation officielle)","https:\u002F\u002Ffr.vuejs.org\u002Fguide\u002Freusability\u002Fcomposables.html","doc",{"nom":928,"url":929,"type":930},"Vue.js, tutoriel interactif (documentation officielle)","https:\u002F\u002Ffr.vuejs.org\u002Ftutorial\u002F","exercice",{"title":5,"description":911},[933,935],{"nom":934,"url":925},"Composables (documentation officielle en français)",{"nom":936,"url":937},"Hooks de cycle de vie (documentation officielle en français)","https:\u002F\u002Ffr.vuejs.org\u002Fguide\u002Fessentials\u002Flifecycle.html","vue\u002F06.composables","Zf2jt5jc_BVJLhESS92SJc1UtxS2TKXOGP8NYEUVCII",[941,945,949,953,957,960,961],{"path":942,"title":943,"stem":944},"\u002Fvue\u002Fpremier-composant","Ton premier composant Vue","vue\u002F01.premier-composant",{"path":946,"title":947,"stem":948},"\u002Fvue\u002Ftemplate-et-directives","Le template et les directives","vue\u002F02.template-et-directives",{"path":950,"title":951,"stem":952},"\u002Fvue\u002Freactivite","La réactivité","vue\u002F03.reactivite",{"path":954,"title":955,"stem":956},"\u002Fvue\u002Fprops-et-evenements","Props, événements et v-model sur un composant","vue\u002F04.props-et-evenements",{"path":921,"title":958,"stem":959},"Slots, watch et cycle de vie","vue\u002F05.slots-watch-et-cycle-de-vie",{"path":919,"title":5,"stem":938},{"path":962,"title":963,"stem":964},"\u002Fvue","Vue","vue\u002Findex",[966,968],{"title":958,"path":921,"stem":959,"description":967,"children":-1},"Laisser le parent fournir du contenu avec les slots, réagir aux changements avec watch et agir au bon moment avec onMounted.",null,[970],{"path":921,"title":958,"ligne":295},[972,974,975,976,978,979,980],{"path":942,"title":943,"niveau":973,"stem":944},"debutant",{"path":946,"title":947,"niveau":973,"stem":948},{"path":950,"title":951,"niveau":973,"stem":952},{"path":954,"title":955,"niveau":977,"stem":956},"intermediaire",{"path":921,"title":958,"niveau":977,"stem":959},{"path":919,"title":5,"niveau":918,"stem":938},{"path":962,"title":963,"niveau":981,"stem":964},"memo",1794583439042]