[{"data":1,"prerenderedAt":3386},["ShallowReactive",2],{"blog-vue-composition-vs-options-api":3},{"id":4,"title":5,"author":6,"body":7,"date":3359,"description":3360,"extension":3361,"faq":3362,"image":3375,"meta":3376,"navigation":293,"path":3377,"seo":3378,"stem":3379,"tags":3380,"updated":3384,"__hash__":3385},"blog\u002Fblog\u002Fvue-composition-vs-options-api.md","Options API vs Composition API no Vue.js: qual usar e quando?","Larissa Santos",{"type":8,"value":9,"toc":3335},"minimark",[10,18,21,24,27,32,39,46,48,52,55,111,120,125,128,639,642,644,648,663,666,673,688,691,693,697,704,714,717,764,768,773,1167,1170,1172,1182,1191,1210,1260,1272,1360,1375,1377,1381,1384,1479,1492,1575,1578,1580,1584,1591,1598,1846,1849,1953,1960,1963,1965,1969,1972,1978,1981,2129,2136,2138,2142,2154,2157,2160,2162,2166,2173,2314,2317,2334,2336,2340,2343,2348,2362,2367,2384,2393,2395,2399,2402,2849,2852,3135,3138,3265,3267,3271,3274,3284,3287,3289,3293,3297,3313,3317,3331],[11,12,13,14],"p",{},"Se você trabalha com Vue.js há algum tempo, com certeza já se deparou com essa dúvida, ou pelo menos ouviu alguém debater sobre ela. Afinal, o Vue 3 trouxe uma nova forma de escrever componentes, e desde então a pergunta não sai do radar da comunidade: ",[15,16,17],"strong",{},"Options API ou Composition API?",[11,19,20],{},"A boa notícia é que não existe uma resposta única e definitiva. A escolha depende do contexto, do projeto e, também, do seu gosto pessoal. Mas para fazer uma escolha consciente, você precisa entender bem as duas abordagens: o que cada uma oferece, como cada uma pensa a organização do código e onde cada uma começa a mostrar suas limitações.",[11,22,23],{},"É exatamente isso que vamos explorar aqui, de forma aprofundada e com exemplos práticos.",[25,26],"hr",{},[28,29,31],"h2",{"id":30},"um-pouco-de-contexto-como-chegamos-até-aqui","Um pouco de contexto: como chegamos até aqui",[11,33,34,35,38],{},"Até o Vue 2, existia basicamente uma única forma de estruturar um componente, o que hoje chamamos de ",[15,36,37],{},"Options API",". Era o jeito Vue de fazer as coisas, e funcionava bem. Mas à medida que projetos cresciam em complexidade e a comunidade de desenvolvedores foi amadurecendo, algumas limitações foram ficando mais evidentes.",[11,40,41,42,45],{},"Em 2020, o Vue 3 foi lançado trazendo a ",[15,43,44],{},"Composition API"," como nova alternativa, inspirada em parte pelos React Hooks, mas com uma abordagem própria e mais alinhada ao modelo de reatividade do Vue. Desde então, as duas coexistem e a documentação oficial deixa claro que nenhuma será descontinuada.",[25,47],{},[28,49,51],{"id":50},"o-que-é-a-options-api","O que é a Options API?",[11,53,54],{},"A Options API é a forma clássica de criar componentes no Vue. Você exporta um objeto com \"opções\" bem definidas, cada uma com sua responsabilidade:",[56,57,58,66,72,78,84,94],"ul",{},[59,60,61,65],"li",{},[62,63,64],"code",{},"data",": onde vivem os dados reativos do componente",[59,67,68,71],{},[62,69,70],{},"methods",": onde ficam as funções que manipulam o estado ou respondem a eventos",[59,73,74,77],{},[62,75,76],{},"computed",": propriedades derivadas, calculadas com base em dados reativos",[59,79,80,83],{},[62,81,82],{},"watch",": observadores que reagem a mudanças em valores específicos",[59,85,86,89,90,93],{},[62,87,88],{},"props"," e ",[62,91,92],{},"emits",": para comunicação com componentes pai\u002Ffilho",[59,95,96,97,100,101,100,104,100,107,110],{},"Lifecycle hooks como ",[62,98,99],{},"mounted",", ",[62,102,103],{},"created",[62,105,106],{},"updated",[62,108,109],{},"unmounted",", entre outros",[11,112,113,114,116,117,119],{},"A estrutura é clara e previsível. Você sabe exatamente onde procurar cada coisa. Quer ver os dados? Vai em ",[62,115,64],{},". Quer ver os métodos? Vai em ",[62,118,70],{},". Isso torna a curva de entrada bastante suave, especialmente para quem está começando.",[121,122,124],"h3",{"id":123},"exemplo-prático-com-options-api","Exemplo prático com Options API",[11,126,127],{},"Imagine um componente simples de contador com uma mensagem derivada:",[129,130,135],"pre",{"className":131,"code":132,"language":133,"meta":134,"style":134},"language-vue shiki shiki-themes material-theme-lighter github-dark github-dark","\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp>Contagem: {{ count }}\u003C\u002Fp>\n    \u003Cp>{{ message }}\u003C\u002Fp>\n    \u003Cbutton @click=\"increment\">Incrementar\u003C\u002Fbutton>\n    \u003Cbutton @click=\"reset\">Resetar\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nexport default {\n  name: 'Counter',\n\n  data() {\n    return {\n      count: 0\n    }\n  },\n\n  computed: {\n    message() {\n      return this.count === 0\n        ? 'Nenhum clique ainda.'\n        : `Você clicou ${this.count} vez(es).`\n    }\n  },\n\n  methods: {\n    increment() {\n      this.count++\n    },\n    reset() {\n      this.count = 0\n    }\n  },\n\n  mounted() {\n    console.log('Componente montado com count:', this.count)\n  }\n}\n\u003C\u002Fscript>\n","vue","",[62,136,137,153,164,186,204,240,269,279,288,295,305,318,340,345,357,365,377,383,389,394,404,414,436,450,481,486,491,496,506,516,529,535,545,559,564,569,574,584,618,624,630],{"__ignoreMap":134},[138,139,142,146,150],"span",{"class":140,"line":141},"line",1,[138,143,145],{"class":144},"sG-J9","\u003C",[138,147,149],{"class":148},"sqIbZ","template",[138,151,152],{"class":144},">\n",[138,154,156,159,162],{"class":140,"line":155},2,[138,157,158],{"class":144},"  \u003C",[138,160,161],{"class":148},"div",[138,163,152],{"class":144},[138,165,167,170,172,175,179,182,184],{"class":140,"line":166},3,[138,168,169],{"class":144},"    \u003C",[138,171,11],{"class":148},[138,173,174],{"class":144},">",[138,176,178],{"class":177},"sMo7A","Contagem: {{ count }}",[138,180,181],{"class":144},"\u003C\u002F",[138,183,11],{"class":148},[138,185,152],{"class":144},[138,187,189,191,193,195,198,200,202],{"class":140,"line":188},4,[138,190,169],{"class":144},[138,192,11],{"class":148},[138,194,174],{"class":144},[138,196,197],{"class":177},"{{ message }}",[138,199,181],{"class":144},[138,201,11],{"class":148},[138,203,152],{"class":144},[138,205,207,209,212,216,219,223,227,229,231,234,236,238],{"class":140,"line":206},5,[138,208,169],{"class":144},[138,210,211],{"class":148},"button",[138,213,215],{"class":214},"s7047"," @click",[138,217,218],{"class":144},"=",[138,220,222],{"class":221},"sF_wb","\"",[138,224,226],{"class":225},"s0vBq","increment",[138,228,222],{"class":221},[138,230,174],{"class":144},[138,232,233],{"class":177},"Incrementar",[138,235,181],{"class":144},[138,237,211],{"class":148},[138,239,152],{"class":144},[138,241,243,245,247,249,251,253,256,258,260,263,265,267],{"class":140,"line":242},6,[138,244,169],{"class":144},[138,246,211],{"class":148},[138,248,215],{"class":214},[138,250,218],{"class":144},[138,252,222],{"class":221},[138,254,255],{"class":225},"reset",[138,257,222],{"class":221},[138,259,174],{"class":144},[138,261,262],{"class":177},"Resetar",[138,264,181],{"class":144},[138,266,211],{"class":148},[138,268,152],{"class":144},[138,270,272,275,277],{"class":140,"line":271},7,[138,273,274],{"class":144},"  \u003C\u002F",[138,276,161],{"class":148},[138,278,152],{"class":144},[138,280,282,284,286],{"class":140,"line":281},8,[138,283,181],{"class":144},[138,285,149],{"class":148},[138,287,152],{"class":144},[138,289,291],{"class":140,"line":290},9,[138,292,294],{"emptyLinePlaceholder":293},true,"\n",[138,296,298,300,303],{"class":140,"line":297},10,[138,299,145],{"class":144},[138,301,302],{"class":148},"script",[138,304,152],{"class":144},[138,306,308,312,315],{"class":140,"line":307},11,[138,309,311],{"class":310},"s3Er8","export",[138,313,314],{"class":310}," default",[138,316,317],{"class":144}," {\n",[138,319,321,325,328,331,334,337],{"class":140,"line":320},12,[138,322,324],{"class":323},"sdv8B","  name",[138,326,327],{"class":144},":",[138,329,330],{"class":221}," '",[138,332,333],{"class":225},"Counter",[138,335,336],{"class":221},"'",[138,338,339],{"class":144},",\n",[138,341,343],{"class":140,"line":342},13,[138,344,294],{"emptyLinePlaceholder":293},[138,346,348,352,355],{"class":140,"line":347},14,[138,349,351],{"class":350},"s0u7J","  data",[138,353,354],{"class":144},"()",[138,356,317],{"class":144},[138,358,360,363],{"class":140,"line":359},15,[138,361,362],{"class":310},"    return",[138,364,317],{"class":144},[138,366,368,371,373],{"class":140,"line":367},16,[138,369,370],{"class":323},"      count",[138,372,327],{"class":144},[138,374,376],{"class":375},"s_k96"," 0\n",[138,378,380],{"class":140,"line":379},17,[138,381,382],{"class":144},"    }\n",[138,384,386],{"class":140,"line":385},18,[138,387,388],{"class":144},"  },\n",[138,390,392],{"class":140,"line":391},19,[138,393,294],{"emptyLinePlaceholder":293},[138,395,397,400,402],{"class":140,"line":396},20,[138,398,399],{"class":323},"  computed",[138,401,327],{"class":144},[138,403,317],{"class":144},[138,405,407,410,412],{"class":140,"line":406},21,[138,408,409],{"class":350},"    message",[138,411,354],{"class":144},[138,413,317],{"class":144},[138,415,417,420,424,427,430,434],{"class":140,"line":416},22,[138,418,419],{"class":310},"      return",[138,421,423],{"class":422},"swu5b"," this",[138,425,426],{"class":144},".",[138,428,429],{"class":177},"count",[138,431,433],{"class":432},"sFfmW"," ===",[138,435,376],{"class":375},[138,437,439,442,444,447],{"class":140,"line":438},23,[138,440,441],{"class":432},"        ?",[138,443,330],{"class":221},[138,445,446],{"class":225},"Nenhum clique ainda.",[138,448,449],{"class":221},"'\n",[138,451,453,456,459,462,465,468,470,472,475,478],{"class":140,"line":452},24,[138,454,455],{"class":432},"        :",[138,457,458],{"class":221}," `",[138,460,461],{"class":225},"Você clicou ",[138,463,464],{"class":221},"${",[138,466,467],{"class":422},"this",[138,469,426],{"class":221},[138,471,429],{"class":177},[138,473,474],{"class":221},"}",[138,476,477],{"class":225}," vez(es).",[138,479,480],{"class":221},"`\n",[138,482,484],{"class":140,"line":483},25,[138,485,382],{"class":144},[138,487,489],{"class":140,"line":488},26,[138,490,388],{"class":144},[138,492,494],{"class":140,"line":493},27,[138,495,294],{"emptyLinePlaceholder":293},[138,497,499,502,504],{"class":140,"line":498},28,[138,500,501],{"class":323},"  methods",[138,503,327],{"class":144},[138,505,317],{"class":144},[138,507,509,512,514],{"class":140,"line":508},29,[138,510,511],{"class":350},"    increment",[138,513,354],{"class":144},[138,515,317],{"class":144},[138,517,519,522,524,526],{"class":140,"line":518},30,[138,520,521],{"class":422},"      this",[138,523,426],{"class":144},[138,525,429],{"class":177},[138,527,528],{"class":432},"++\n",[138,530,532],{"class":140,"line":531},31,[138,533,534],{"class":144},"    },\n",[138,536,538,541,543],{"class":140,"line":537},32,[138,539,540],{"class":350},"    reset",[138,542,354],{"class":144},[138,544,317],{"class":144},[138,546,548,550,552,554,557],{"class":140,"line":547},33,[138,549,521],{"class":422},[138,551,426],{"class":144},[138,553,429],{"class":177},[138,555,556],{"class":432}," =",[138,558,376],{"class":375},[138,560,562],{"class":140,"line":561},34,[138,563,382],{"class":144},[138,565,567],{"class":140,"line":566},35,[138,568,388],{"class":144},[138,570,572],{"class":140,"line":571},36,[138,573,294],{"emptyLinePlaceholder":293},[138,575,577,580,582],{"class":140,"line":576},37,[138,578,579],{"class":350},"  mounted",[138,581,354],{"class":144},[138,583,317],{"class":144},[138,585,587,590,592,596,599,601,604,606,609,611,613,615],{"class":140,"line":586},38,[138,588,589],{"class":177},"    console",[138,591,426],{"class":144},[138,593,595],{"class":594},"sK_r7","log",[138,597,598],{"class":323},"(",[138,600,336],{"class":221},[138,602,603],{"class":225},"Componente montado com count:",[138,605,336],{"class":221},[138,607,608],{"class":144},",",[138,610,423],{"class":422},[138,612,426],{"class":144},[138,614,429],{"class":177},[138,616,617],{"class":323},")\n",[138,619,621],{"class":140,"line":620},39,[138,622,623],{"class":144},"  }\n",[138,625,627],{"class":140,"line":626},40,[138,628,629],{"class":144},"}\n",[138,631,633,635,637],{"class":140,"line":632},41,[138,634,181],{"class":144},[138,636,302],{"class":148},[138,638,152],{"class":144},[11,640,641],{},"Repare que toda a lógica fica organizada dentro de \"gavetas\" separadas. Para quem vem do Vue 2 ou está aprendendo o framework agora, essa estrutura é bastante intuitiva. O problema começa quando o componente cresce.",[25,643],{},[28,645,647],{"id":646},"o-problema-de-escala-na-options-api","O problema de escala na Options API",[11,649,650,651,654,655,657,658,657,660,662],{},"Imagine agora que esse mesmo componente precisa, além do contador, gerenciar também um formulário de contato, um estado de loading para uma requisição HTTP e uma lógica de validação. Com a Options API, o código de cada uma dessas responsabilidades vai estar ",[15,652,653],{},"fragmentado",": parte em ",[62,656,64],{},", parte em ",[62,659,70],{},[62,661,76],{},", outra parte nos lifecycle hooks.",[11,664,665],{},"Você passa a ter um arquivo com 300 linhas onde, para entender uma única funcionalidade, precisa ficar rolando o componente de cima para baixo, saltando entre as seções. A documentação oficial do Vue ilustra esse problema com um diagrama que mostra exatamente como os blocos de código relacionados ficam espalhados quando usamos Options API em componentes complexos.",[11,667,668,669,672],{},"Outro ponto crítico é o reuso de lógica. Na Options API, a solução tradicional para compartilhar comportamento entre componentes eram os ",[15,670,671],{},"mixins",", que trazem uma série de problemas:",[56,674,675,678,685],{},[59,676,677],{},"Colisão de nomes: se dois mixins definem uma propriedade com o mesmo nome, há conflito",[59,679,680,681,684],{},"Origem obscura: ao olhar para ",[62,682,683],{},"this.algumDado",", é difícil saber se ele veio do próprio componente, de um mixin A ou de um mixin B",[59,686,687],{},"Acoplamento implícito: mixins podem depender de propriedades do componente host sem deixar isso claro na assinatura",[11,689,690],{},"Esses problemas ficam sérios em bases de código grandes, onde múltiplos mixins são combinados no mesmo componente.",[25,692],{},[28,694,696],{"id":695},"o-que-é-a-composition-api","O que é a Composition API?",[11,698,699,700,703],{},"A Composition API é uma alternativa que permite escrever a lógica do componente usando ",[15,701,702],{},"funções importadas diretamente da API do Vue",", em vez de declarar um objeto de opções. O nome \"composição\" vem exatamente da ideia de compor o comportamento do componente a partir de funções menores e reutilizáveis.",[11,705,706,707,710,711,713],{},"Ela é usada principalmente junto com a sintaxe ",[62,708,709],{},"\u003Cscript setup>",", que é um \"açúcar sintático\" (syntactic sugar) que reduz o boilerplate necessário. Com ",[62,712,709],{},", tudo que você declara no script fica automaticamente disponível no template, sem precisar retornar explicitamente nada.",[11,715,716],{},"As principais funções da Composition API incluem:",[56,718,719,728,734,743,755],{},[59,720,721,89,724,727],{},[62,722,723],{},"ref()",[62,725,726],{},"reactive()",": para criar estado reativo",[59,729,730,733],{},[62,731,732],{},"computed()",": para criar propriedades computadas",[59,735,736,89,739,742],{},[62,737,738],{},"watch()",[62,740,741],{},"watchEffect()",": para observar mudanças reativas",[59,744,745,100,748,100,751,754],{},[62,746,747],{},"onMounted()",[62,749,750],{},"onUnmounted()",[62,752,753],{},"onUpdated()"," e outros hooks de ciclo de vida",[59,756,757,89,760,763],{},[62,758,759],{},"provide()",[62,761,762],{},"inject()",": para injeção de dependências entre componentes",[121,765,767],{"id":766},"exemplo-prático-com-composition-api","Exemplo prático com Composition API",[11,769,770,771,327],{},"O mesmo componente de contador, reescrito com Composition API e ",[62,772,709],{},[129,774,776],{"className":131,"code":775,"language":133,"meta":134,"style":134},"\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp>Contagem: {{ count }}\u003C\u002Fp>\n    \u003Cp>{{ message }}\u003C\u002Fp>\n    \u003Cbutton @click=\"increment\">Incrementar\u003C\u002Fbutton>\n    \u003Cbutton @click=\"reset\">Resetar\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nimport { ref, computed, onMounted } from 'vue'\n\nconst count = ref(0)\n\nconst message = computed(() => {\n  return count.value === 0\n    ? 'Nenhum clique ainda.'\n    : `Você clicou ${count.value} vez(es).`\n})\n\nfunction increment() {\n  count.value++\n}\n\nfunction reset() {\n  count.value = 0\n}\n\nonMounted(() => {\n  console.log('Componente montado com count:', count.value)\n})\n\u003C\u002Fscript>\n",[62,777,778,786,794,810,826,852,878,886,894,898,909,942,946,967,971,991,1007,1018,1041,1047,1051,1063,1074,1078,1082,1093,1105,1109,1113,1126,1153,1159],{"__ignoreMap":134},[138,779,780,782,784],{"class":140,"line":141},[138,781,145],{"class":144},[138,783,149],{"class":148},[138,785,152],{"class":144},[138,787,788,790,792],{"class":140,"line":155},[138,789,158],{"class":144},[138,791,161],{"class":148},[138,793,152],{"class":144},[138,795,796,798,800,802,804,806,808],{"class":140,"line":166},[138,797,169],{"class":144},[138,799,11],{"class":148},[138,801,174],{"class":144},[138,803,178],{"class":177},[138,805,181],{"class":144},[138,807,11],{"class":148},[138,809,152],{"class":144},[138,811,812,814,816,818,820,822,824],{"class":140,"line":188},[138,813,169],{"class":144},[138,815,11],{"class":148},[138,817,174],{"class":144},[138,819,197],{"class":177},[138,821,181],{"class":144},[138,823,11],{"class":148},[138,825,152],{"class":144},[138,827,828,830,832,834,836,838,840,842,844,846,848,850],{"class":140,"line":206},[138,829,169],{"class":144},[138,831,211],{"class":148},[138,833,215],{"class":214},[138,835,218],{"class":144},[138,837,222],{"class":221},[138,839,226],{"class":225},[138,841,222],{"class":221},[138,843,174],{"class":144},[138,845,233],{"class":177},[138,847,181],{"class":144},[138,849,211],{"class":148},[138,851,152],{"class":144},[138,853,854,856,858,860,862,864,866,868,870,872,874,876],{"class":140,"line":242},[138,855,169],{"class":144},[138,857,211],{"class":148},[138,859,215],{"class":214},[138,861,218],{"class":144},[138,863,222],{"class":221},[138,865,255],{"class":225},[138,867,222],{"class":221},[138,869,174],{"class":144},[138,871,262],{"class":177},[138,873,181],{"class":144},[138,875,211],{"class":148},[138,877,152],{"class":144},[138,879,880,882,884],{"class":140,"line":271},[138,881,274],{"class":144},[138,883,161],{"class":148},[138,885,152],{"class":144},[138,887,888,890,892],{"class":140,"line":281},[138,889,181],{"class":144},[138,891,149],{"class":148},[138,893,152],{"class":144},[138,895,896],{"class":140,"line":290},[138,897,294],{"emptyLinePlaceholder":293},[138,899,900,902,904,907],{"class":140,"line":297},[138,901,145],{"class":144},[138,903,302],{"class":148},[138,905,906],{"class":214}," setup",[138,908,152],{"class":144},[138,910,911,914,917,920,922,925,927,930,933,936,938,940],{"class":140,"line":307},[138,912,913],{"class":310},"import",[138,915,916],{"class":144}," {",[138,918,919],{"class":177}," ref",[138,921,608],{"class":144},[138,923,924],{"class":177}," computed",[138,926,608],{"class":144},[138,928,929],{"class":177}," onMounted",[138,931,932],{"class":144}," }",[138,934,935],{"class":310}," from",[138,937,330],{"class":221},[138,939,133],{"class":225},[138,941,449],{"class":221},[138,943,944],{"class":140,"line":320},[138,945,294],{"emptyLinePlaceholder":293},[138,947,948,952,956,958,960,962,965],{"class":140,"line":342},[138,949,951],{"class":950},"sFsEu","const",[138,953,955],{"class":954},"sVPC0"," count",[138,957,556],{"class":432},[138,959,919],{"class":594},[138,961,598],{"class":177},[138,963,964],{"class":375},"0",[138,966,617],{"class":177},[138,968,969],{"class":140,"line":347},[138,970,294],{"emptyLinePlaceholder":293},[138,972,973,975,978,980,982,984,986,989],{"class":140,"line":359},[138,974,951],{"class":950},[138,976,977],{"class":954}," message",[138,979,556],{"class":432},[138,981,924],{"class":594},[138,983,598],{"class":177},[138,985,354],{"class":144},[138,987,988],{"class":950}," =>",[138,990,317],{"class":144},[138,992,993,996,998,1000,1003,1005],{"class":140,"line":367},[138,994,995],{"class":310},"  return",[138,997,955],{"class":177},[138,999,426],{"class":144},[138,1001,1002],{"class":177},"value",[138,1004,433],{"class":432},[138,1006,376],{"class":375},[138,1008,1009,1012,1014,1016],{"class":140,"line":379},[138,1010,1011],{"class":432},"    ?",[138,1013,330],{"class":221},[138,1015,446],{"class":225},[138,1017,449],{"class":221},[138,1019,1020,1023,1025,1027,1029,1031,1033,1035,1037,1039],{"class":140,"line":385},[138,1021,1022],{"class":432},"    :",[138,1024,458],{"class":221},[138,1026,461],{"class":225},[138,1028,464],{"class":221},[138,1030,429],{"class":177},[138,1032,426],{"class":221},[138,1034,1002],{"class":177},[138,1036,474],{"class":221},[138,1038,477],{"class":225},[138,1040,480],{"class":221},[138,1042,1043,1045],{"class":140,"line":391},[138,1044,474],{"class":144},[138,1046,617],{"class":177},[138,1048,1049],{"class":140,"line":396},[138,1050,294],{"emptyLinePlaceholder":293},[138,1052,1053,1056,1059,1061],{"class":140,"line":406},[138,1054,1055],{"class":950},"function",[138,1057,1058],{"class":594}," increment",[138,1060,354],{"class":144},[138,1062,317],{"class":144},[138,1064,1065,1068,1070,1072],{"class":140,"line":416},[138,1066,1067],{"class":177},"  count",[138,1069,426],{"class":144},[138,1071,1002],{"class":177},[138,1073,528],{"class":432},[138,1075,1076],{"class":140,"line":438},[138,1077,629],{"class":144},[138,1079,1080],{"class":140,"line":452},[138,1081,294],{"emptyLinePlaceholder":293},[138,1083,1084,1086,1089,1091],{"class":140,"line":483},[138,1085,1055],{"class":950},[138,1087,1088],{"class":594}," reset",[138,1090,354],{"class":144},[138,1092,317],{"class":144},[138,1094,1095,1097,1099,1101,1103],{"class":140,"line":488},[138,1096,1067],{"class":177},[138,1098,426],{"class":144},[138,1100,1002],{"class":177},[138,1102,556],{"class":432},[138,1104,376],{"class":375},[138,1106,1107],{"class":140,"line":493},[138,1108,629],{"class":144},[138,1110,1111],{"class":140,"line":498},[138,1112,294],{"emptyLinePlaceholder":293},[138,1114,1115,1118,1120,1122,1124],{"class":140,"line":508},[138,1116,1117],{"class":594},"onMounted",[138,1119,598],{"class":177},[138,1121,354],{"class":144},[138,1123,988],{"class":950},[138,1125,317],{"class":144},[138,1127,1128,1131,1133,1135,1137,1139,1141,1143,1145,1147,1149,1151],{"class":140,"line":518},[138,1129,1130],{"class":177},"  console",[138,1132,426],{"class":144},[138,1134,595],{"class":594},[138,1136,598],{"class":323},[138,1138,336],{"class":221},[138,1140,603],{"class":225},[138,1142,336],{"class":221},[138,1144,608],{"class":144},[138,1146,955],{"class":177},[138,1148,426],{"class":144},[138,1150,1002],{"class":177},[138,1152,617],{"class":323},[138,1154,1155,1157],{"class":140,"line":531},[138,1156,474],{"class":144},[138,1158,617],{"class":177},[138,1160,1161,1163,1165],{"class":140,"line":537},[138,1162,181],{"class":144},[138,1164,302],{"class":148},[138,1166,152],{"class":144},[11,1168,1169],{},"À primeira vista, o código parece muito similar. E de fato é: para componentes simples, a diferença não é tão gritante. A grande vantagem começa a aparecer quando o componente cresce ou quando você precisa reutilizar lógica.",[25,1171],{},[28,1173,1175,1176,89,1179],{"id":1174},"uma-diferença-importante-ref-e-value","Uma diferença importante: ",[62,1177,1178],{},"ref",[62,1180,1181],{},".value",[11,1183,1184,1185],{},"Uma das primeiras dúvidas de quem migra para a Composition API é: ",[15,1186,1187,1188,1190],{},"por que precisamos de ",[62,1189,1181],{}," para acessar o dado?",[11,1192,1193,1194,1196,1197,1199,1200,1202,1203,1206,1207,426],{},"A razão é técnica. ",[62,1195,723],{}," retorna um objeto reativo que encapsula o valor. Isso permite que o Vue rastreie as dependências corretamente. Dentro do ",[62,1198,709],{},", você acessa e modifica o valor via ",[62,1201,1181],{},". Já no template, o Vue faz o \"unwrap\" automaticamente. Você escreve ",[62,1204,1205],{},"{{ count }}"," e não ",[62,1208,1209],{},"{{ count.value }}",[129,1211,1215],{"className":1212,"code":1213,"language":1214,"meta":134,"style":134},"language-js shiki shiki-themes material-theme-lighter github-dark github-dark","const count = ref(0)\n\ncount.value++ \u002F\u002F dentro do script: usa .value\n\u002F\u002F {{ count }}       \u002F\u002F no template: sem .value, Vue desempacota automaticamente\n","js",[62,1216,1217,1233,1237,1252],{"__ignoreMap":134},[138,1218,1219,1221,1223,1225,1227,1229,1231],{"class":140,"line":141},[138,1220,951],{"class":950},[138,1222,955],{"class":954},[138,1224,556],{"class":432},[138,1226,919],{"class":594},[138,1228,598],{"class":177},[138,1230,964],{"class":375},[138,1232,617],{"class":177},[138,1234,1235],{"class":140,"line":155},[138,1236,294],{"emptyLinePlaceholder":293},[138,1238,1239,1241,1243,1245,1248],{"class":140,"line":166},[138,1240,429],{"class":177},[138,1242,426],{"class":144},[138,1244,1002],{"class":177},[138,1246,1247],{"class":432},"++",[138,1249,1251],{"class":1250},"sutJx"," \u002F\u002F dentro do script: usa .value\n",[138,1253,1254,1257],{"class":140,"line":188},[138,1255,1256],{"class":1250},"\u002F\u002F {{ count }}",[138,1258,1259],{"class":1250},"       \u002F\u002F no template: sem .value, Vue desempacota automaticamente\n",[11,1261,1262,1263,1265,1266,1268,1269,1271],{},"Para objetos e arrays, você pode usar ",[62,1264,726],{}," em vez de ",[62,1267,723],{},". Nesse caso, não há ",[62,1270,1181],{},", pois o próprio objeto é reativo:",[129,1273,1275],{"className":1212,"code":1274,"language":1214,"meta":134,"style":134},"const state = reactive({\n  count: 0,\n  name: 'Vue'\n})\n\nstate.count++ \u002F\u002F sem .value\nstate.name = 'Nuxt'\n",[62,1276,1277,1294,1305,1318,1324,1328,1342],{"__ignoreMap":134},[138,1278,1279,1281,1284,1286,1289,1291],{"class":140,"line":141},[138,1280,951],{"class":950},[138,1282,1283],{"class":954}," state",[138,1285,556],{"class":432},[138,1287,1288],{"class":594}," reactive",[138,1290,598],{"class":177},[138,1292,1293],{"class":144},"{\n",[138,1295,1296,1298,1300,1303],{"class":140,"line":155},[138,1297,1067],{"class":323},[138,1299,327],{"class":144},[138,1301,1302],{"class":375}," 0",[138,1304,339],{"class":144},[138,1306,1307,1309,1311,1313,1316],{"class":140,"line":166},[138,1308,324],{"class":323},[138,1310,327],{"class":144},[138,1312,330],{"class":221},[138,1314,1315],{"class":225},"Vue",[138,1317,449],{"class":221},[138,1319,1320,1322],{"class":140,"line":188},[138,1321,474],{"class":144},[138,1323,617],{"class":177},[138,1325,1326],{"class":140,"line":206},[138,1327,294],{"emptyLinePlaceholder":293},[138,1329,1330,1333,1335,1337,1339],{"class":140,"line":242},[138,1331,1332],{"class":177},"state",[138,1334,426],{"class":144},[138,1336,429],{"class":177},[138,1338,1247],{"class":432},[138,1340,1341],{"class":1250}," \u002F\u002F sem .value\n",[138,1343,1344,1346,1348,1351,1353,1355,1358],{"class":140,"line":271},[138,1345,1332],{"class":177},[138,1347,426],{"class":144},[138,1349,1350],{"class":177},"name ",[138,1352,218],{"class":432},[138,1354,330],{"class":221},[138,1356,1357],{"class":225},"Nuxt",[138,1359,449],{"class":221},[11,1361,1362,1363,89,1365,1368,1369,1371,1372,1374],{},"A escolha entre ",[62,1364,1178],{},[62,1366,1367],{},"reactive"," é uma questão de preferência e contexto. Muitos desenvolvedores usam ",[62,1370,1178],{}," para tudo por consistência, enquanto outros preferem ",[62,1373,1367],{}," para agrupar estados relacionados.",[25,1376],{},[28,1378,1380],{"id":1379},"comparando-lado-a-lado-os-lifecycle-hooks","Comparando lado a lado: os lifecycle hooks",[11,1382,1383],{},"Uma das diferenças mais práticas entre as duas abordagens é como lidar com os hooks de ciclo de vida. Na Options API, eles são métodos do objeto de opções. Na Composition API, são funções importadas.",[1385,1386,1387,1398],"table",{},[1388,1389,1390],"thead",{},[1391,1392,1393,1396],"tr",{},[1394,1395,37],"th",{},[1394,1397,44],{},[1399,1400,1401,1411,1421,1432,1443,1455,1467],"tbody",{},[1391,1402,1403,1408],{},[1404,1405,1406],"td",{},[62,1407,103],{},[1404,1409,1410],{},"(executa no setup)",[1391,1412,1413,1417],{},[1404,1414,1415],{},[62,1416,99],{},[1404,1418,1419],{},[62,1420,1117],{},[1391,1422,1423,1427],{},[1404,1424,1425],{},[62,1426,106],{},[1404,1428,1429],{},[62,1430,1431],{},"onUpdated",[1391,1433,1434,1438],{},[1404,1435,1436],{},[62,1437,109],{},[1404,1439,1440],{},[62,1441,1442],{},"onUnmounted",[1391,1444,1445,1450],{},[1404,1446,1447],{},[62,1448,1449],{},"beforeMount",[1404,1451,1452],{},[62,1453,1454],{},"onBeforeMount",[1391,1456,1457,1462],{},[1404,1458,1459],{},[62,1460,1461],{},"beforeUpdate",[1404,1463,1464],{},[62,1465,1466],{},"onBeforeUpdate",[1391,1468,1469,1474],{},[1404,1470,1471],{},[62,1472,1473],{},"beforeUnmount",[1404,1475,1476],{},[62,1477,1478],{},"onBeforeUnmount",[11,1480,1481,1482,1485,1486,1488,1489,1491],{},"Vale destacar um comportamento interessante: na Composition API, você pode ",[15,1483,1484],{},"chamar o mesmo hook várias vezes"," dentro do mesmo componente, e todas as chamadas serão executadas. Na Options API, só há um ",[62,1487,99],{},", um ",[62,1490,106],{},", etc.",[129,1493,1495],{"className":1212,"code":1494,"language":1214,"meta":134,"style":134},"onMounted(() => {\n  console.log('Inicializando o mapa...')\n})\n\nonMounted(() => {\n  console.log('Buscando dados iniciais...')\n})\n",[62,1496,1497,1509,1528,1534,1538,1550,1569],{"__ignoreMap":134},[138,1498,1499,1501,1503,1505,1507],{"class":140,"line":141},[138,1500,1117],{"class":594},[138,1502,598],{"class":177},[138,1504,354],{"class":144},[138,1506,988],{"class":950},[138,1508,317],{"class":144},[138,1510,1511,1513,1515,1517,1519,1521,1524,1526],{"class":140,"line":155},[138,1512,1130],{"class":177},[138,1514,426],{"class":144},[138,1516,595],{"class":594},[138,1518,598],{"class":323},[138,1520,336],{"class":221},[138,1522,1523],{"class":225},"Inicializando o mapa...",[138,1525,336],{"class":221},[138,1527,617],{"class":323},[138,1529,1530,1532],{"class":140,"line":166},[138,1531,474],{"class":144},[138,1533,617],{"class":177},[138,1535,1536],{"class":140,"line":188},[138,1537,294],{"emptyLinePlaceholder":293},[138,1539,1540,1542,1544,1546,1548],{"class":140,"line":206},[138,1541,1117],{"class":594},[138,1543,598],{"class":177},[138,1545,354],{"class":144},[138,1547,988],{"class":950},[138,1549,317],{"class":144},[138,1551,1552,1554,1556,1558,1560,1562,1565,1567],{"class":140,"line":242},[138,1553,1130],{"class":177},[138,1555,426],{"class":144},[138,1557,595],{"class":594},[138,1559,598],{"class":323},[138,1561,336],{"class":221},[138,1563,1564],{"class":225},"Buscando dados iniciais...",[138,1566,336],{"class":221},[138,1568,617],{"class":323},[138,1570,1571,1573],{"class":140,"line":271},[138,1572,474],{"class":144},[138,1574,617],{"class":177},[11,1576,1577],{},"Isso pode parecer estranho no começo, mas faz muito sentido quando você começa a extrair lógica para composables, pois cada um pode registrar seus próprios hooks sem interferir nos outros.",[25,1579],{},[28,1581,1583],{"id":1582},"o-grande-diferencial-os-composables","O grande diferencial: os Composables",[11,1585,1586,1587,1590],{},"Se a Composition API tem um superpoder, esse superpoder tem nome: ",[15,1588,1589],{},"composables",". São funções que encapsulam lógica com estado e podem ser reutilizadas em qualquer componente, sem os problemas dos mixins.",[11,1592,1593,1594,1597],{},"Por convenção, composables começam com ",[62,1595,1596],{},"use"," (assim como os hooks do React). Veja um exemplo real de um composable para rastrear a posição do mouse:",[129,1599,1601],{"className":1212,"code":1600,"language":1214,"meta":134,"style":134},"\u002F\u002F useMouse.js\nimport { 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",[62,1602,1603,1608,1635,1639,1653,1671,1688,1692,1711,1730,1748,1752,1756,1791,1823,1827,1842],{"__ignoreMap":134},[138,1604,1605],{"class":140,"line":141},[138,1606,1607],{"class":1250},"\u002F\u002F useMouse.js\n",[138,1609,1610,1612,1614,1616,1618,1620,1622,1625,1627,1629,1631,1633],{"class":140,"line":155},[138,1611,913],{"class":310},[138,1613,916],{"class":144},[138,1615,919],{"class":177},[138,1617,608],{"class":144},[138,1619,929],{"class":177},[138,1621,608],{"class":144},[138,1623,1624],{"class":177}," onUnmounted",[138,1626,932],{"class":144},[138,1628,935],{"class":310},[138,1630,330],{"class":221},[138,1632,133],{"class":225},[138,1634,449],{"class":221},[138,1636,1637],{"class":140,"line":166},[138,1638,294],{"emptyLinePlaceholder":293},[138,1640,1641,1643,1646,1649,1651],{"class":140,"line":188},[138,1642,311],{"class":310},[138,1644,1645],{"class":950}," function",[138,1647,1648],{"class":594}," useMouse",[138,1650,354],{"class":144},[138,1652,317],{"class":144},[138,1654,1655,1658,1661,1663,1665,1667,1669],{"class":140,"line":206},[138,1656,1657],{"class":950},"  const",[138,1659,1660],{"class":954}," x",[138,1662,556],{"class":432},[138,1664,919],{"class":594},[138,1666,598],{"class":323},[138,1668,964],{"class":375},[138,1670,617],{"class":323},[138,1672,1673,1675,1678,1680,1682,1684,1686],{"class":140,"line":242},[138,1674,1657],{"class":950},[138,1676,1677],{"class":954}," y",[138,1679,556],{"class":432},[138,1681,919],{"class":594},[138,1683,598],{"class":323},[138,1685,964],{"class":375},[138,1687,617],{"class":323},[138,1689,1690],{"class":140,"line":271},[138,1691,294],{"emptyLinePlaceholder":293},[138,1693,1694,1697,1700,1702,1706,1709],{"class":140,"line":281},[138,1695,1696],{"class":950},"  function",[138,1698,1699],{"class":594}," update",[138,1701,598],{"class":144},[138,1703,1705],{"class":1704},"sk1zL","event",[138,1707,1708],{"class":144},")",[138,1710,317],{"class":144},[138,1712,1713,1716,1718,1720,1722,1725,1727],{"class":140,"line":290},[138,1714,1715],{"class":177},"    x",[138,1717,426],{"class":144},[138,1719,1002],{"class":177},[138,1721,556],{"class":432},[138,1723,1724],{"class":177}," event",[138,1726,426],{"class":144},[138,1728,1729],{"class":177},"pageX\n",[138,1731,1732,1735,1737,1739,1741,1743,1745],{"class":140,"line":297},[138,1733,1734],{"class":177},"    y",[138,1736,426],{"class":144},[138,1738,1002],{"class":177},[138,1740,556],{"class":432},[138,1742,1724],{"class":177},[138,1744,426],{"class":144},[138,1746,1747],{"class":177},"pageY\n",[138,1749,1750],{"class":140,"line":307},[138,1751,623],{"class":144},[138,1753,1754],{"class":140,"line":320},[138,1755,294],{"emptyLinePlaceholder":293},[138,1757,1758,1761,1763,1765,1767,1770,1772,1775,1777,1779,1782,1784,1786,1788],{"class":140,"line":342},[138,1759,1760],{"class":594},"  onMounted",[138,1762,598],{"class":323},[138,1764,354],{"class":144},[138,1766,988],{"class":950},[138,1768,1769],{"class":177}," window",[138,1771,426],{"class":144},[138,1773,1774],{"class":594},"addEventListener",[138,1776,598],{"class":323},[138,1778,336],{"class":221},[138,1780,1781],{"class":225},"mousemove",[138,1783,336],{"class":221},[138,1785,608],{"class":144},[138,1787,1699],{"class":177},[138,1789,1790],{"class":323},"))\n",[138,1792,1793,1796,1798,1800,1802,1804,1806,1809,1811,1813,1815,1817,1819,1821],{"class":140,"line":347},[138,1794,1795],{"class":594},"  onUnmounted",[138,1797,598],{"class":323},[138,1799,354],{"class":144},[138,1801,988],{"class":950},[138,1803,1769],{"class":177},[138,1805,426],{"class":144},[138,1807,1808],{"class":594},"removeEventListener",[138,1810,598],{"class":323},[138,1812,336],{"class":221},[138,1814,1781],{"class":225},[138,1816,336],{"class":221},[138,1818,608],{"class":144},[138,1820,1699],{"class":177},[138,1822,1790],{"class":323},[138,1824,1825],{"class":140,"line":359},[138,1826,294],{"emptyLinePlaceholder":293},[138,1828,1829,1831,1833,1835,1837,1839],{"class":140,"line":367},[138,1830,995],{"class":310},[138,1832,916],{"class":144},[138,1834,1660],{"class":177},[138,1836,608],{"class":144},[138,1838,1677],{"class":177},[138,1840,1841],{"class":144}," }\n",[138,1843,1844],{"class":140,"line":379},[138,1845,629],{"class":144},[11,1847,1848],{},"E agora, para usar em qualquer componente:",[129,1850,1852],{"className":131,"code":1851,"language":133,"meta":134,"style":134},"\u003Cscript setup>\nimport { useMouse } from '.\u002Fcomposables\u002FuseMouse'\n\nconst { x, y } = useMouse()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cp>Posição do mouse: {{ x }}, {{ y }}\u003C\u002Fp>\n\u003C\u002Ftemplate>\n",[62,1853,1854,1864,1883,1887,1908,1916,1920,1928,1945],{"__ignoreMap":134},[138,1855,1856,1858,1860,1862],{"class":140,"line":141},[138,1857,145],{"class":144},[138,1859,302],{"class":148},[138,1861,906],{"class":214},[138,1863,152],{"class":144},[138,1865,1866,1868,1870,1872,1874,1876,1878,1881],{"class":140,"line":155},[138,1867,913],{"class":310},[138,1869,916],{"class":144},[138,1871,1648],{"class":177},[138,1873,932],{"class":144},[138,1875,935],{"class":310},[138,1877,330],{"class":221},[138,1879,1880],{"class":225},".\u002Fcomposables\u002FuseMouse",[138,1882,449],{"class":221},[138,1884,1885],{"class":140,"line":166},[138,1886,294],{"emptyLinePlaceholder":293},[138,1888,1889,1891,1893,1895,1897,1899,1901,1903,1905],{"class":140,"line":188},[138,1890,951],{"class":950},[138,1892,916],{"class":144},[138,1894,1660],{"class":954},[138,1896,608],{"class":144},[138,1898,1677],{"class":954},[138,1900,932],{"class":144},[138,1902,556],{"class":432},[138,1904,1648],{"class":594},[138,1906,1907],{"class":177},"()\n",[138,1909,1910,1912,1914],{"class":140,"line":206},[138,1911,181],{"class":144},[138,1913,302],{"class":148},[138,1915,152],{"class":144},[138,1917,1918],{"class":140,"line":242},[138,1919,294],{"emptyLinePlaceholder":293},[138,1921,1922,1924,1926],{"class":140,"line":271},[138,1923,145],{"class":144},[138,1925,149],{"class":148},[138,1927,152],{"class":144},[138,1929,1930,1932,1934,1936,1939,1941,1943],{"class":140,"line":281},[138,1931,158],{"class":144},[138,1933,11],{"class":148},[138,1935,174],{"class":144},[138,1937,1938],{"class":177},"Posição do mouse: {{ x }}, {{ y }}",[138,1940,181],{"class":144},[138,1942,11],{"class":148},[138,1944,152],{"class":144},[138,1946,1947,1949,1951],{"class":140,"line":290},[138,1948,181],{"class":144},[138,1950,149],{"class":148},[138,1952,152],{"class":144},[11,1954,1955,1956,1959],{},"Repare o que acontece aqui: a lógica de adicionar e remover o event listener está ",[15,1957,1958],{},"completamente encapsulada"," no composable. O componente não precisa saber como isso funciona internamente, ele só consome o resultado. Não há risco de colisão de nomes, não há ambiguidade sobre a origem dos dados, e o composable pode ser testado de forma independente.",[11,1961,1962],{},"Isso seria muito mais difícil de alcançar com mixins na Options API.",[25,1964],{},[28,1966,1968],{"id":1967},"typescript-onde-a-composition-api-brilha-mais","TypeScript: onde a Composition API brilha mais",[11,1970,1971],{},"Com o crescimento do TypeScript no ecossistema frontend, essa é uma dimensão cada vez mais relevante na escolha entre as duas APIs.",[11,1973,1974,1975,1977],{},"A Options API foi projetada antes do TypeScript se tornar popular, e isso cria fricção. O sistema de tipos precisa \"adivinhar\" o que está disponível em ",[62,1976,467],{},", o que exige malabarismos internos no Vue. Para mixins, a situação piora ainda mais, pois o TypeScript não consegue inferir de onde vêm as propriedades.",[11,1979,1980],{},"A Composition API, por outro lado, trabalha com variáveis e funções comuns do JavaScript, algo que o TypeScript entende naturalmente. A inferência de tipos funciona quase que automaticamente:",[129,1982,1986],{"className":1983,"code":1984,"language":1985,"meta":134,"style":134},"language-ts shiki shiki-themes material-theme-lighter github-dark github-dark","\u003Cscript setup lang=\"ts\">\nimport { ref, computed } from 'vue'\n\nconst count = ref(0)          \u002F\u002F TypeScript infere: Ref\u003Cnumber>\nconst double = computed(() => count.value * 2) \u002F\u002F infere: ComputedRef\u003Cnumber>\n\nfunction increment(): void {\n  count.value++\n}\n\u003C\u002Fscript>\n","ts",[62,1987,1988,2005,2027,2031,2051,2087,2091,2107,2117,2121],{"__ignoreMap":134},[138,1989,1990,1992,1995,1997,1999,2001,2003],{"class":140,"line":141},[138,1991,145],{"class":432},[138,1993,1994],{"class":177},"script setup lang",[138,1996,218],{"class":432},[138,1998,222],{"class":221},[138,2000,1985],{"class":225},[138,2002,222],{"class":221},[138,2004,152],{"class":432},[138,2006,2007,2009,2011,2013,2015,2017,2019,2021,2023,2025],{"class":140,"line":155},[138,2008,913],{"class":310},[138,2010,916],{"class":144},[138,2012,919],{"class":177},[138,2014,608],{"class":144},[138,2016,924],{"class":177},[138,2018,932],{"class":144},[138,2020,935],{"class":310},[138,2022,330],{"class":221},[138,2024,133],{"class":225},[138,2026,449],{"class":221},[138,2028,2029],{"class":140,"line":166},[138,2030,294],{"emptyLinePlaceholder":293},[138,2032,2033,2035,2037,2039,2041,2043,2045,2048],{"class":140,"line":188},[138,2034,951],{"class":950},[138,2036,955],{"class":954},[138,2038,556],{"class":432},[138,2040,919],{"class":594},[138,2042,598],{"class":177},[138,2044,964],{"class":375},[138,2046,2047],{"class":177},")          ",[138,2049,2050],{"class":1250},"\u002F\u002F TypeScript infere: Ref\u003Cnumber>\n",[138,2052,2053,2055,2058,2060,2062,2064,2066,2068,2070,2072,2075,2078,2081,2084],{"class":140,"line":206},[138,2054,951],{"class":950},[138,2056,2057],{"class":954}," double",[138,2059,556],{"class":432},[138,2061,924],{"class":594},[138,2063,598],{"class":177},[138,2065,354],{"class":144},[138,2067,988],{"class":950},[138,2069,955],{"class":177},[138,2071,426],{"class":144},[138,2073,2074],{"class":177},"value ",[138,2076,2077],{"class":432},"*",[138,2079,2080],{"class":375}," 2",[138,2082,2083],{"class":177},") ",[138,2085,2086],{"class":1250},"\u002F\u002F infere: ComputedRef\u003Cnumber>\n",[138,2088,2089],{"class":140,"line":242},[138,2090,294],{"emptyLinePlaceholder":293},[138,2092,2093,2095,2097,2099,2101,2105],{"class":140,"line":271},[138,2094,1055],{"class":950},[138,2096,1058],{"class":594},[138,2098,354],{"class":144},[138,2100,327],{"class":432},[138,2102,2104],{"class":2103},"s3afY"," void",[138,2106,317],{"class":144},[138,2108,2109,2111,2113,2115],{"class":140,"line":281},[138,2110,1067],{"class":177},[138,2112,426],{"class":144},[138,2114,1002],{"class":177},[138,2116,528],{"class":432},[138,2118,2119],{"class":140,"line":290},[138,2120,629],{"class":144},[138,2122,2123,2125,2127],{"class":140,"line":297},[138,2124,181],{"class":432},[138,2126,302],{"class":177},[138,2128,152],{"class":432},[11,2130,2131,2132,2135],{},"Para projetos que usam TypeScript, a Composition API é claramente a abordagem mais ergonômica. Com a Options API e TypeScript, é necessário usar ",[62,2133,2134],{},"defineComponent"," e ainda assim algumas situações de tipagem ficam trabalhosas.",[25,2137],{},[28,2139,2141],{"id":2140},"performance-e-bundle-size","Performance e bundle size",[11,2143,2144,2145,2147,2148,2150,2151,2153],{},"Outro ponto que a documentação oficial destaca é que código escrito com ",[62,2146,709],{}," é mais eficiente na fase de minificação. Isso acontece porque, diferente da Options API onde as propriedades são acessadas via ",[62,2149,467],{},", no ",[62,2152,709],{}," tudo é declarado no escopo local, e os minificadores conseguem renomear variáveis locais de forma muito mais agressiva.",[11,2155,2156],{},"O resultado prático é um bundle final um pouco menor, o que impacta positivamente o tempo de carregamento da aplicação, especialmente relevante para projetos grandes.",[11,2158,2159],{},"Além disso, se você usar exclusivamente a Composition API em um projeto, é possível configurar uma flag de compilação que remove o código da Options API do bundle do Vue em si, economizando alguns kilobytes adicionais.",[25,2161],{},[28,2163,2165],{"id":2164},"podem-ser-usadas-juntas","Podem ser usadas juntas?",[11,2167,2168,2169,2172],{},"Sim! Uma dúvida comum é se é possível misturar as duas abordagens. A resposta é sim: você pode usar ",[62,2170,2171],{},"setup()"," como uma opção dentro de um componente Options API:",[129,2174,2176],{"className":131,"code":2175,"language":133,"meta":134,"style":134},"\u003Cscript>\nimport { ref } from 'vue'\n\nexport default {\n  data() {\n    return {\n      legacyData: 'sou da Options API'\n    }\n  },\n\n  setup() {\n    const newData = ref('sou da Composition API')\n    return { newData }\n  }\n}\n\u003C\u002Fscript>\n",[62,2177,2178,2186,2204,2208,2216,2224,2230,2244,2248,2252,2256,2265,2288,2298,2302,2306],{"__ignoreMap":134},[138,2179,2180,2182,2184],{"class":140,"line":141},[138,2181,145],{"class":144},[138,2183,302],{"class":148},[138,2185,152],{"class":144},[138,2187,2188,2190,2192,2194,2196,2198,2200,2202],{"class":140,"line":155},[138,2189,913],{"class":310},[138,2191,916],{"class":144},[138,2193,919],{"class":177},[138,2195,932],{"class":144},[138,2197,935],{"class":310},[138,2199,330],{"class":221},[138,2201,133],{"class":225},[138,2203,449],{"class":221},[138,2205,2206],{"class":140,"line":166},[138,2207,294],{"emptyLinePlaceholder":293},[138,2209,2210,2212,2214],{"class":140,"line":188},[138,2211,311],{"class":310},[138,2213,314],{"class":310},[138,2215,317],{"class":144},[138,2217,2218,2220,2222],{"class":140,"line":206},[138,2219,351],{"class":350},[138,2221,354],{"class":144},[138,2223,317],{"class":144},[138,2225,2226,2228],{"class":140,"line":242},[138,2227,362],{"class":310},[138,2229,317],{"class":144},[138,2231,2232,2235,2237,2239,2242],{"class":140,"line":271},[138,2233,2234],{"class":323},"      legacyData",[138,2236,327],{"class":144},[138,2238,330],{"class":221},[138,2240,2241],{"class":225},"sou da Options API",[138,2243,449],{"class":221},[138,2245,2246],{"class":140,"line":281},[138,2247,382],{"class":144},[138,2249,2250],{"class":140,"line":290},[138,2251,388],{"class":144},[138,2253,2254],{"class":140,"line":297},[138,2255,294],{"emptyLinePlaceholder":293},[138,2257,2258,2261,2263],{"class":140,"line":307},[138,2259,2260],{"class":350},"  setup",[138,2262,354],{"class":144},[138,2264,317],{"class":144},[138,2266,2267,2270,2273,2275,2277,2279,2281,2284,2286],{"class":140,"line":320},[138,2268,2269],{"class":950},"    const",[138,2271,2272],{"class":954}," newData",[138,2274,556],{"class":432},[138,2276,919],{"class":594},[138,2278,598],{"class":323},[138,2280,336],{"class":221},[138,2282,2283],{"class":225},"sou da Composition API",[138,2285,336],{"class":221},[138,2287,617],{"class":323},[138,2289,2290,2292,2294,2296],{"class":140,"line":342},[138,2291,362],{"class":310},[138,2293,916],{"class":144},[138,2295,2272],{"class":177},[138,2297,1841],{"class":144},[138,2299,2300],{"class":140,"line":347},[138,2301,623],{"class":144},[138,2303,2304],{"class":140,"line":359},[138,2305,629],{"class":144},[138,2307,2308,2310,2312],{"class":140,"line":367},[138,2309,181],{"class":144},[138,2311,302],{"class":148},[138,2313,152],{"class":144},[11,2315,2316],{},"Isso é especialmente útil durante migrações graduais, pois você pode ir introduzindo a Composition API em componentes existentes sem precisar reescrever tudo de uma vez.",[11,2318,2319,2320,2323,2324,2326,2327,2330,2331,2333],{},"O que ",[15,2321,2322],{},"não"," é recomendado é usar ",[62,2325,709],{}," (a sintaxe mais moderna) junto com opções tradicionais como ",[62,2328,2329],{},"data()"," ou ",[62,2332,70],{}," no mesmo componente. Nesse caso, você deve escolher um ou outro.",[25,2335],{},[28,2337,2339],{"id":2338},"quando-usar-cada-uma","Quando usar cada uma?",[11,2341,2342],{},"Depois de tudo isso, a pergunta inevitável: quando optar por cada abordagem?",[11,2344,2345],{},[15,2346,2347],{},"Options API faz sentido quando:",[56,2349,2350,2353,2356,2359],{},[59,2351,2352],{},"Você está iniciando no Vue e quer uma curva de aprendizado menor",[59,2354,2355],{},"O projeto é pequeno ou de baixa complexidade",[59,2357,2358],{},"A equipe tem familiaridade com Vue 2 e a migração precisa ser gradual",[59,2360,2361],{},"Componentes têm responsabilidades bem delimitadas e não crescem muito",[11,2363,2364],{},[15,2365,2366],{},"Composition API faz sentido quando:",[56,2368,2369,2372,2375,2378,2381],{},[59,2370,2371],{},"O projeto é de médio a grande porte",[59,2373,2374],{},"Você usa TypeScript (ou pretende usar)",[59,2376,2377],{},"Há lógica que precisa ser reutilizada entre múltiplos componentes",[59,2379,2380],{},"A equipe preza por testes unitários, já que composables são muito mais fáceis de testar isoladamente",[59,2382,2383],{},"Você está construindo uma biblioteca de componentes ou um design system",[11,2385,2386,2389,2390,2392],{},[15,2387,2388],{},"Na prática:"," projetos novos iniciados com Vue 3 dificilmente têm motivo para escolher a Options API como padrão. A Composition API com ",[62,2391,709],{}," é a direção clara do framework: é o que a documentação recomenda, é o que o ecossistema (Nuxt 3, Pinia, VueUse) adota nativamente.",[25,2394],{},[28,2396,2398],{"id":2397},"um-exemplo-real-de-organização-com-composition-api","Um exemplo real de organização com Composition API",[11,2400,2401],{},"Para fechar, um exemplo mais próximo do mundo real: um componente que busca uma lista de usuários de uma API.",[129,2403,2405],{"className":131,"code":2404,"language":133,"meta":134,"style":134},"\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp v-if=\"loading\">Carregando...\u003C\u002Fp>\n    \u003Cp v-if=\"error\">Erro: {{ error }}\u003C\u002Fp>\n    \u003Cul v-if=\"!loading && !error\">\n      \u003Cli v-for=\"user in users\" :key=\"user.id\">{{ user.name }}\u003C\u002Fli>\n    \u003C\u002Ful>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nimport { ref, onMounted } from 'vue'\n\nconst users = ref([])\nconst loading = ref(false)\nconst error = ref(null)\n\nasync function fetchUsers() {\n  loading.value = true\n  error.value = null\n\n  try {\n    const response = await fetch('https:\u002F\u002Fjsonplaceholder.typicode.com\u002Fusers')\n    users.value = await response.json()\n  } catch (err) {\n    error.value = err.message\n  } finally {\n    loading.value = false\n  }\n}\n\nonMounted(fetchUsers)\n\u003C\u002Fscript>\n",[62,2406,2407,2415,2423,2452,2480,2499,2541,2550,2558,2566,2570,2580,2602,2606,2620,2639,2657,2661,2675,2689,2703,2707,2714,2740,2762,2780,2799,2808,2822,2826,2830,2834,2841],{"__ignoreMap":134},[138,2408,2409,2411,2413],{"class":140,"line":141},[138,2410,145],{"class":144},[138,2412,149],{"class":148},[138,2414,152],{"class":144},[138,2416,2417,2419,2421],{"class":140,"line":155},[138,2418,158],{"class":144},[138,2420,161],{"class":148},[138,2422,152],{"class":144},[138,2424,2425,2427,2429,2432,2434,2436,2439,2441,2443,2446,2448,2450],{"class":140,"line":166},[138,2426,169],{"class":144},[138,2428,11],{"class":148},[138,2430,2431],{"class":214}," v-if",[138,2433,218],{"class":144},[138,2435,222],{"class":221},[138,2437,2438],{"class":225},"loading",[138,2440,222],{"class":221},[138,2442,174],{"class":144},[138,2444,2445],{"class":177},"Carregando...",[138,2447,181],{"class":144},[138,2449,11],{"class":148},[138,2451,152],{"class":144},[138,2453,2454,2456,2458,2460,2462,2464,2467,2469,2471,2474,2476,2478],{"class":140,"line":188},[138,2455,169],{"class":144},[138,2457,11],{"class":148},[138,2459,2431],{"class":214},[138,2461,218],{"class":144},[138,2463,222],{"class":221},[138,2465,2466],{"class":225},"error",[138,2468,222],{"class":221},[138,2470,174],{"class":144},[138,2472,2473],{"class":177},"Erro: {{ error }}",[138,2475,181],{"class":144},[138,2477,11],{"class":148},[138,2479,152],{"class":144},[138,2481,2482,2484,2486,2488,2490,2492,2495,2497],{"class":140,"line":206},[138,2483,169],{"class":144},[138,2485,56],{"class":148},[138,2487,2431],{"class":214},[138,2489,218],{"class":144},[138,2491,222],{"class":221},[138,2493,2494],{"class":225},"!loading && !error",[138,2496,222],{"class":221},[138,2498,152],{"class":144},[138,2500,2501,2504,2506,2509,2511,2513,2516,2518,2521,2523,2525,2528,2530,2532,2535,2537,2539],{"class":140,"line":242},[138,2502,2503],{"class":144},"      \u003C",[138,2505,59],{"class":148},[138,2507,2508],{"class":214}," v-for",[138,2510,218],{"class":144},[138,2512,222],{"class":221},[138,2514,2515],{"class":225},"user in users",[138,2517,222],{"class":221},[138,2519,2520],{"class":214}," :key",[138,2522,218],{"class":144},[138,2524,222],{"class":221},[138,2526,2527],{"class":225},"user.id",[138,2529,222],{"class":221},[138,2531,174],{"class":144},[138,2533,2534],{"class":177},"{{ user.name }}",[138,2536,181],{"class":144},[138,2538,59],{"class":148},[138,2540,152],{"class":144},[138,2542,2543,2546,2548],{"class":140,"line":271},[138,2544,2545],{"class":144},"    \u003C\u002F",[138,2547,56],{"class":148},[138,2549,152],{"class":144},[138,2551,2552,2554,2556],{"class":140,"line":281},[138,2553,274],{"class":144},[138,2555,161],{"class":148},[138,2557,152],{"class":144},[138,2559,2560,2562,2564],{"class":140,"line":290},[138,2561,181],{"class":144},[138,2563,149],{"class":148},[138,2565,152],{"class":144},[138,2567,2568],{"class":140,"line":297},[138,2569,294],{"emptyLinePlaceholder":293},[138,2571,2572,2574,2576,2578],{"class":140,"line":307},[138,2573,145],{"class":144},[138,2575,302],{"class":148},[138,2577,906],{"class":214},[138,2579,152],{"class":144},[138,2581,2582,2584,2586,2588,2590,2592,2594,2596,2598,2600],{"class":140,"line":320},[138,2583,913],{"class":310},[138,2585,916],{"class":144},[138,2587,919],{"class":177},[138,2589,608],{"class":144},[138,2591,929],{"class":177},[138,2593,932],{"class":144},[138,2595,935],{"class":310},[138,2597,330],{"class":221},[138,2599,133],{"class":225},[138,2601,449],{"class":221},[138,2603,2604],{"class":140,"line":342},[138,2605,294],{"emptyLinePlaceholder":293},[138,2607,2608,2610,2613,2615,2617],{"class":140,"line":347},[138,2609,951],{"class":950},[138,2611,2612],{"class":954}," users",[138,2614,556],{"class":432},[138,2616,919],{"class":594},[138,2618,2619],{"class":177},"([])\n",[138,2621,2622,2624,2627,2629,2631,2633,2637],{"class":140,"line":359},[138,2623,951],{"class":950},[138,2625,2626],{"class":954}," loading",[138,2628,556],{"class":432},[138,2630,919],{"class":594},[138,2632,598],{"class":177},[138,2634,2636],{"class":2635},"sMrrN","false",[138,2638,617],{"class":177},[138,2640,2641,2643,2646,2648,2650,2652,2655],{"class":140,"line":367},[138,2642,951],{"class":950},[138,2644,2645],{"class":954}," error",[138,2647,556],{"class":432},[138,2649,919],{"class":594},[138,2651,598],{"class":177},[138,2653,2654],{"class":422},"null",[138,2656,617],{"class":177},[138,2658,2659],{"class":140,"line":379},[138,2660,294],{"emptyLinePlaceholder":293},[138,2662,2663,2666,2668,2671,2673],{"class":140,"line":385},[138,2664,2665],{"class":950},"async",[138,2667,1645],{"class":950},[138,2669,2670],{"class":594}," fetchUsers",[138,2672,354],{"class":144},[138,2674,317],{"class":144},[138,2676,2677,2680,2682,2684,2686],{"class":140,"line":391},[138,2678,2679],{"class":177},"  loading",[138,2681,426],{"class":144},[138,2683,1002],{"class":177},[138,2685,556],{"class":432},[138,2687,2688],{"class":2635}," true\n",[138,2690,2691,2694,2696,2698,2700],{"class":140,"line":396},[138,2692,2693],{"class":177},"  error",[138,2695,426],{"class":144},[138,2697,1002],{"class":177},[138,2699,556],{"class":432},[138,2701,2702],{"class":422}," null\n",[138,2704,2705],{"class":140,"line":406},[138,2706,294],{"emptyLinePlaceholder":293},[138,2708,2709,2712],{"class":140,"line":416},[138,2710,2711],{"class":310},"  try",[138,2713,317],{"class":144},[138,2715,2716,2718,2721,2723,2726,2729,2731,2733,2736,2738],{"class":140,"line":438},[138,2717,2269],{"class":950},[138,2719,2720],{"class":954}," response",[138,2722,556],{"class":432},[138,2724,2725],{"class":310}," await",[138,2727,2728],{"class":594}," fetch",[138,2730,598],{"class":323},[138,2732,336],{"class":221},[138,2734,2735],{"class":225},"https:\u002F\u002Fjsonplaceholder.typicode.com\u002Fusers",[138,2737,336],{"class":221},[138,2739,617],{"class":323},[138,2741,2742,2745,2747,2749,2751,2753,2755,2757,2760],{"class":140,"line":452},[138,2743,2744],{"class":177},"    users",[138,2746,426],{"class":144},[138,2748,1002],{"class":177},[138,2750,556],{"class":432},[138,2752,2725],{"class":310},[138,2754,2720],{"class":177},[138,2756,426],{"class":144},[138,2758,2759],{"class":594},"json",[138,2761,1907],{"class":323},[138,2763,2764,2767,2770,2773,2776,2778],{"class":140,"line":483},[138,2765,2766],{"class":144},"  }",[138,2768,2769],{"class":310}," catch",[138,2771,2772],{"class":323}," (",[138,2774,2775],{"class":177},"err",[138,2777,2083],{"class":323},[138,2779,1293],{"class":144},[138,2781,2782,2785,2787,2789,2791,2794,2796],{"class":140,"line":488},[138,2783,2784],{"class":177},"    error",[138,2786,426],{"class":144},[138,2788,1002],{"class":177},[138,2790,556],{"class":432},[138,2792,2793],{"class":177}," err",[138,2795,426],{"class":144},[138,2797,2798],{"class":177},"message\n",[138,2800,2801,2803,2806],{"class":140,"line":493},[138,2802,2766],{"class":144},[138,2804,2805],{"class":310}," finally",[138,2807,317],{"class":144},[138,2809,2810,2813,2815,2817,2819],{"class":140,"line":498},[138,2811,2812],{"class":177},"    loading",[138,2814,426],{"class":144},[138,2816,1002],{"class":177},[138,2818,556],{"class":432},[138,2820,2821],{"class":2635}," false\n",[138,2823,2824],{"class":140,"line":508},[138,2825,623],{"class":144},[138,2827,2828],{"class":140,"line":518},[138,2829,629],{"class":144},[138,2831,2832],{"class":140,"line":531},[138,2833,294],{"emptyLinePlaceholder":293},[138,2835,2836,2838],{"class":140,"line":537},[138,2837,1117],{"class":594},[138,2839,2840],{"class":177},"(fetchUsers)\n",[138,2842,2843,2845,2847],{"class":140,"line":547},[138,2844,181],{"class":144},[138,2846,302],{"class":148},[138,2848,152],{"class":144},[11,2850,2851],{},"Agora imagine que essa lógica de fetch (loading, error, dados) precisa ser reutilizada em vários lugares. Com a Composition API, você extrai para um composable:",[129,2853,2855],{"className":1212,"code":2854,"language":1214,"meta":134,"style":134},"\u002F\u002F useFetch.js\nimport { ref } from 'vue'\n\nexport function useFetch(url) {\n  const data = ref(null)\n  const loading = ref(false)\n  const error = ref(null)\n\n  async function execute() {\n    loading.value = true\n    error.value = null\n\n    try {\n      const response = await fetch(url)\n      data.value = await response.json()\n    } catch (err) {\n      error.value = err.message\n    } finally {\n      loading.value = false\n    }\n  }\n\n  return { data, loading, error, execute }\n}\n",[62,2856,2857,2862,2880,2884,2902,2919,2935,2951,2955,2969,2981,2993,2997,3004,3023,3044,3059,3076,3084,3097,3101,3105,3109,3131],{"__ignoreMap":134},[138,2858,2859],{"class":140,"line":141},[138,2860,2861],{"class":1250},"\u002F\u002F useFetch.js\n",[138,2863,2864,2866,2868,2870,2872,2874,2876,2878],{"class":140,"line":155},[138,2865,913],{"class":310},[138,2867,916],{"class":144},[138,2869,919],{"class":177},[138,2871,932],{"class":144},[138,2873,935],{"class":310},[138,2875,330],{"class":221},[138,2877,133],{"class":225},[138,2879,449],{"class":221},[138,2881,2882],{"class":140,"line":166},[138,2883,294],{"emptyLinePlaceholder":293},[138,2885,2886,2888,2890,2893,2895,2898,2900],{"class":140,"line":188},[138,2887,311],{"class":310},[138,2889,1645],{"class":950},[138,2891,2892],{"class":594}," useFetch",[138,2894,598],{"class":144},[138,2896,2897],{"class":1704},"url",[138,2899,1708],{"class":144},[138,2901,317],{"class":144},[138,2903,2904,2906,2909,2911,2913,2915,2917],{"class":140,"line":206},[138,2905,1657],{"class":950},[138,2907,2908],{"class":954}," data",[138,2910,556],{"class":432},[138,2912,919],{"class":594},[138,2914,598],{"class":323},[138,2916,2654],{"class":422},[138,2918,617],{"class":323},[138,2920,2921,2923,2925,2927,2929,2931,2933],{"class":140,"line":242},[138,2922,1657],{"class":950},[138,2924,2626],{"class":954},[138,2926,556],{"class":432},[138,2928,919],{"class":594},[138,2930,598],{"class":323},[138,2932,2636],{"class":2635},[138,2934,617],{"class":323},[138,2936,2937,2939,2941,2943,2945,2947,2949],{"class":140,"line":271},[138,2938,1657],{"class":950},[138,2940,2645],{"class":954},[138,2942,556],{"class":432},[138,2944,919],{"class":594},[138,2946,598],{"class":323},[138,2948,2654],{"class":422},[138,2950,617],{"class":323},[138,2952,2953],{"class":140,"line":281},[138,2954,294],{"emptyLinePlaceholder":293},[138,2956,2957,2960,2962,2965,2967],{"class":140,"line":290},[138,2958,2959],{"class":950},"  async",[138,2961,1645],{"class":950},[138,2963,2964],{"class":594}," execute",[138,2966,354],{"class":144},[138,2968,317],{"class":144},[138,2970,2971,2973,2975,2977,2979],{"class":140,"line":297},[138,2972,2812],{"class":177},[138,2974,426],{"class":144},[138,2976,1002],{"class":177},[138,2978,556],{"class":432},[138,2980,2688],{"class":2635},[138,2982,2983,2985,2987,2989,2991],{"class":140,"line":307},[138,2984,2784],{"class":177},[138,2986,426],{"class":144},[138,2988,1002],{"class":177},[138,2990,556],{"class":432},[138,2992,2702],{"class":422},[138,2994,2995],{"class":140,"line":320},[138,2996,294],{"emptyLinePlaceholder":293},[138,2998,2999,3002],{"class":140,"line":342},[138,3000,3001],{"class":310},"    try",[138,3003,317],{"class":144},[138,3005,3006,3009,3011,3013,3015,3017,3019,3021],{"class":140,"line":347},[138,3007,3008],{"class":950},"      const",[138,3010,2720],{"class":954},[138,3012,556],{"class":432},[138,3014,2725],{"class":310},[138,3016,2728],{"class":594},[138,3018,598],{"class":323},[138,3020,2897],{"class":177},[138,3022,617],{"class":323},[138,3024,3025,3028,3030,3032,3034,3036,3038,3040,3042],{"class":140,"line":359},[138,3026,3027],{"class":177},"      data",[138,3029,426],{"class":144},[138,3031,1002],{"class":177},[138,3033,556],{"class":432},[138,3035,2725],{"class":310},[138,3037,2720],{"class":177},[138,3039,426],{"class":144},[138,3041,2759],{"class":594},[138,3043,1907],{"class":323},[138,3045,3046,3049,3051,3053,3055,3057],{"class":140,"line":367},[138,3047,3048],{"class":144},"    }",[138,3050,2769],{"class":310},[138,3052,2772],{"class":323},[138,3054,2775],{"class":177},[138,3056,2083],{"class":323},[138,3058,1293],{"class":144},[138,3060,3061,3064,3066,3068,3070,3072,3074],{"class":140,"line":379},[138,3062,3063],{"class":177},"      error",[138,3065,426],{"class":144},[138,3067,1002],{"class":177},[138,3069,556],{"class":432},[138,3071,2793],{"class":177},[138,3073,426],{"class":144},[138,3075,2798],{"class":177},[138,3077,3078,3080,3082],{"class":140,"line":385},[138,3079,3048],{"class":144},[138,3081,2805],{"class":310},[138,3083,317],{"class":144},[138,3085,3086,3089,3091,3093,3095],{"class":140,"line":391},[138,3087,3088],{"class":177},"      loading",[138,3090,426],{"class":144},[138,3092,1002],{"class":177},[138,3094,556],{"class":432},[138,3096,2821],{"class":2635},[138,3098,3099],{"class":140,"line":396},[138,3100,382],{"class":144},[138,3102,3103],{"class":140,"line":406},[138,3104,623],{"class":144},[138,3106,3107],{"class":140,"line":416},[138,3108,294],{"emptyLinePlaceholder":293},[138,3110,3111,3113,3115,3117,3119,3121,3123,3125,3127,3129],{"class":140,"line":438},[138,3112,995],{"class":310},[138,3114,916],{"class":144},[138,3116,2908],{"class":177},[138,3118,608],{"class":144},[138,3120,2626],{"class":177},[138,3122,608],{"class":144},[138,3124,2645],{"class":177},[138,3126,608],{"class":144},[138,3128,2964],{"class":177},[138,3130,1841],{"class":144},[138,3132,3133],{"class":140,"line":452},[138,3134,629],{"class":144},[11,3136,3137],{},"E o componente fica limpo e expressivo:",[129,3139,3141],{"className":131,"code":3140,"language":133,"meta":134,"style":134},"\u003Cscript setup>\nimport { onMounted } from 'vue'\nimport { useFetch } from '.\u002Fcomposables\u002FuseFetch'\n\nconst {\n  data: users,\n  loading,\n  error,\n  execute\n} = useFetch('https:\u002F\u002Fjsonplaceholder.typicode.com\u002Fusers')\n\nonMounted(execute)\n\u003C\u002Fscript>\n",[62,3142,3143,3153,3171,3190,3194,3200,3211,3217,3223,3228,3246,3250,3257],{"__ignoreMap":134},[138,3144,3145,3147,3149,3151],{"class":140,"line":141},[138,3146,145],{"class":144},[138,3148,302],{"class":148},[138,3150,906],{"class":214},[138,3152,152],{"class":144},[138,3154,3155,3157,3159,3161,3163,3165,3167,3169],{"class":140,"line":155},[138,3156,913],{"class":310},[138,3158,916],{"class":144},[138,3160,929],{"class":177},[138,3162,932],{"class":144},[138,3164,935],{"class":310},[138,3166,330],{"class":221},[138,3168,133],{"class":225},[138,3170,449],{"class":221},[138,3172,3173,3175,3177,3179,3181,3183,3185,3188],{"class":140,"line":166},[138,3174,913],{"class":310},[138,3176,916],{"class":144},[138,3178,2892],{"class":177},[138,3180,932],{"class":144},[138,3182,935],{"class":310},[138,3184,330],{"class":221},[138,3186,3187],{"class":225},".\u002Fcomposables\u002FuseFetch",[138,3189,449],{"class":221},[138,3191,3192],{"class":140,"line":188},[138,3193,294],{"emptyLinePlaceholder":293},[138,3195,3196,3198],{"class":140,"line":206},[138,3197,951],{"class":950},[138,3199,317],{"class":144},[138,3201,3202,3205,3207,3209],{"class":140,"line":242},[138,3203,351],{"class":3204},"sTbKH",[138,3206,327],{"class":144},[138,3208,2612],{"class":954},[138,3210,339],{"class":144},[138,3212,3213,3215],{"class":140,"line":271},[138,3214,2679],{"class":954},[138,3216,339],{"class":144},[138,3218,3219,3221],{"class":140,"line":281},[138,3220,2693],{"class":954},[138,3222,339],{"class":144},[138,3224,3225],{"class":140,"line":290},[138,3226,3227],{"class":954},"  execute\n",[138,3229,3230,3232,3234,3236,3238,3240,3242,3244],{"class":140,"line":297},[138,3231,474],{"class":144},[138,3233,556],{"class":432},[138,3235,2892],{"class":594},[138,3237,598],{"class":177},[138,3239,336],{"class":221},[138,3241,2735],{"class":225},[138,3243,336],{"class":221},[138,3245,617],{"class":177},[138,3247,3248],{"class":140,"line":307},[138,3249,294],{"emptyLinePlaceholder":293},[138,3251,3252,3254],{"class":140,"line":320},[138,3253,1117],{"class":594},[138,3255,3256],{"class":177},"(execute)\n",[138,3258,3259,3261,3263],{"class":140,"line":342},[138,3260,181],{"class":144},[138,3262,302],{"class":148},[138,3264,152],{"class":144},[25,3266],{},[28,3268,3270],{"id":3269},"conclusão","Conclusão",[11,3272,3273],{},"A Options API e a Composition API não são inimigas: são ferramentas diferentes, cada uma com seu contexto ideal. A Options API continua sendo uma escolha válida e não vai desaparecer. Mas a Composition API representa a evolução natural do Vue, trazendo mais flexibilidade, melhor suporte a TypeScript e uma forma muito mais elegante de compartilhar lógica entre componentes.",[11,3275,3276,3277,100,3279,100,3281,3283],{},"Se você ainda não mergulhou de cabeça na Composition API, esse é o momento. A curva de aprendizado existe, especialmente se você vem de anos de Options API, mas uma vez que você entende ",[62,3278,1178],{},[62,3280,76],{},[62,3282,1117],{}," e a ideia de composables, o código começa a fluir de forma muito mais natural e organizada.",[11,3285,3286],{},"E a melhor parte: você pode começar devagar, introduzindo a Composition API gradualmente nos seus projetos, sem precisar jogar tudo fora.",[25,3288],{},[28,3290,3292],{"id":3291},"referências","Referências",[121,3294,3296],{"id":3295},"documentação-oficial","Documentação oficial",[56,3298,3299,3307],{},[59,3300,3301],{},[3302,3303,3304],"a",{"href":3304,"rel":3305},"https:\u002F\u002Fvuejs.org\u002Fguide\u002Fextras\u002Fcomposition-api-faq",[3306],"nofollow",[59,3308,3309],{},[3302,3310,3311],{"href":3311,"rel":3312},"https:\u002F\u002Fvuejs.org\u002Fguide\u002Ftypescript\u002Foptions-api",[3306],[121,3314,3316],{"id":3315},"artigos-e-conteúdos-complementares","Artigos e conteúdos complementares",[56,3318,3319,3325],{},[59,3320,3321],{},[3302,3322,3323],{"href":3323,"rel":3324},"https:\u002F\u002Fdev.to\u002Fsucodelarangela\u002Fvue3-options-api-vs-composition-api-1j09",[3306],[59,3326,3327],{},[3302,3328,3329],{"href":3329,"rel":3330},"https:\u002F\u002Fmedium.com\u002F@victor.souza2210\u002Fvue-js-composition-api-vs-options-api-qual-abordagem-escolher-a50a2f2f932b",[3306],[3332,3333,3334],"style",{},"html pre.shiki code .sG-J9, html code.shiki .sG-J9{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sqIbZ, html code.shiki .sqIbZ{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D}html pre.shiki code .sMo7A, html code.shiki .sMo7A{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .s7047, html code.shiki .s7047{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sF_wb, html code.shiki .sF_wb{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .s0vBq, html code.shiki .s0vBq{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .s3Er8, html code.shiki .s3Er8{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sdv8B, html code.shiki .sdv8B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .s0u7J, html code.shiki .s0u7J{--shiki-light:#E53935;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .s_k96, html code.shiki .s_k96{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .swu5b, html code.shiki .swu5b{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sFfmW, html code.shiki .sFfmW{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .sK_r7, html code.shiki .sK_r7{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0}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 .sFsEu, html code.shiki .sFsEu{--shiki-light:#9C3EDA;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .sVPC0, html code.shiki .sVPC0{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sk1zL, html code.shiki .sk1zL{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFAB70;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .s3afY, html code.shiki .s3afY{--shiki-light:#E2931D;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sMrrN, html code.shiki .sMrrN{--shiki-light:#FF5370;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sTbKH, html code.shiki .sTbKH{--shiki-light:#E53935;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}",{"title":134,"searchDepth":155,"depth":155,"links":3336},[3337,3338,3341,3342,3345,3347,3348,3349,3350,3351,3352,3353,3354,3355],{"id":30,"depth":155,"text":31},{"id":50,"depth":155,"text":51,"children":3339},[3340],{"id":123,"depth":166,"text":124},{"id":646,"depth":155,"text":647},{"id":695,"depth":155,"text":696,"children":3343},[3344],{"id":766,"depth":166,"text":767},{"id":1174,"depth":155,"text":3346},"Uma diferença importante: ref e .value",{"id":1379,"depth":155,"text":1380},{"id":1582,"depth":155,"text":1583},{"id":1967,"depth":155,"text":1968},{"id":2140,"depth":155,"text":2141},{"id":2164,"depth":155,"text":2165},{"id":2338,"depth":155,"text":2339},{"id":2397,"depth":155,"text":2398},{"id":3269,"depth":155,"text":3270},{"id":3291,"depth":155,"text":3292,"children":3356},[3357,3358],{"id":3295,"depth":166,"text":3296},{"id":3315,"depth":166,"text":3316},"2026-04-16T21:30:00-03:00","Entenda as diferenças entre Options API e Composition API no Vue 3 com exemplos práticos, reatividade, reutilização de código e quando usar cada abordagem.","md",[3363,3366,3369,3372],{"question":3364,"answer":3365},"Options API ou Composition API: qual usar no Vue 3?","Depende do contexto. A Options API tem curva de aprendizado menor e serve bem projetos pequenos ou componentes com responsabilidades delimitadas. A Composition API brilha em projetos de médio a grande porte, com TypeScript, reutilização de lógica e testes. Para projetos novos com Vue 3, a Composition API com script setup é a direção recomendada pela documentação e adotada por Nuxt 3, Pinia e VueUse.",{"question":3367,"answer":3368},"A Options API vai ser descontinuada no Vue?","Não. A documentação oficial deixa claro que nenhuma das duas abordagens será descontinuada. A Options API continua sendo uma escolha válida e coexiste com a Composition API.",{"question":3370,"answer":3371},"Posso usar Options API e Composition API no mesmo componente?","Sim. Você pode usar a função setup() como uma opção dentro de um componente Options API, o que é útil em migrações graduais. O que não é recomendado é misturar a sintaxe script setup com opções tradicionais como data() ou methods no mesmo componente.",{"question":3373,"answer":3374},"Por que preciso usar .value com ref na Composition API?","Porque ref() retorna um objeto reativo que encapsula o valor, permitindo ao Vue rastrear dependências. Dentro do script você acessa via .value; no template o Vue faz o unwrap automático, então você escreve apenas a variável. Para objetos e arrays você pode usar reactive(), que não precisa de .value.","\u002Fimages\u002Fblog\u002Fvue-options-vs-composition.png",{},"\u002Fblog\u002Fvue-composition-vs-options-api",{"title":5,"description":3360},"blog\u002Fvue-composition-vs-options-api",[1315,3381,3382,3383,44,37],"Vue3","JavaScript","Frontend",null,"THeAdoYrQSkf-E7IZULyJ20ZJZ1HiKLsceCXZXAQ1dI",1783037052063]