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