",{"type":25,"value":281}," component",{"type":25,"value":283},", in large part when it comes to styling, animation, page routing, global state management, data fetching, etc, you're in for a dizzying array of choice, and the choice in each problem category has their own set of longer term consequences and factors to consider in addition to deciding on React itself. It's enough not just to write its own article about, but you could argue each individual category demands its own article and deep dive.",{"type":19,"tag":27,"props":285,"children":286},{},[287,289,296,298,302],{"type":25,"value":288},"On the opposite end of this spectrum is ",{"type":19,"tag":81,"props":290,"children":293},{"href":291,"rel":292},"https://angular.dev/",[85],[294],{"type":25,"value":295},"Angular",{"type":25,"value":297},", which in large part comes with its own solutions to these problems and more as part of the framework itself. I admit my experience with Angular is minimal so I can't speak with as much confidence, but what I have gathered is that it is quite uncommon to stray from what is provided out of the box if your project needs require. This makes it an excellent option when you need to eliminate as much choice as possible, but I feel this can limit your ability to scale ",{"type":19,"tag":55,"props":299,"children":300},{},[301],{"type":25,"value":147},{"type":25,"value":303}," by a not insignificant amount.",{"type":19,"tag":27,"props":305,"children":306},{},[307,309,323,325,332,334,340,342,349,351,358,360,367,369,376],{"type":25,"value":308},"This is something I see as another huge strength of Vue. I think it strikes the perfect balance of not having so many options available to overwhelm, while still giving you the flexibility of selecting alternative or completely eliminating solutions when required. Vue has included a ",{"type":19,"tag":81,"props":310,"children":313},{"href":311,"rel":312},"https://vuejs.org/guide/built-ins/transition",[85],[314,316,322],{"type":25,"value":315},"baked in ",{"type":19,"tag":33,"props":317,"children":319},{"className":318},[],[320],{"type":25,"value":321},"\u003CTransition />",{"type":25,"value":281},{"type":25,"value":324}," for powerful animations for years, has built-in options for styling components using ",{"type":19,"tag":81,"props":326,"children":329},{"href":327,"rel":328},"https://vuejs.org/guide/scaling-up/sfc",[85],[330],{"type":25,"value":331},"Single File Components",{"type":25,"value":333}," and a ",{"type":19,"tag":33,"props":335,"children":337},{"className":336},[],[338],{"type":25,"value":339},"\u003Cstyle>",{"type":25,"value":341}," tag, and has powerful official core team developed solutions to ",{"type":19,"tag":81,"props":343,"children":346},{"href":344,"rel":345},"https://router.vuejs.org/",[85],[347],{"type":25,"value":348},"routing",{"type":25,"value":350}," and ",{"type":19,"tag":81,"props":352,"children":355},{"href":353,"rel":354},"https://pinia.vuejs.org/",[85],[356],{"type":25,"value":357},"global state management",{"type":25,"value":359},". Even more recently, there is a promising ",{"type":19,"tag":81,"props":361,"children":364},{"href":362,"rel":363},"https://pinia-colada.esm.dev/",[85],[365],{"type":25,"value":366},"data fetching solution",{"type":25,"value":368}," that models after the wonderful ",{"type":19,"tag":81,"props":370,"children":373},{"href":371,"rel":372},"https://tanstack.com/query",[85],[374],{"type":25,"value":375},"TanStack Query",{"type":25,"value":377}," for data fetching needs.",{"type":19,"tag":27,"props":379,"children":380},{},[381,383,388],{"type":25,"value":382},"The best part in my mind is literally every single one of these solutions are optional. Even the ",{"type":19,"tag":33,"props":384,"children":386},{"className":385},[],[387],{"type":25,"value":321},{"type":25,"value":389}," component, while a baked in core feature, will be code split from your bundle when using a capable bundler if it is unused in your project. Should you desire, you can seek out and use other available options. But there is beauty in the fact that you don't have to. These solutions are battle tested and proven to handle even the largest application's needs.",{"type":19,"tag":106,"props":391,"children":393},{"id":392},"vue-is-for-the-web",[394],{"type":25,"value":395},"Vue Is For The Web",{"type":19,"tag":27,"props":397,"children":398},{},[399,401,408,410,417,419,426,428,435],{"type":25,"value":400},"Depending on your needs, this can be a pro, a con, or mostly inconsequential. But Vue is in large part rooted in the web and the needs of web development. This doesn't mean it's impossible to write ",{"type":19,"tag":81,"props":402,"children":405},{"href":403,"rel":404},"https://nativescript-vue.org/",[85],[406],{"type":25,"value":407},"native applications using Vue syntax",{"type":25,"value":409},", but it is a much less common use case than the popular, powerful, and mature ecosystem around ",{"type":19,"tag":81,"props":411,"children":414},{"href":412,"rel":413},"https://reactnative.dev/",[85],[415],{"type":25,"value":416},"React Native",{"type":25,"value":418},". I'll be blunt; if your project requires a true native application (and not even a ",{"type":19,"tag":81,"props":420,"children":423},{"href":421,"rel":422},"https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps",[85],[424],{"type":25,"value":425},"PWA",{"type":25,"value":427}," can meet requirements), I am not even close to recommending a Vue based solution. React Native with ",{"type":19,"tag":81,"props":429,"children":432},{"href":430,"rel":431},"https://expo.dev/",[85],[433],{"type":25,"value":434},"Expo",{"type":25,"value":436}," is a wonderful developer experience that I can personally attest to and is absolutely worth using.",{"type":19,"tag":27,"props":438,"children":439},{},[440,442,449],{"type":25,"value":441},"But for people in my case who, outside of fringe projects, live and breathe the web, Vue is the most natural and comfortable fit. This feeling is not accidental either; Vue's template syntax was designed to be fully compliant HTML. From the ",{"type":19,"tag":81,"props":443,"children":446},{"href":444,"rel":445},"https://vuejs.org/guide/essentials/template-syntax",[85],[447],{"type":25,"value":448},"Vue docs",{"type":25,"value":450},":",{"type":19,"tag":452,"props":453,"children":454},"blockquote",{},[455],{"type":19,"tag":27,"props":456,"children":457},{},[458],{"type":25,"value":459},"All Vue templates are syntactically valid HTML that can be parsed by spec-compliant browsers and HTML parsers.",{"type":19,"tag":27,"props":461,"children":462},{},[463,465,472,474,480,482,489,491,497,499,505,507,513,515,521,523,530],{"type":25,"value":464},"This is a point that I feel often gets glossed over in ",{"type":19,"tag":81,"props":466,"children":469},{"href":467,"rel":468},"https://x.com/ThePrimeagen/status/1874975481034096685",[85],[470],{"type":25,"value":471},"discussions around Vue's template syntax",{"type":25,"value":473},". It's easy to knee jerk looking at a div with a ",{"type":19,"tag":33,"props":475,"children":477},{"className":476},[],[478],{"type":25,"value":479},"v-if",{"type":25,"value":481}," attribute inside it and feel a little disturbed at how far it strays from a more JavaScript-like syntax using JSX. But this decision was ",{"type":19,"tag":81,"props":483,"children":486},{"href":484,"rel":485},"https://x.com/youyuxi/status/1664643797853122562",[85],[487],{"type":25,"value":488},"not made on a whim or purely for stylistic reasons",{"type":25,"value":490},". It is this way because it still remains entirely valid HTML. In theory, if you copy Vue template code that does not rely on data binding directly from a component to an HTML file it will render without issues. No ",{"type":19,"tag":33,"props":492,"children":494},{"className":493},[],[495],{"type":25,"value":496},"className",{"type":25,"value":498}," or ",{"type":19,"tag":33,"props":500,"children":502},{"className":501},[],[503],{"type":25,"value":504},"htmlFor",{"type":25,"value":506}," attributes to rename, no stripping of ",{"type":19,"tag":33,"props":508,"children":510},{"className":509},[],[511],{"type":25,"value":512},"{#if value}",{"type":25,"value":514}," ",{"type":19,"tag":33,"props":516,"children":518},{"className":517},[],[519],{"type":25,"value":520},"{/if}",{"type":25,"value":522}," logic a-la ",{"type":19,"tag":81,"props":524,"children":527},{"href":525,"rel":526},"https://svelte.dev/docs/svelte/if",[85],[528],{"type":25,"value":529},"Svelte",{"type":25,"value":531},", it is (and always will be) HTML compliant.",{"type":19,"tag":27,"props":533,"children":534},{},[535],{"type":25,"value":536},"You can argue that trade-off doesn't matter, and honestly in most cases I think you're right! But going back to solutions that scale, if you're looking at a project that is intended to be maintained and running decades into the future; a future where the existence of individual frameworks like React/Vue/Svelte/Solid are uncertain, how far do you really want to stray from web standards? It may not matter to most, but it could be absolutely critical to some. Vue is full of solutions with this mindset. It feels like a framework built to be resilient to the test of time. It's not perfect, the migration from Vue 2 and Vue 3 a prime example of its own hurdles and challenges, but core fundamental choices have been made that shape the framework around the web and that is something I personally see value in and align with.",{"type":19,"tag":106,"props":538,"children":540},{"id":539},"conclusion",[541],{"type":25,"value":542},"Conclusion",{"type":19,"tag":27,"props":544,"children":545},{},[546,548,555],{"type":25,"value":547},"I could write much more about reasons I have made Vue my front-end framework of choice, but at the end of the day so much of it is personal preference and the needs of your team, your company, your project, your customer, etc. Vue is not always the best choice for me and the projects I work on day to day either. Sometimes it doesn't have a mature enough component library (or a community maintained component library at all) for the design system being used. Sometimes it's not even an option at all like when authoring a web extension for an existing application like the Jira Marketplace (shameless plug for an extension I help work on called ",{"type":19,"tag":81,"props":549,"children":552},{"href":550,"rel":551},"https://marketplace.atlassian.com/apps/1231953/clear-path-for-jira-visual-dependency-and-backlog-manager",[85],[553],{"type":25,"value":554},"Clear Path for Jira",{"type":25,"value":556}," ๐
).",{"type":19,"tag":27,"props":558,"children":559},{},[560,562,569],{"type":25,"value":561},"Also, as much as I love Vue, I also love React despite its issues, and have given Svelte a passing glance and approving look from time to time even though I have yet to use it beyond a playground. ",{"type":19,"tag":81,"props":563,"children":566},{"href":564,"rel":565},"https://svelte.dev/blog/runes",[85],[567],{"type":25,"value":568},"Svelte Runes",{"type":25,"value":570}," are an excellent example of the framework evolving in a direction I can align with, making extracting reusable logic outside of Svelte components much more straightforward and closer to the mindset of React's hooks and Vue's composition API.",{"type":19,"tag":27,"props":572,"children":573},{},[574],{"type":25,"value":575},"This is not me trying to sell you on Vue. I have nothing to gain from that anyway outside of the possibility of being able to use it on more projects in the future. It's more to explain my own reasons for enjoying it and maybe give you some food for thought the next time you're starting a web project. I also have this feeling when consuming content in the wider web development ecosystem that Vue and Nuxt are mostly glossed over in framework discussions and seemingly only mentioned as afterthoughts if mentioned at all. I would personally like to see this shift, and more firmly place Vue up with the greats and give it the recognition that I believe it deserves. Thanks for reading!",{"title":9,"searchDepth":577,"depth":577,"links":578},2,[579,580,581,582],{"id":108,"depth":577,"text":111},{"id":213,"depth":577,"text":216},{"id":392,"depth":577,"text":395},{"id":539,"depth":577,"text":542},"markdown","content:articles:why-i-like-vue.md","content","articles/why-i-like-vue.md","articles/why-i-like-vue","md",{"_path":590,"_dir":7,"_draft":8,"_partial":8,"_locale":9,"title":591,"description":592,"date":593,"status":13,"discussion":594,"body":595,"_type":583,"_id":829,"_source":585,"_file":830,"_stem":831,"_extension":588},"/articles/hello-world","Hello World","My plan for attempting to begin a path of writing; ideas for keeping me from feeling friction when authoring, free from being locked in to a specific service or set of tools, and of course the first step after getting set up... writing the post you're reading right now!","2024-06-04T20:00:00","https://github.com/danielwaltz/content/discussions/1",{"type":16,"children":596,"toc":824},[597,602,606,612,624,645,656,662,667,705,717,738,786,792,797,819],{"type":19,"tag":20,"props":598,"children":600},{"id":599},"hello-world",[601],{"type":25,"value":591},{"type":19,"tag":27,"props":603,"children":604},{},[605],{"type":25,"value":592},{"type":19,"tag":106,"props":607,"children":609},{"id":608},"why",[610],{"type":25,"value":611},"Why?",{"type":19,"tag":27,"props":613,"children":614},{},[615,617,622],{"type":25,"value":616},"I have had some interest in writing blog posts and content about my experiences as a developer and sharing some of the things I have learned in my career for many years now. While I could attribute the majority of the reason for why I haven't started down this path before to laziness (a very common and arguably beneficial trait for developers), I have also wrestled with imposter syndrome and consumed so much from other authors and developers that I admire (and crediting them absolutely deserves a post by itself) that I never ",{"type":19,"tag":55,"props":618,"children":619},{},[620],{"type":25,"value":621},"truly",{"type":25,"value":623}," ever felt like it's a space I could meaningfully contribute to.",{"type":19,"tag":27,"props":625,"children":626},{},[627,629,636,638,643],{"type":25,"value":628},"What changed now? Frankly, I can't say it's any specific event or moment. I've been working in the development industry for ",{"type":19,"tag":81,"props":630,"children":633},{"href":631,"rel":632},"https://www.linkedin.com/in/danielbwaltz/",[85],[634],{"type":25,"value":635},"15 years",{"type":25,"value":637}," now, so perhaps it's just my time. ๐ And honestly, in this age of explosive generative AI growth, it almost feels like now might be about the ",{"type":19,"tag":55,"props":639,"children":640},{},[641],{"type":25,"value":642},"worst",{"type":25,"value":644}," time to start exploring hand-authoring text based content. But hey, someone's still gotta feed the machine right? So here we are!",{"type":19,"tag":27,"props":646,"children":647},{},[648,650],{"type":25,"value":649},"I feel some excitement to start dipping my toes in this, but another aspect that really gnawed at me is finding the right platform and tools for me to write without feeling blocked, locked in, or having barriers to actually start writing. So obviously, as a developer, this was the path that I had to explore first! ",{"type":19,"tag":651,"props":652,"children":653},"sup",{},[654],{"type":25,"value":655},"heh",{"type":19,"tag":106,"props":657,"children":659},{"id":658},"how",[660],{"type":25,"value":661},"How?",{"type":19,"tag":27,"props":663,"children":664},{},[665],{"type":25,"value":666},"I had a high level idea for what I wanted:",{"type":19,"tag":668,"props":669,"children":670},"ol",{},[671,685,690,695,700],{"type":19,"tag":672,"props":673,"children":674},"li",{},[675,677,683],{"type":25,"value":676},"Simple file based content using markdown ",{"type":19,"tag":33,"props":678,"children":680},{"className":679},[],[681],{"type":25,"value":682},".md",{"type":25,"value":684}," for longevity and scripting ability",{"type":19,"tag":672,"props":686,"children":687},{},[688],{"type":25,"value":689},"Able to use publicly available services and zero cost software (ideally open source)",{"type":19,"tag":672,"props":691,"children":692},{},[693],{"type":25,"value":694},"Content lives separately from where it is consumed",{"type":19,"tag":672,"props":696,"children":697},{},[698],{"type":25,"value":699},"Full rich text editor experience",{"type":19,"tag":672,"props":701,"children":702},{},[703],{"type":25,"value":704},"A workflow that is as simple as \"save file โ see content\"",{"type":19,"tag":27,"props":706,"children":707},{},[708,710,715],{"type":25,"value":709},"You might be thinking, as I sure was as I was theorizing this plan, that this doesn't sound simple at all. ๐ Honestly... you would be right. I can joke and say that this is just the ",{"type":19,"tag":55,"props":711,"children":712},{},[713],{"type":25,"value":714},"way of the developerโข๏ธ",{"type":25,"value":716},", but in reality this is what I really felt was required for me to actually start writing. If it's as simple as opening an app on my Mac, creating a new file, and writing, what excuses do I have left?",{"type":19,"tag":27,"props":718,"children":719},{},[720,722,729,731,736],{"type":25,"value":721},"As fate would have it, late one night a spark of inspiration hit. I had a vague familiarity with an application called ",{"type":19,"tag":81,"props":723,"children":726},{"href":724,"rel":725},"https://obsidian.md/",[85],[727],{"type":25,"value":728},"Obsidian",{"type":25,"value":730}," after briefly using Notion at my job and going down a rabbit role after really enjoying the experience. I had read somewhere that it was ",{"type":19,"tag":55,"props":732,"children":733},{},[734],{"type":25,"value":735},"mostly",{"type":25,"value":737}," markdown based, which fit my first criteria of authoring my content in plain markdown files perfectly. Check!",{"type":19,"tag":27,"props":739,"children":740},{},[741,743,750,752,759,761,766,768,775,777,784],{"type":25,"value":742},"After downloading it I discovered a vibrant community marketplace and spotted a ",{"type":19,"tag":81,"props":744,"children":747},{"href":745,"rel":746},"https://github.com/denolehov/obsidian-git",[85],[748],{"type":25,"value":749},"community plugin",{"type":25,"value":751}," that enables you to connect with and automatically sync your content to a ",{"type":19,"tag":81,"props":753,"children":756},{"href":754,"rel":755},"https://github.com/danielwaltz/content",[85],[757],{"type":25,"value":758},"public GitHub repository",{"type":25,"value":760},". This then triggered a memory of my framework of choice at the moment ",{"type":19,"tag":81,"props":762,"children":764},{"href":166,"rel":763},[85],[765],{"type":25,"value":195},{"type":25,"value":767}," having a content module that can ",{"type":19,"tag":81,"props":769,"children":772},{"href":770,"rel":771},"https://content.nuxt.com/get-started/configuration#sources",[85],[773],{"type":25,"value":774},"pull from external GitHub repos",{"type":25,"value":776}," for content with the ability to query and style content pretty much however you want. So I integrated it in my ",{"type":19,"tag":81,"props":778,"children":781},{"href":779,"rel":780},"https://github.com/danielwaltz/daniel-waltz",[85],[782],{"type":25,"value":783},"personal website",{"type":25,"value":785}," ๐ and wired everything up and bingo bingo presto!",{"type":19,"tag":106,"props":787,"children":789},{"id":788},"wait-really",[790],{"type":25,"value":791},"Wait... really?",{"type":19,"tag":27,"props":793,"children":794},{},[795],{"type":25,"value":796},"Actually, yes! I absolutely thought there would be a catch (especially the connection between Nuxt and my GitHub repo), but truly it ended up being that simple. No doubt using a public repo made things much easier for lack of requiring authentication, but still. This was exciting to me, and this simplicity is exactly what drew me to using Nuxt in the first place!",{"type":19,"tag":27,"props":798,"children":799},{},[800,802,808,810,817],{"type":25,"value":801},"If you're curious about how this is implemented and maybe want to try this out for yourself, the source code for my website is available ",{"type":19,"tag":81,"props":803,"children":805},{"href":779,"rel":804},[85],[806],{"type":25,"value":807},"here",{"type":25,"value":809},"! Plus, if you would like to see specifically the changes were required when adding this to an existing Nuxt project, check out ",{"type":19,"tag":81,"props":811,"children":814},{"href":812,"rel":813},"https://github.com/danielwaltz/daniel-waltz/commit/adbe60e2b95e3a77875fe2da5e5f5e0b4b40e941#diff-5977891bf10802cdd3cde62f0355105a1662e65b02ae4fb404a27bb0f5f53a07",[85],[815],{"type":25,"value":816},"this commit",{"type":25,"value":818}," in particular.",{"type":19,"tag":27,"props":820,"children":821},{},[822],{"type":25,"value":823},"So consider this a practice run. The first (and maybe also the last) post I have ever written. Thanks for reading!",{"title":9,"searchDepth":577,"depth":577,"links":825},[826,827,828],{"id":608,"depth":577,"text":611},{"id":658,"depth":577,"text":661},{"id":788,"depth":577,"text":791},"content:articles:hello-world.md","articles/hello-world.md","articles/hello-world",["Reactive",833],{},["Set"],["ShallowReactive",836],{"articles":-1},true,"/articles"]