<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vue PDF Viewer</title>
    <description>The latest articles on DEV Community by Vue PDF Viewer (@vue-pdf-viewer).</description>
    <link>https://dev.to/vue-pdf-viewer</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F9659%2Fa855b275-485d-4335-86e4-6b27642b5a96.jpg</url>
      <title>DEV Community: Vue PDF Viewer</title>
      <link>https://dev.to/vue-pdf-viewer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vue-pdf-viewer"/>
    <language>en</language>
    <item>
      <title>🚀 6 Open-Source PDF Viewer and Annotation libraries every Vue developers should know [2025] ✨</title>
      <dc:creator>Anson Ch</dc:creator>
      <pubDate>Tue, 09 Sep 2025 10:03:53 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/6-open-source-pdf-viewer-and-annotation-libraries-every-vue-developers-should-know-2025-7oc</link>
      <guid>https://dev.to/vue-pdf-viewer/6-open-source-pdf-viewer-and-annotation-libraries-every-vue-developers-should-know-2025-7oc</guid>
      <description>&lt;p&gt;PDF Viewer and annotation features have become standard in modern web apps. Whether you're building dashboards, admin panels, or document platforms, users expect smooth PDF reading experience and the ability to mark up files with comments, highlights, or signature, all without ever leaving your site.&lt;/p&gt;

&lt;p&gt;For Vue developers, knowing which open-source PDF Viewer and annotation libraries work best can save hours of trial and error. You can even mix and match libraries to tackle multiple use cases, from fast document rendering to advanced markup. The right solution solve the hassle of juggling pop-ups, downloads, or iframe workarounds.&lt;/p&gt;

&lt;p&gt;Here're are the six open-source libraries you need to know as you look for the ideal fit for your next Vue.js project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehidbdymnupf7zp6ybdp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehidbdymnupf7zp6ybdp.gif" alt="Gif on bring it on" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Before we jump into the list of libraries, here’s something worth checking out: a flexible &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_content=6-open-source-pdf-viewer-and-annotation-libraries-every-vue-developers-should-know"&gt;Vue PDF&lt;/a&gt; rendering solution built specifically for Vue 3.&lt;/p&gt;

&lt;p&gt;Whether you’re building a dashboard, AI PDF chat tool, or internal tool, Vue PDF Viewer makes it easy to embed PDF viewing right inside your app. It supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile responsive viewing&lt;/li&gt;
&lt;li&gt;Built-in toolbar and search&lt;/li&gt;
&lt;li&gt;Text selection, zoom, thumbnails, and more&lt;/li&gt;
&lt;li&gt;Easy theming and layout overrides&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With minimal setup and strong TypeScript support, it’s a solid option if you’re looking for an all-in-one PDF solution with modern features and clean design.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fghuuzlxeymc3vh66cmzr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fghuuzlxeymc3vh66cmzr.png" alt="Screenshot of Vue PDF Viewer" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Open-Source PDF Viewer and Annotation Libraries Matter for Vue Developers
&lt;/h2&gt;

&lt;p&gt;Building robust document features in Vue has moved way beyond just dropping a PDF link on a page. Users want to read, highlight, mark up, and sign documents right inside your app. Open-source PDF viewer and annotation libraries make this level of integration possible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost Saving:&lt;/strong&gt; No hidden usage or licensing fee. No vendor lock-in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency:&lt;/strong&gt; You can inspect, debug, and improve the code, with full visibility into how things work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility and Control:&lt;/strong&gt; Customize, extend, or combine libraries to fit your app’s needs without being boxed in.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Vue-Focused PDF Viewer Libraries
&lt;/h2&gt;

&lt;p&gt;Before diving into specific libraries, it’s important to understand PDF.js. Most open-source PDF Viewer libraries for Vue are built on top of it. It's the backbone for rendering, navigating, and interacting with PDF files inside your browser. &lt;/p&gt;

&lt;h3&gt;
  
  
  What is Mozilla PDF.js?
&lt;/h3&gt;

&lt;p&gt;PDF.js is an open-source JavaScript library built and maintained by Mozilla that allows you to render and interact with PDF files directly in modern web browsers. It relies on standard web technologies, making it highly compatible and easy to integrate into frontend stacks like Vue.&lt;/p&gt;

&lt;p&gt;This tool isn’t just for displaying PDF pages. It gives you the control to create a full PDF Viewer with built-in zoom, search and text selection. For Vue developers, that means you can keep users in your app and offer rich document features, instead of handing them off to third-party tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Render large files with search, zoom, and page navigation&lt;/li&gt;
&lt;li&gt;No license restrictions and vendor lock-in. Use, modify, and ship updates as you see fit&lt;/li&gt;
&lt;li&gt;Responsive viewing for most modern browsers&lt;/li&gt;
&lt;li&gt;Easily integrate with other libraries focused on annotation or signature, creating a PDF experience tailored for your users' needs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PDF.js is often used in websites, web apps, and custom projects where you just want to keep everything in the browser. It’s a solid pick if you want to display documents in a way that just works for everyone. As of July 2025,&lt;code&gt;pdfjs-dist&lt;/code&gt; has over 51,400 stars with over 390 contributors on GitHub and an average weekly downloads count of over 4,000,000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mozilla/pdf.js" rel="noopener noreferrer"&gt;https://github.com/mozilla/pdf.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fem9q3yzykr0plhwyliee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fem9q3yzykr0plhwyliee.png" alt="Screenshot of PDF.js" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  vue-pdf-embed
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;vue-pdf-embed&lt;/code&gt;, built on top of PDF.js, offers Vue developers an easy way to embed PDF viewing capabilities into any page or dashboard. It provides an easy-to-use component designed for Vue 2 and Vue 3 to display PDFs without complex setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controlled rendering: Letting you manage how and when pages display.&lt;/li&gt;
&lt;li&gt;Support for password-protected PDF: Keep sensitive files secure and accessible only to the right people.&lt;/li&gt;
&lt;li&gt;Selectable text: Great for users who need to copy or search document content.&lt;/li&gt;
&lt;li&gt;Support annotation layer: PDF with annotations can be displayed easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need just the basics or want a lightweight viewer with proven usage, this library fits the bill. As of July 2025,&lt;code&gt;vue-pdf-embed&lt;/code&gt; has over 890 stars, 25 contributors, and an average weekly downloads count of over 59,000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hrynko/vue-pdf-embed" rel="noopener noreferrer"&gt;https://github.com/hrynko/vue-pdf-embed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fulp0c4nw9e78ne50mg0v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fulp0c4nw9e78ne50mg0v.png" alt="Screenshot of vue-pdf-embed" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  @tato30/vue-pdf
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;@tato30/vue-pdf&lt;/code&gt; is a popular Vue wrapper for Mozilla’s PDF.js. It brings deep PDF rendering directly into Vue projects, allowing you to avoid custom wiring with PDF.js’s raw API. It supports many core features of PDF.js and makes it easier to integrate into Vue or Nuxt applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple integration if your app is already built on Vue 3&lt;/li&gt;
&lt;li&gt;Provide functions like search, zoom level and rotate&lt;/li&gt;
&lt;li&gt;Render control for text, annotations, and optional layers&lt;/li&gt;
&lt;li&gt;Allow custom watermark on PDF pages to protect your content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're looking for than a simple PDF reader, this library is great for complex interactions. As of July 2025,&lt;code&gt;@tato30/vue-pdf&lt;/code&gt; has over 589 stars with 9 contributors on GitHub and an average weekly downloads count of over 25,000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TaTo30/vue-pdf" rel="noopener noreferrer"&gt;https://github.com/TaTo30/vue-pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxxa25770yq1x56t8w6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxxa25770yq1x56t8w6r.png" alt="Screenshot of @tato30/vue-pdf" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  vue-pdf
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;vue-pdf&lt;/code&gt; library (not to be confused with others with similar names) is an older lightweight wrapper around PDF.js, specifically tailored for Vue applications. By using &lt;code&gt;vue-pdf&lt;/code&gt;, Vue developers can enjoy the benefits of PDF.js without needing to manage the complex JavaScript integration manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast single-page or multi-page PDF rendering&lt;/li&gt;
&lt;li&gt;Simple navigation controls, print and zoom&lt;/li&gt;
&lt;li&gt;Provide events for loading, progress, and error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vue-pdf is ideal for applications that require basic PDF display. It's a practical option for small projects and MVPs where ease of use and quick implementation are prioritized. As of July 2025,&lt;code&gt;vue-pdf&lt;/code&gt; as over 2,300 stars with 20 contributors on GitHub and an average weekly downloads count of over 17,000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/FranckFreiburger/vue-pdf" rel="noopener noreferrer"&gt;https://github.com/FranckFreiburger/vue-pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5j4ydq6i8bsk5wr0f1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5j4ydq6i8bsk5wr0f1h.png" alt="Screenshot of vue-pdf" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ The library has not been updated since Jun 2021 so use it with caution. Remember to update &lt;code&gt;pdf-dist&lt;/code&gt; version to avoid potential security and compatibility concerns.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Open-Source PDF Annotation Libraries for Vue
&lt;/h2&gt;

&lt;p&gt;Modern applications demand more than just displaying PDFs. Users now expect to draw, highlight, and leave comments on documents, all inside the browser. Getting annotation tools right can make or break PDF Viewing experience in a Vue.js project. Here's how three powerful open-source options stack up for bringing annotations to life in Vue apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  pdf-lib
&lt;/h3&gt;

&lt;p&gt;If you are looking to programmatically annotate PDFs in your Vue project, &lt;code&gt;pdf-lib&lt;/code&gt; stands out. This open-source JavaScript library lets you work with PDFs in the browser and on the server. It’s not just a PDF annotator, it supports form creation, content editing, and even digital signatures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add new shapes, signatures, or freehand scribbles.&lt;/li&gt;
&lt;li&gt;Highlight text sections in a way that’s easy for users to spot later.&lt;/li&gt;
&lt;li&gt;Attach notes or pop-up comments to any part of the PDF.&lt;/li&gt;
&lt;li&gt;Has no external dependencies, keeping your bundle size manageable and integrations simple.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a clean API, Vue coders can use &lt;code&gt;pdf-lib&lt;/code&gt; to create or update complex annotations dynamically, storing them in the user’s browser or syncing them with a backend as needed. As of July 2025, &lt;code&gt;pdf-lib&lt;/code&gt; has over 7,700 stars with 42 contributors on GitHub and an average weekly downloads count of over 1,480,000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Hopding/pdf-lib" rel="noopener noreferrer"&gt;https://github.com/Hopding/pdf-lib&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Few666grc1mkuy357fcot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Few666grc1mkuy357fcot.png" alt="Screenshot of pdf-lib" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ The library has not been updated since Nov 2021 so use it with caution. There is a &lt;a href="https://github.com/cantoo-scribe/pdf-lib" rel="noopener noreferrer"&gt;forked&lt;/a&gt; version but I'm unable to verify its current status.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  sinatayebati/pdfjs-annotation
&lt;/h3&gt;

&lt;p&gt;For devs who want a faster setup, sinatayebati/pdfjs-annotation offers a Vue-based annotation UI, tightly wrapped around Mozilla PDF.js. You get a ready-to-use PDF Viewer plus a complete set of annotation features built right in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Annotation tools includes shapes, highlights, free text and more&lt;/li&gt;
&lt;li&gt;Designed to overlay on PDF.js within a Vue context, so your data stays reactive and easy to sync.&lt;/li&gt;
&lt;li&gt;Annotation widgets and toolbars are part of the package, so you don't have to build them from scratch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This wrapper takes a lot of guesswork out of document enhancement. You can enrich PDF files with highlights or notes and never leave the app’s single-page flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sinatayebati/pdfjs-annotation" rel="noopener noreferrer"&gt;https://github.com/sinatayebati/pdfjs-annotation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bwvtpux3nhm0rmfxfw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bwvtpux3nhm0rmfxfw9.png" alt="Screenshot of sinatayebati/pdfjs-annotation" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  That's right, Mozilla PDF.js
&lt;/h3&gt;

&lt;p&gt;Did you know that PDF.js has started rolling out annotation editor back in &lt;a href="https://github.com/mozilla/pdf.js/releases/tag/v3.0.279" rel="noopener noreferrer"&gt;v3.0.279&lt;/a&gt; released in October 2022. Just for context, the most recent version of PDF.js is &lt;a href="https://github.com/mozilla/pdf.js/releases/tag/v5.3.93" rel="noopener noreferrer"&gt;5.3.93&lt;/a&gt;. Surprising there isn't a lot information on how to utilize annotation functions in PDF.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highlight, underline, strikethrough text or areas for instant visual cues&lt;/li&gt;
&lt;li&gt;Drop virtual notes anywhere in your PDF to collaborate easily&lt;/li&gt;
&lt;li&gt;Add new shapes, images, or free text to enrich your PDF file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Knowing how to integrate and extend PDF.js can turn your app from a simple PDF viewer into a dynamic document experience that users will love.&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://mozilla.github.io/pdf.js/web/viewer.html" rel="noopener noreferrer"&gt;https://mozilla.github.io/pdf.js/web/viewer.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn33clbithjzz5nafjw6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn33clbithjzz5nafjw6e.png" alt="Screenshot of PDF.js with annotations" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How Combining Libraries Boosts PDF Functionality
&lt;/h2&gt;

&lt;p&gt;If a single library does not all of your use cases, you could consider combining libraries in your Vue project. Think of your PDF stack like LEGO blocks. You can mix libraries—one for fast viewing, one for deep annotation, another for e-signatures or forms—to create the setup your project actually needs. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For instance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with &lt;code&gt;vue-pdf-embed&lt;/code&gt; for light, fast viewing inside dashboards&lt;/li&gt;
&lt;li&gt;Bring in &lt;code&gt;pdf-lib&lt;/code&gt; if you want to annotate PDF or handle form data behind the scenes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This mix-and-match method keeps your app flexible. When a new requirement or feature comes along, you just swap or add another piece, rather than rebuilding from scratch. Combining open-source libraries helps you tailor the user experience and stay in control.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Choose the Right Library for Your Project
&lt;/h2&gt;

&lt;p&gt;With so many open-source options available, making the right choice starts with focusing on what your users need and what works for your workflow. A good fit saves you time, keeps your app smooth, and lets your users read, search, and mark up documents without any distractions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vue Compatibility&lt;/strong&gt; - Libraries based on Vue take advantage of hooks, props, and state for smooth integration. Generic JS tools may need more setup or “glue code.”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Know Your Use Cases&lt;/strong&gt; - By mapping out your core requirements, you won’t get distracted by extra features you’ll never use. You’ll hone in on what matters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Community and Documentation - A powerful library is only as good as its documentation and community. Scan GitHub stars and check for active issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt; - Performance matters, especially for web apps that serve large or image-heavy documents. Explore if the libraries uses techniques like lazy loading or virtualization to keep things fast&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Real-World Testing
&lt;/h2&gt;

&lt;p&gt;Finally, never trust a demo alone. Pull in a few sample PDFs from your users with a quick prototype. Try different annotation workflows. Make sure font rendering, zoom, and navigation all work as expected. A little time spent testing now can save you endless fixes down the road.&lt;/p&gt;




&lt;p&gt;If you liked this article, take a look at a library for &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_content=6-open-source-pdf-viewer-and-annotation-libraries-every-vue-developers-should-know"&gt;Vue PDF&lt;/a&gt;, a modern PDF viewing solution built specifically for Vue 3 apps. It’s designed to drop smoothly into your Vue ecosystem, whether you’re using PrimeVue, Vuetify, or your own custom UI setup.&lt;/p&gt;

&lt;p&gt;Vue PDF Viewer helps you build polished document experiences without starting from scratch. Features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vue 3 Composition API support&lt;/li&gt;
&lt;li&gt;Responsive UI with thumbnails, toolbars, and other tools such as highlights, zoom and search&lt;/li&gt;
&lt;li&gt;Works with both local and remote files&lt;/li&gt;
&lt;li&gt;Clean APIs and typed props for full developer control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vue PDF Viewer is actively maintained and developer-focused. If you’re building serious document functionality in Vue, it’s worth a look 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nu0lkpijspajsuzw7f4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nu0lkpijspajsuzw7f4.png" alt="Screenshot of Vue PDF Viewer" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>nuxt</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🌟 Vue 3 UI Libraries: 6 Most Popular Picks for 2025 🚀</title>
      <dc:creator>Anson Ch</dc:creator>
      <pubDate>Tue, 04 Feb 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/vue-3-ui-libraries-6-most-popular-picks-for-2025-2m7l</link>
      <guid>https://dev.to/vue-pdf-viewer/vue-3-ui-libraries-6-most-popular-picks-for-2025-2m7l</guid>
      <description>&lt;p&gt;&lt;em&gt;Edit: Back in 2024, I shared a list of the "&lt;/em&gt;&lt;a href="https://blog.vue-pdf-viewer.dev/top-6-vuejs-ui-libraries-vue-3-trending-in-2024" rel="noopener noreferrer"&gt;&lt;em&gt;⚡️Top 6 Vue.js UI Libraries (Vue 3) Trending in 2024 🔥&lt;/em&gt;&lt;/a&gt;&lt;em&gt;". Now in 2025 I couldn’t resist revisiting this topic to see what has changed and which libraries are still making waves 🎉&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you have been working with Vue.js for a while, you will know how it hooks you with its simplicity, flexibility, and sheer performance. It has been my go-to framework for years, and I am always on the lookout for tools that make developing with Vue even better. UI component libraries are some of the best tools in that category, they save so much time and help you build beautiful, responsive interfaces without breaking a sweat.&lt;/p&gt;

&lt;p&gt;Since Vue 3 officially became the default after Vue 2’s retirement at the end of 2023 (RIP Vue 2 👋), the community has rallied around libraries designed specifically for Vue 3. In this article, I am sharing &lt;strong&gt;6 of the most popular Vue.js UI libraries for 2025&lt;/strong&gt;—libraries I have loved using or seen gain serious momentum this year.&lt;/p&gt;

&lt;p&gt;Whether you are just starting with Vue or deep into building your next big project, these libraries are worth a look. Let’s dive in!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia4.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExYzFicDFwcWlkbjJlb2xzdnF0NTdxamh1ODJkMXltY2VteXNvbGNvMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F2cehTmp8rASyunE10R%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia4.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExYzFicDFwcWlkbjJlb2xzdnF0NTdxamh1ODJkMXltY2VteXNvbGNvMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F2cehTmp8rASyunE10R%2Fgiphy.gif" width="480" height="480"&gt;&lt;/a&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  Vue PDF Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;Just a quick background about what I’m working on. &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=vue-3-ui-libraries-6-most-popular-picks-for-2025"&gt;Vue PDF Viewer&lt;/a&gt; renders the PDF viewer on your Vue or Nuxt websites so that your users can interact with your PDF document without leaving your sites. The component has over 20 features including theme customization, built-in localization, web responsive and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjky806ks7bv7fmdow1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjky806ks7bv7fmdow1v.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’d love for you to check &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=vue-3-ui-libraries-6-most-popular-picks-for-2025"&gt;Vue PDF Viewer&lt;/a&gt; out! Your support means the world and helps me create more awesome content like this. ❤️&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Vuetify
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbembd8bmpuizeznomy8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbembd8bmpuizeznomy8e.png" alt="Vuetify" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First up is &lt;strong&gt;Vuetify&lt;/strong&gt;, the OG Material Design-based UI library for Vue.js. It provides over 100 customizable components for creating beautiful and responsive user interfaces. With its modular design, developers can selectively import components, which keeps the bundle size small and improve performance.&lt;/p&gt;

&lt;p&gt;Additionally, Vuetify integrates seamlessly with Nuxt 3 and features powerful theming capabilities where developers can customize their application style and match it with their brand.&lt;/p&gt;

&lt;p&gt;As of January 2025, Vuetify has over 40,000 stars (from 38,800 stars in 2024) on GitHub and an average weekly downloads count of close to 600,000. (The &lt;a href="https://npmtrends.com/vuetify" rel="noopener noreferrer"&gt;trend line&lt;/a&gt; seems to be growing steadily over the years)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Over 80 pre-designed components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for server-side rendering and single-page applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensive documentation and active community support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more on &lt;a href="https://vuetifyjs.com" rel="noopener noreferrer"&gt;https://vuetifyjs.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. PrimeVue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fna7a2lj3tehi086ndfdp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fna7a2lj3tehi086ndfdp.png" alt="PrimeVue" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PrimeVue&lt;/strong&gt; is a rich set of open-source UI components for Vue applications powered by PrimeTek. It offers over 90 components and 200+ icons making it one of the most comprehensive libraries in the Vue.js community. It's a lightweight library with exclusive Tailwind CSS integration, enabling developers to build complex enterprise-level applications with ease.&lt;/p&gt;

&lt;p&gt;PrimeVue also features an intuitive API, allowing developers to quickly customize the components to achieve their desired designs.&lt;/p&gt;

&lt;p&gt;As of January 2025, PrimeVue has over 11,000 stars (from 6,800 stars in 2024) on GitHub and an average weekly downloads count of over 280,000 (&lt;a href="https://npmtrends.com/primevue" rel="noopener noreferrer"&gt;Huge increase&lt;/a&gt; from around 170,000 downloads in 2024).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Over 80 versatile components, including charts and data tables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accessibility features compliant with WAI-ARIA.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Regular updates and a supportive community.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more on &lt;a href="https://primevue.org/" rel="noopener noreferrer"&gt;https://primevue.org/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Element Plus
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1h3u8kwmdxa12u6r2yit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1h3u8kwmdxa12u6r2yit.png" alt="Element Plus" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Element Plus&lt;/strong&gt; is the successor to Element UI, which was designed exclusively for Vue 2.x. While its predecessor focused on Vue 2.x, Element Plus brings new features, modern tools, and an active community, making it a reliable choice for developers around the globe.&lt;/p&gt;

&lt;p&gt;With its strong TypeScript support and an API designed for Vue 3’s Composition API, Element Plus offers a smooth development experience. Its UI style is clean and easy to personalize, making it suitable for everything from small projects to large-scale applications. Its documentation and examples further simplify adoption for new users.&lt;/p&gt;

&lt;p&gt;As of January 2025, Element Plus has over 25,000 stars (from 22,600 stars in 2024) on GitHub and an average weekly downloads count of over 230,000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Rich component library with customizable themes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internationalization support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detailed documentation and community-driven development.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more on &lt;a href="https://element-plus.org/en-US/" rel="noopener noreferrer"&gt;https://element-plus.org/en-US/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Quasar
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxcm4bcrqwbj53wpfalc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxcm4bcrqwbj53wpfalc.png" alt="Quasar" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quasar&lt;/strong&gt; is a high-performance Vue framework that enables developers to build responsive websites, mobile apps, and Electron apps using a single codebase. What makes Quasar, founded since 2015, different and standout from other UI component libraries is that Quasar is not only a UI component library but an entire framework.&lt;/p&gt;

&lt;p&gt;Quasar's UI Components feature 70 high performance customizable Material Design components and icons of various styles (bootstrap, material, fontawesome and many more). The documentation is detailed and well thought-out. The library also has pre-built features including animations and functions to handle dates and times.&lt;/p&gt;

&lt;p&gt;As of January 2025, Quasar has over 26,000 stars (from 25,000 stars in 2024) on GitHub and an average weekly downloads count of over 150,000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Supports multiple platforms (SPA, SSR, PWA, Mobile, and Desktop).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comprehensive theming and customization options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built-in support for internationalization.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more on &lt;a href="https://quasar.dev/" rel="noopener noreferrer"&gt;https://quasar.dev/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Radix Vue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyni7ptzumf5zdogqvlx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyni7ptzumf5zdogqvlx.png" alt="Radix Vue" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Radix Vue&lt;/strong&gt; is a headless component library crafted specifically for Vue.js, offering developers an accessibility-first approach to building user interfaces. Adapted from the popular Radix UI, it provides a robust set of highly customizable components that integrate seamlessly with Vue 3 applications.&lt;/p&gt;

&lt;p&gt;The library prioritizes WAI-ARIA compliance, ensuring all components, such as dropdown menus, sliders, and modals, are fully accessible out of the box. Radix Vue’s headless architecture allows developers to implement their unique styling and behavior without being tied to a specific design system, making it a versatile choice for projects of any scale.&lt;/p&gt;

&lt;p&gt;As of January 2025, Radix Vue continues to grow in popularity, with a thriving GitHub community and over 130,000 weekly downloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fully accessible components built with WAI-ARIA standards for inclusivity out of the box.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Headless architecture, allowing complete customization of styles and behavior to fit any design system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modular and lightweight, optimized for seamless integration into Vue 3 applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more on &lt;a href="https://www.radix-vue.com/" rel="noopener noreferrer"&gt;https://www.radix-vue.com/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Ant Design Vue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwj8dlwhnewe9pg5mnca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwj8dlwhnewe9pg5mnca.png" alt="Ant Design Vue" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ant Design Vue (Antdv)&lt;/strong&gt; brings the power of the Ant Design ecosystem to Vue.js, offering a polished and professional UI library. Originally developed for React by a team at Alibaba, its Vue implementation has carved out its own space, earning a reputation for its extensive features and developer-friendly design.&lt;/p&gt;

&lt;p&gt;Antdv provides a wide array of components, from complex data visualization tools to advanced forms and tree structures. Its focus on scalability and flexibility makes it a strong contender for both small projects and enterprise-grade applications. While the sheer number of features can feel overwhelming at first, the clear documentation and consistent design system make it easy to master.&lt;/p&gt;

&lt;p&gt;As of January 2025, Ant Design Vue has over 20,500 stars (from 19,300 stars in 2024) on GitHub and an average weekly downloads count of over 90,000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Comprehensive component library with consistent design language.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customizable themes and styles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Strong community support and regular updates.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more on &lt;a href="https://antdv.com/" rel="noopener noreferrer"&gt;https://antdv.com/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Special Mention: Nuxt UI
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnxdcckdodsdu95kee14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnxdcckdodsdu95kee14.png" alt="Nuxt UI" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nuxt UI&lt;/strong&gt; is a UI framework built by the Nuxt team that offers a library of components specifically designed for seamless integration with Nuxt.js projects. It ensures developers have a fast, reliable, and optimized experience when crafting modern web applications.&lt;/p&gt;

&lt;p&gt;The library includes a curated selection of lightweight and highly customizable components that prioritize performance and developer productivity. Its components are designed to work out of the box with Nuxt’s powerful features, such as server-side rendering (SSR) and static site generation (SSG), making it an excellent choice for creating scalable and responsive applications.&lt;/p&gt;

&lt;p&gt;As of January 2025, Nuxt UI is gaining traction in the Vue.js community, with a rapidly growing GitHub presence and over 460,000 weekly downloads. It’s quickly becoming a go-to solution for those seeking a streamlined and efficient component library tailored for Nuxt.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Optimized components tailored for seamless integration with Nuxt’s SSR and SSG capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lightweight and customizable, designed to enhance performance without sacrificing flexibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backed by the Nuxt team, ensuring consistent updates, detailed documentation, and community support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more on &lt;a href="https://ui.nuxt.com/" rel="noopener noreferrer"&gt;https://ui.nuxt.com/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The Vue.js ecosystem continues to thrive in 2025, offering developers a wide range of UI component libraries to meet every need, from comprehensive frameworks to lightweight, customizable solutions. Whether you’re building a simple personal project or a complex enterprise application, there’s a library perfectly suited for your needs.  &lt;/p&gt;

&lt;p&gt;Each of the libraries brings something unique to the table. To understand which one aligns with your project specific requirements, workflow or design preferences, diving in to explore what each has to offer is probably the best option. 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue PDF Viewer: The PDF Viewer Built for Vue.js Developers 🚀
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxnoe3404vs2nmjj09jqn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxnoe3404vs2nmjj09jqn.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you enjoyed this article, I encourage you to check out &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=vue-3-ui-libraries-6-most-popular-picks-for-2025"&gt;Vue PDF Viewer&lt;/a&gt;. Designed specifically for Vue.js applications (small to large), it’s packed with features like easy Vue integration, advanced customization options, responsive layouts, and more. With our developer-friendly APIs and quick-start toolkit, you’ll have a fully functional PDF viewer integrated into your Vue project in no time.&lt;/p&gt;

&lt;p&gt;Your support inspires me to create even more valuable content for the Vue community. Thank you for considering &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=vue-3-ui-libraries-6-most-popular-picks-for-2025"&gt;Vue PDF Viewer&lt;/a&gt;, and happy coding! 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia2.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExZXNpaWI0MGV3dTVicGE2YWliYTF4cDg3NTNlN2FjM25rZ2c5bzRrMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FvnnoqBjIrJ73y%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia2.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExZXNpaWI0MGV3dTVicGE2YWliYTF4cDg3NTNlN2FjM25rZ2c5bzRrMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FvnnoqBjIrJ73y%2Fgiphy.gif" width="420" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>nuxt</category>
    </item>
    <item>
      <title>📄 Popular PDF Viewers for Vue.js: Which One Is Right for You? 🤔</title>
      <dc:creator>Anson Ch</dc:creator>
      <pubDate>Tue, 10 Dec 2024 11:13:35 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/popular-pdf-viewers-for-vuejs-which-one-is-right-for-you-32kd</link>
      <guid>https://dev.to/vue-pdf-viewer/popular-pdf-viewers-for-vuejs-which-one-is-right-for-you-32kd</guid>
      <description>&lt;p&gt;PDF is a common document that is used digitally everywhere. I have been involved in a few Vue projects that require PDF display. For simple viewing, native browser function or iframe solutions should suffice. For more advanced rendering and interactions, you will need dedicated libraries that offer features like theme customization, responsive layouts and reliable support. &lt;/p&gt;

&lt;p&gt;Choosing a PDF viewer for a Vue.js application depends on your project’s needs. Here’s a quick breakdown of five options to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PDF.js (Open Source):&lt;/strong&gt; Reliable, no-frills viewing for simple applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vue-pdf (Open Source):&lt;/strong&gt; Lightweight wrapper for PDF.js, built for Vue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nutrient (Paid):&lt;/strong&gt; Feature-rich and enterprise-ready, ideal for complex needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vue PDF Viewer (Paid):&lt;/strong&gt; Customizable and powerful, built for Vue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF.js Express (Hybrid):&lt;/strong&gt; Start with free basics, with optional premium add-ons.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I'll be comparing five popular PDF libraries for Vue.js. Each library has its strengths and weaknesses, and my goal is to help you pick the best one for your project’s unique needs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I’m part of the Vue PDF Viewer team.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Importance of a Reliable PDF Viewer
&lt;/h2&gt;

&lt;p&gt;In any Vue.js application where document viewing is essential, a reliable PDF viewer can make all the difference. Whether you’re building a business dashboard, an educational platform, or a document management system, the right PDF viewer streamlines development and enhances the user experience. &lt;/p&gt;

&lt;h3&gt;
  
  
  Key Criteria for Choosing a PDF Viewer in Vue.js
&lt;/h3&gt;

&lt;p&gt;When selecting a PDF viewer, a few critical factors can determine whether it will fit your project needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; Fast loading and smooth rendering, especially for large PDFs, are essential.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Integration:&lt;/strong&gt; Libraries that integrate easily into Vue projects save time and simplify maintenance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customization:&lt;/strong&gt; The ability to style, extend, and configure is important for aligning with specific requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community &amp;amp; Support:&lt;/strong&gt; Documentation and community resources make troubleshooting easier and enhance long-term viability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these in mind, let’s explore the top options!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExbjJmcXltdHJ2OGFvcHhnbDdiMzRnMmw1Y3d6amgyNnExaHF2ZGdoNCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/IOUn2qgyH54tH90uJ8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExbjJmcXltdHJ2OGFvcHhnbDdiMzRnMmw1Y3d6amgyNnExaHF2ZGdoNCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/IOUn2qgyH54tH90uJ8/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Source PDF Viewers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. PDF.js
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa04mthwoozpmyx9jzn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa04mthwoozpmyx9jzn8.png" alt="PDF.js" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mozilla.github.io/pdf.js/" rel="noopener noreferrer"&gt;&lt;strong&gt;PDF.js&lt;/strong&gt;&lt;/a&gt; is a well-known open-source JavaScript library created by Mozilla for rendering PDFs directly in the browser. The library allows developers to display PDF documents without relying on external plugins or native applications. PDF.js renders PDFs by converting each page into HTML5 canvas elements, ensuring that the content is viewable directly in the browser. &lt;/p&gt;

&lt;p&gt;Developers who need a simple, cost-effective solution for displaying PDFs in Vue applications often use PDF.js as a base library. Because it’s a standalone JavaScript library, it’s compatible across multiple frameworks. However, it’s not built specifically for Vue, so Vue developers may need to use wrappers or custom integration to make the most of it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large, active community and extensive documentation.&lt;/li&gt;
&lt;li&gt;Free to use, with a simple API that allows basic PDF rendering.&lt;/li&gt;
&lt;li&gt;Actively maintained, so updates and support are consistent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not specifically designed for Vue; additional setup or wrappers like vue-pdf may be required for integration.&lt;/li&gt;
&lt;li&gt;Limited customization, so advanced functionality (e.g., annotations) requires additional coding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Suited For:&lt;/strong&gt; Simple applications where basic PDF rendering is suffices. While customization is possible, integrating advanced features with Vue.js requires extensive effort as the library is not designed specifically for the framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. vue-pdf
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdq9vunrgqwra7tftvark.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdq9vunrgqwra7tftvark.png" alt="vue-pdf" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/vue-pdf" rel="noopener noreferrer"&gt;&lt;strong&gt;Vue-pdf&lt;/strong&gt;&lt;/a&gt; is a lightweight wrapper around PDF.js, specifically tailored for Vue applications. While PDF.js itself provides a core PDF rendering engine, vue-pdf simplifies the integration process for Vue developers, making it easier to render PDFs without writing extensive code. By using vue-pdf, Vue developers can enjoy the benefits of PDF.js without needing to manage the complex JavaScript integration manually. &lt;/p&gt;

&lt;p&gt;Vue-pdf is ideal for applications that require basic PDF display but don’t need extensive functionality like annotations or form filling. It’s popular in small projects and MVPs where ease of use and quick implementation are prioritized. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vue compatibility out-of-the-box, which simplifies integration.&lt;/li&gt;
&lt;li&gt;Free and open-source, with a straightforward API.&lt;/li&gt;
&lt;li&gt;Great for smaller projects and quick prototyping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limited advanced features, so it’s best suited for basic viewing.&lt;/li&gt;
&lt;li&gt;Minimal control over rendering or layout; not ideal for highly customized projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Suited For:&lt;/strong&gt; Lightweight applications with straightforward PDF display needs without default layout. Vue-pdf is widely used in the Vue.js community, but be aware that the library has not been updated in over 3 years, which may lead to potential security and compatibility concerns.&lt;/p&gt;




&lt;h2&gt;
  
  
  Paid PDF Viewers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3. Nutrient (formerly PSPDFKit)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6hes222egf9jzebs0xx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6hes222egf9jzebs0xx.png" alt="Nutrient" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nutrient.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Nutrient&lt;/strong&gt;&lt;/a&gt; is a premium, enterprise-grade PDF SDK designed to meet the needs of complex applications with advanced PDF requirements. This SDK goes beyond basic PDF viewing, offering interactive features like annotations, form filling, and even document editing. Built with scalability and customization in mind, Nutrient is often chosen by large-scale applications that prioritize security, stability, and extensive functionality. &lt;/p&gt;

&lt;p&gt;While Nutrient is not designed specifically for Vue, it can be integrated into Vue applications with some customization. It’s ideal for organizations that need robust PDF features and are willing to invest in a paid solution that comes with dedicated support and a rich feature set. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature-rich, with support for annotations, editing, search, and form filling.&lt;/li&gt;
&lt;li&gt;Optimized for large-scale applications, handling complex PDFs efficiently.&lt;/li&gt;
&lt;li&gt;Excellent customer support and thorough documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High cost, which may be a factor for smaller teams or budget-restricted projects.&lt;/li&gt;
&lt;li&gt;Integration with Vue may require extensive customization and configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Suited For:&lt;/strong&gt; Enterprise applications that demand robust, feature-rich PDF functionality such as annotation and editing. Nutrient is ideal for large-scale projects where security, performance, and dedicated support are priorities. However, its high cost and the need for extensive Vue-specific customization may make it less suitable for smaller teams or simpler projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Vue PDF Viewer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanjygu6xojpwaxly0ftg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanjygu6xojpwaxly0ftg.png" alt="Vue PDF Viewer" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=popular-pdf-viewers-for-vuejs-which-one-is-right-for-you"&gt;&lt;strong&gt;Vue PDF Viewer&lt;/strong&gt;&lt;/a&gt; is a Vue-native solution designed specifically for Vue.js applications. Unlike generic libraries, it integrates seamlessly with Vue projects, offering features that cater to both simple and complex PDF requirements. Its native compatibility ensures that developers can focus more on building their applications and less on managing integration challenges. &lt;/p&gt;

&lt;p&gt;Vue PDF Viewer stands out for its ease of use, performance, and the level of customization it offers. It’s particularly suited for projects that demand robust PDF features, such as theme customization, responsive design, and advanced interaction capabilities like annotations. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to integrate, with Vue-specific functions or methods since it’s Vue-native.&lt;/li&gt;
&lt;li&gt;Optimized for quick loading and smooth rendering to handle large PDF files.&lt;/li&gt;
&lt;li&gt;Adaptable to any project’s design and functional needs with various APIs to leverage or customize from.&lt;/li&gt;
&lt;li&gt;Ensures a seamless experience on both desktop and mobile devices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some advanced enterprise-grade features, such as built-in document editing, may not be available.&lt;/li&gt;
&lt;li&gt;While optimized for modern Vue.js frameworks, it is not compatible with older Vue versions (i.e., Vue 2).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Suited For:&lt;/strong&gt; Vue PDF Viewer is perfect for Vue.js applications requiring a PDF viewer built specifically for Vue. It provides a powerful, native solution with flexibility, high performance, and extensive customization options, making it ideal for projects that prioritize responsive design and seamless user experiences.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hybrid PDF Viewer
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5. PDF.js Express
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fslef63hlla33lvyd4ncz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fslef63hlla33lvyd4ncz.png" alt="PDF.js Express" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pdfjs.express/" rel="noopener noreferrer"&gt;&lt;strong&gt;PDF.js Express&lt;/strong&gt;&lt;/a&gt; offers a unique hybrid model for teams who want flexibility in scaling PDF capabilities. Based on PDF.js, it provides a free version with basic features and the option to unlock premium functionality through paid upgrades. This model is ideal for projects that may need simple viewing at first but might require additional features like annotations, text search, and form filling as they grow. &lt;/p&gt;

&lt;p&gt;PDF.js Express is compatible with Vue and is easy to set up, making it accessible to both small projects and larger applications. The option to scale up as needed gives developers flexibility in budgeting and feature selection, allowing projects to remain adaptable. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vue-compatible and easy to integrate, with a streamlined setup for quick PDF viewing implementation.&lt;/li&gt;
&lt;li&gt;Provides a range of premium features (annotations, form filling, text search) as optional upgrades, which allows developers to start small and add features as the project grows.&lt;/li&gt;
&lt;li&gt;Strong documentation and support for both free and premium features, making it a developer-friendly option with a low entry cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free version is limited in functionality; advanced features require a paid license.&lt;/li&gt;
&lt;li&gt;For applications needing high customization or many features, a full SDK like Nutrient or Apryse may be a better choice.&lt;/li&gt;
&lt;li&gt;Integration with Vue may require extensive customization since the UI source code is based on React.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Suited For:&lt;/strong&gt; Projects starting with free features and scaling to premium capabilities like annotations and form filling. It’s best suited for applications with straightforward PDF needs or projects that can accommodate some customization to integrate more advanced functionality over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Honorable Mentions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v0bowzdt8zk53333mit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v0bowzdt8zk53333mit.png" alt="Apryse" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apryse.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Apryse&lt;/strong&gt;&lt;/a&gt; (formerly PDFTron) is a paid PDF SDK that provides advanced PDF processing capabilities for applications that require more than just viewing. Known for its support of various document types, including Word, Excel, and PowerPoint, Apryse is a versatile SDK that fits well in document-heavy applications. Apryse offers extensive manipulation options, including document redaction, digital signatures, and text extraction, making it a go-to for industries with strict document handling requirements, such as finance, healthcare, and legal. &lt;/p&gt;

&lt;p&gt;Apryse is also the parent company of PDF.js Express, which offers a hybrid model for scaling PDF capabilities. Like Nutrient, Apryse isn’t Vue-native, but it can be incorporated into Vue projects with some setup. Its comprehensive functionality and emphasis on security make it suitable for projects with high compliance standards. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Suited For&lt;/strong&gt;: Enterprise applications needing advanced PDF and multi-format handling. &lt;/p&gt;




&lt;h2&gt;
  
  
  Table Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Customizable with Vue.js&lt;/th&gt;
&lt;th&gt;PROS&lt;/th&gt;
&lt;th&gt;CONS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vue PDF Viewer&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Native Vue.js integration, highly customizable&lt;/td&gt;
&lt;td&gt;Lacks document editing, not supported for older Vue versions (i.e., Vue 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF.js&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Free, large community, cross-framework&lt;/td&gt;
&lt;td&gt;Not Vue-native, limited advanced features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vue-pdf&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Easy Vue integration, free and lightweight&lt;/td&gt;
&lt;td&gt;Limited features, outdated (3+ years)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nutrient&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Feature-rich, enterprise-ready&lt;/td&gt;
&lt;td&gt;Expensive, requires Vue customization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF.js Express&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Flexible, optional premium features&lt;/td&gt;
&lt;td&gt;Limited free features, React-based UI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion and Recommendation
&lt;/h2&gt;

&lt;p&gt;If your projects are relatively small with simple PDF viewing needs, PDF.js should suffice. On the other hand, if you require advanced features like annotation and edit support or customization in Vue.js, Nutrient and Vue PDF Viewer are the best options respectively. PDF.js Express strikes a good balance between flexibility and scalability, making it a strong choice for projects with evolving requirements or variable budgets. Carefully evaluate your project’s requirements and pick the right library for your development process.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue PDF Viewer: The PDF Viewer Built for Vue.js Developers 🚀
&lt;/h2&gt;

&lt;p&gt;If you enjoyed this article, I encourage you to check out &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=popular-pdf-viewers-for-vuejs-which-one-is-right-for-you"&gt;Vue PDF Viewer&lt;/a&gt;. Designed specifically for Vue.js applications (small to large), it’s packed with features like seamless Vue integration, advanced customization options, responsive layouts, and more. With our developer-friendly APIs and quick-start toolkit, you’ll have a fully functional PDF viewer integrated into your Vue project in no time.&lt;/p&gt;

&lt;p&gt;Your support keeps me motivated to share more insights and build tools for the developer community. Thank you in advance! 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F4J4F61F1XSzjW%2Fgiphy.gif%3Fcid%3D790b7611lxfxzunt5a0farls22pun8gvtq2yhom61m7tx3f3%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F4J4F61F1XSzjW%2Fgiphy.gif%3Fcid%3D790b7611lxfxzunt5a0farls22pun8gvtq2yhom61m7tx3f3%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" width="282" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🔥How to Render a Beautiful PDF Viewer for Vue.js in Minutes💅</title>
      <dc:creator>Fang Tanbamrung</dc:creator>
      <pubDate>Wed, 25 Sep 2024 12:00:00 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes-45kh</link>
      <guid>https://dev.to/vue-pdf-viewer/how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes-45kh</guid>
      <description>&lt;p&gt;Since my last post on building PDF Viewer with Vue.js, I have been hard at work to develop a library that just works: &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes"&gt;Vue PDF Viewer&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/vue-pdf-viewer" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F9659%2Fa855b275-485d-4335-86e4-6b27642b5a96.jpg" alt="Vue PDF Viewer" width="300" height="300"&gt;
      &lt;div class="ltag__link__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F328315%2Faede6284-fb58-42a8-baae-2f066ed3f707.jpg" alt="" width="680" height="680"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/vue-pdf-viewer/building-a-pdf-viewer-for-vuejs-with-pdfjs-vue3-pdf-app-and-more-21ii" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;✨Building a PDF Viewer for Vue.js with PDF.js, vue3-pdf-app and more 🚀&lt;/h2&gt;
      &lt;h3&gt;Fang Tanbamrung for Vue PDF Viewer ・ Mar 19 '24&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#vue&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#frontend&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;After being in private beta for a few months, we officially launched &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes"&gt;Vue PDF Viewer&lt;/a&gt; earlier this month. In this article, I'll be sharing with you how to render a PDF in Vue.js in just minutes, along with a few use cases to help you make the most out of this library.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Vue PDF Viewer?
&lt;/h2&gt;

&lt;p&gt;Let’s start with why &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes"&gt;Vue PDF Viewer&lt;/a&gt; stands out. Here’s a quick rundown of its key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Built for Vue&lt;/strong&gt;: Designed specifically for Vue.js developers, Vue PDF Viewer is designed using familiar Vue’s component-based structure, syntax and state management for Vue.js developers to customize natively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quick Setup&lt;/strong&gt;: Go from zero to a fully functional PDF viewer in just 3 simple steps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable&lt;/strong&gt;: Supports themes, responsive layouts, and custom icons, allowing you to tailor the viewer to fit your app’s design.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Performance&lt;/strong&gt;: Optimized for handling multiple PDFs without sacrificing speed or performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let’s dive into the step-by-step process to get started with Vue PDF Viewer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExaW5qZzZ6Z3R6YWxueXJ6NDRoeTE1b3Y4ZTl5NWdlMGpoZnEyN285eSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/CjmvTCZf2U3p09Cn0h/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExaW5qZzZ6Z3R6YWxueXJ6NDRoeTE1b3Y4ZTl5NWdlMGpoZnEyN285eSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/CjmvTCZf2U3p09Cn0h/giphy.gif" width="480" height="452"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Displaying a PDF Viewer Component
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.vue-pdf-viewer.dev/introduction/getting-started.html?utm_source=dev.to&amp;amp;utm_content=how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes"&gt;Vue PDF Viewer&lt;/a&gt; supports Vue 3. It also works seamlessly across a wide range of environments, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vue 3 – Composition API (TypeScript, JavaScript)&lt;/li&gt;
&lt;li&gt;Vue 3 – Options API (TypeScript, JavaScript)&lt;/li&gt;
&lt;li&gt;Vue 3 – Server-Side rendering (TypeScript)&lt;/li&gt;
&lt;li&gt;Nuxt&lt;/li&gt;
&lt;li&gt;VitePress&lt;/li&gt;
&lt;li&gt;Quasar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this demo, I’ll show you how to add the Vue PDF Viewer component to a Vue app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Adding the Library
&lt;/h3&gt;

&lt;p&gt;To get started, add the Vue PDF Viewer library to your project. It’s a quick and easy installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun add @vue-pdf-viewer/viewer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Remark: You can use &lt;code&gt;yarn&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;pnpm&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Importing the Component
&lt;/h3&gt;

&lt;p&gt;Next, we’ll import the PDF viewer component into your Vue application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;VPdfViewer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vue-pdf-viewer/viewer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Render the Component
&lt;/h3&gt;

&lt;p&gt;Finally, render the component and pass in the required props to display your PDF document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;VPdfViewer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vue-pdf-viewer/viewer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;:style=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ width: '1028px', height: '700px' }"&amp;gt;
    &lt;span class="nt"&gt;&amp;lt;VPdfViewer&lt;/span&gt;
      &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpzi39fwc3boto5c3ri2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpzi39fwc3boto5c3ri2.png" alt="An image rendering a Vue PDF Viewer component" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it! In just a few steps, you have integrated a fully responsive and customizable PDF viewer into your Vue app!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Remark: Since the Vue PDF Viewer is a component, you can initiate multiple instances of the component in the same page independently.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZnBjb3V0cWJoM2p5cXZtamY5MTcweDl1bjQ1Z2w5Z3pibnlwc3l5ZCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/VPRABLhiu6sJAn5FEK/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZnBjb3V0cWJoM2p5cXZtamY5MTcweDl1bjQ1Z2w5Z3pibnlwc3l5ZCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/VPRABLhiu6sJAn5FEK/giphy.gif" width="480" height="480"&gt;&lt;/a&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;p&gt;Want to know more about how you can modify Vue PDF Viewer to fit your needs? Here are some common use cases:&lt;/p&gt;

&lt;h3&gt;
  
  
  Change Themes to Match Your Site
&lt;/h3&gt;

&lt;p&gt;You can easily adjust the viewer’s theme to match your website’s design. Whether your site uses light or dark modes or other types of color scheme, VPV can be customized to fit the current settings, ensuring a consistent look and feel across your entire platform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="nt"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt; &lt;span class="nt"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nd"&gt;:deep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.vpv-variables&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-container-border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lightblue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-toolbar-background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;mintcream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-toolbar-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-toolbar-border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lightblue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-icon-active-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-sidebar-content-background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;mintcream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-sidebar-content_thumbnail-page-number-font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-sidebar-content_thumbnail-focused-border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;darkslategrey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-pages-container-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;mintcream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* To override variables in dark mode */&lt;/span&gt;
&lt;span class="nd"&gt;:deep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.vpv-variables.vpv-variables__dark&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-container-border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-toolbar-background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;darkgrey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-toolbar-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-toolbar-border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-icon-active-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-sidebar-content-background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;darkgrey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-sidebar-content_thumbnail-focused-border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--vpv-pages-container-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;darkgrey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiiiygxynb8yz80bs0eq5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiiiygxynb8yz80bs0eq5.gif" alt="A gif showing a Vue PDF Viewer component switching to a dark theme." width="600" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adjust Web Responsive Breakpoint
&lt;/h3&gt;

&lt;p&gt;By default, the Vue PDF Viewer component resizes responsively at &lt;code&gt;768px&lt;/code&gt;. If you wish to adjust the breakpoint to be higher, perhaps because you using text instead of graphic as icons, you can easily specify breakpoint to trigger responsive style.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt; &lt;span class="nt"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nd"&gt;:deep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.vpv-variables&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--vpv-container-width-sm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ujwnwbofb5gw0o2uly1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ujwnwbofb5gw0o2uly1.gif" alt="A gif showing a Vue PDF Viewer component resizing responsively with a higher breakpoint than that of a default." width="600" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or if you need the PDF viewer component to resize even below the default breakpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt; &lt;span class="nt"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nd"&gt;:deep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.vpv-variables&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--vpv-container-width-sm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6u64uja0jheqiydweje.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6u64uja0jheqiydweje.gif" alt="A gif showing a Vue PDF Viewer component resizing responsively with a lower breakpoint than that of a default." width="600" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Customize Any Icon
&lt;/h3&gt;

&lt;p&gt;Vue PDF Viewer provides flexibility when it comes to customizing the user interface. You can easily swap out default icons with custom ones, giving you the ability to maintain brand consistency or match your app’s style.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;VPdfViewer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vue-pdf-viewer/viewer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pdfFileSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;:style=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ width: '1028px', height: '700px' }"&amp;gt;
    &lt;span class="nt"&gt;&amp;lt;VPdfViewer&lt;/span&gt; &lt;span class="na"&gt;:src=&lt;/span&gt;&lt;span class="s"&gt;"pdfFileSource"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#iconSearch&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Search&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/VPdfViewer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lg9y88kctw2ipah07s2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lg9y88kctw2ipah07s2.png" alt="An image showing a Vue PDF Viwer component with a custom search icon using text." width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are interested in learning more about the library, feel free to check out the &lt;a href="https://docs.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes"&gt;docs&lt;/a&gt; or try out our &lt;a href="https://demo.vue-pdf-viewer.dev/?vpv-locale=en_US&amp;amp;utm_source=dev.to&amp;amp;utm_content=how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes"&gt;demo&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In just a few steps, you can have a fully functioning, responsive, and customizable PDF viewer embedded into your Vue.js application using Vue PDF Viewer. Whether you are building a simple document viewer or a more complex app, Vue PDF Viewer makes PDF rendering effortless and beautiful.&lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read this post. And I look forward to seeing what you build with &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=how-to-render-a-beautiful-pdf-viewer-for-vuejs-in-minutes"&gt;Vue PDF Viewer&lt;/a&gt;! 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExdGFuaTFwbWFkc2VhZzg1NHRzMWRiZTZlcW94cTg0NmMzeXQ3Y2c5OCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/5g1WreDOnHbqXpNhhz/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExdGFuaTFwbWFkc2VhZzg1NHRzMWRiZTZlcW94cTg0NmMzeXQ3Y2c5OCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/5g1WreDOnHbqXpNhhz/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>frontend</category>
      <category>pdf</category>
      <category>javascript</category>
    </item>
    <item>
      <title>✨Building a PDF Viewer for Vue.js with PDF.js, vue3-pdf-app and more 🚀</title>
      <dc:creator>Fang Tanbamrung</dc:creator>
      <pubDate>Tue, 19 Mar 2024 12:30:00 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/building-a-pdf-viewer-for-vuejs-with-pdfjs-vue3-pdf-app-and-more-21ii</link>
      <guid>https://dev.to/vue-pdf-viewer/building-a-pdf-viewer-for-vuejs-with-pdfjs-vue3-pdf-app-and-more-21ii</guid>
      <description>&lt;p&gt;As someone who has worked on several Vue.js projects in the past, I know firsthand the importance of having a great PDF Viewer to enhance the user experience. Whether it's displaying important documents, presenting reports, or sharing content, PDF viewers provide a seamless way to access and interact with PDF files. &lt;/p&gt;

&lt;p&gt;In this article, I'll be sharing with you four different methods that I've personally used for building a PDF Viewer in Vue.js: iFrame, PDF with New Tab, PDF.js, and vue3-pdf-app. Each method offers unique features and benefits, catering to various project requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNWRvbjBibHlpNHVsMHU3cG9kczh1d3pua3E1YzJ1ejE5OWtudDFlayZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3o7TKUM3IgJBX2as9O/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNWRvbjBibHlpNHVsMHU3cG9kczh1d3pua3E1YzJ1ejE5OWtudDFlayZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3o7TKUM3IgJBX2as9O/giphy.gif" width="267" height="200"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is so important about PDF?
&lt;/h2&gt;

&lt;p&gt;Rendering PDFs on websites has a wide range of practical use cases that some of you may have come across. Here are a few examples of these use cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Product Manuals: As a senior developer, you know that product manuals are an essential resource for customers. By rendering product manuals as PDFs, users can access them on any device, view them in high resolution, and even print them out if needed. PDFs allow you to preserve the original layout and formatting while adding interactive elements like hyperlinks and bookmarks to make navigation easy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Legal Contracts: Contracts are an important legal document that requires accuracy and consistency. By rendering legal contracts as PDFs, you can ensure that they cannot be edited or tampered with, and that they can be quickly and easily signed online with digital signatures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;E-books and Online Publications: Many websites offer e-books, case studies, and other online publications. By rendering this content as PDFs, readers can enjoy a familiar reading experience, similar to reading a physical book or magazine, with the ability to zoom in, annotate, and bookmark pages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Educational Materials: As a developer, you may find yourself working on e-learning websites or educational platforms. By rendering course materials and study guides as PDFs, you can present the content in an easy-to-read, visually appealing way.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Vue PDF Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;Just a quick background about what I’m working on. &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=building-a-pdf-viewer-for-vuejs"&gt;Vue PDF Viewer&lt;/a&gt; renders the PDF viewer on your Vue or Nuxt websites so that your users can interact with your PDF document without leaving your sites. The component has over 20 features including theme customization, built-in localization, web responsive and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcaxyyicw35mz9exhdc1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcaxyyicw35mz9exhdc1c.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be grateful if you could check &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=building-a-pdf-viewer-for-vuejs"&gt;Vue PDF Viewer&lt;/a&gt; out. It will encourage me to make even more contents ❤️‍🔥&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 1: iFrame
&lt;/h2&gt;

&lt;p&gt;iFrame provides a straightforward approach to embed PDF files and leverage the browser's built-in PDF viewing capabilities. &lt;br&gt;
Here's how you can implement it in Vue.js:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Vue.js and create a new Vue project using the Vite.&lt;/li&gt;
&lt;li&gt;Add an iFrame element to your Vue component template.&lt;/li&gt;
&lt;li&gt;Set the src attribute of the iFrame to the URL or path of the PDF file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the &lt;a href="https://codesandbox.io/p/devbox/pdf-vg3g97?file=%2Fsrc%2Fcomponents%2FIframe.vue" rel="noopener noreferrer"&gt;link&lt;/a&gt; to the code sample.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhbc6rlye414j1boy6od.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhbc6rlye414j1boy6od.png" alt="iFrame demo" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using iFrame has its pros and cons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple implementation&lt;/li&gt;
&lt;li&gt;Relies on the browser's native PDF viewer&lt;/li&gt;
&lt;li&gt;Display PDF file as part of a website&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cannot customize because it's using the browser's native pdf function&lt;/li&gt;
&lt;li&gt;Potential compatibility issues with different browsers and versions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;&lt;br&gt;
Looking for a quick set up without a need for PDF viewer to have UI consistency.&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 2: PDF with New Tab
&lt;/h2&gt;

&lt;p&gt;The second method involves opening the PDF in a new browser tab. Here's an overview of implementing this method in Vue.js:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a link or button element in your Vue component template.&lt;/li&gt;
&lt;li&gt;Add an onclick event handler to open a new browser tab with the PDF URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using a new tab approach offers the following pros and cons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple implementation&lt;/li&gt;
&lt;li&gt;Direct interaction with the PDF content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User experience cannot be controlled&lt;/li&gt;
&lt;li&gt;Potential compatibility issues with different browsers and versions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;&lt;br&gt;
Similar to method 1 and when you want the viewing experience of PDF file to be separated from the main website. For example, you do not want to add a PDF iFrame.&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 3: PDF.js
&lt;/h2&gt;

&lt;p&gt;PDF.js is a powerful JavaScript library maintained by Mozilla that allows rendering and manipulation of PDF files directly in web browsers. It provides extensive features and capabilities for displaying PDFs in Vue.js applications. To utilize PDF.js in Vue.js, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the PDF.js library using a script tag.&lt;/li&gt;
&lt;li&gt;Create a Vue component to display the PDF viewer&lt;/li&gt;
&lt;li&gt;incorporate the PDF.js into the component to render PDF files.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I have added a simple PDF Viewer using PDF.js in a Vue website. You may find the codes &lt;a href="https://codesandbox.io/p/devbox/pdf-vg3g97?file=%2Fsrc%2Fcomponents%2FPDFjs.vue" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5o25yttxnqftdhxymcny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5o25yttxnqftdhxymcny.png" alt="PDF.js demo" width="800" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's discuss the advantages and disadvantages of using PDF.js:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Advanced PDF rendering functionality&lt;/li&gt;
&lt;li&gt;Cross-browser compatibility&lt;/li&gt;
&lt;li&gt;Extensive customization options&lt;/li&gt;
&lt;li&gt;Well maintained&lt;/li&gt;
&lt;li&gt;Big community&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;May require time and effort to learn the syntax and best practices of the library &lt;/li&gt;
&lt;li&gt;Not user-friendly technical document&lt;/li&gt;
&lt;li&gt;Not easy to customize with JavaScript such as Angular, React and Vue&lt;/li&gt;
&lt;li&gt;Increased complexity when handling more complex PDF interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;&lt;br&gt;
If you want to customize the PDF viewer UI and integrate it as part of a Vue website.&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 4: vue3-pdf-app
&lt;/h2&gt;

&lt;p&gt;vue-pdf is a convenient package specifically designed for Vue.js developers to build PDF viewers. It acts as a wrapper around PDF.js, simplifying the integration process. Here's how you can get started with vue3-pdf-app in Vue.js:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the vue3-pdf-app package using npm or yarn&lt;/li&gt;
&lt;li&gt;Import the vue3-pdf-app component to display PDF&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Please find the demo &lt;a href="https://codesandbox.io/p/sandbox/vue3-pdf-app-forked-p2zygn?file=%2Fsrc%2FApp.vue%3A5%2C8" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojacamdthb869n1ia59i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojacamdthb869n1ia59i.png" alt="vue3-pdf-app demo" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's explore the advantages and disadvantages of using vue-pdf:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy integration with Vue.js projects&lt;/li&gt;
&lt;li&gt;Simplified API for PDF rendering&lt;/li&gt;
&lt;li&gt;Customizable viewer options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support only Vue 3.2 with vue-cli which is not no longer recommended by Vue&lt;/li&gt;
&lt;li&gt;Cannot run on Vite&lt;/li&gt;
&lt;li&gt;Not maintained&lt;/li&gt;
&lt;li&gt;Small community&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;&lt;br&gt;
Actually, I don't recommend using this library because of it only support Vue 3.2.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparison Summary
&lt;/h2&gt;

&lt;p&gt;There are multiple methods available to build a PDF viewer for Vue.js. The iFrame approach is simple and relies on the browser's built-in capabilities. Displaying PDFs on the browser provides more control but requires user installation of a PDF viewer plugin. PDF.js offers advanced rendering features and cross-browser compatibility. For Vue.js developers, the vue-pdf package provides a convenient wrapper for PDF.js, simplifying the implementation process. Choose the method that best suits your project requirements and delivers the desired user experience&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExMGo1N29zbjd2aG5paHM1ZWE5dnF3M2pkeTE1YW0yNHB1N285aDY1cCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/eIqj0vevEQ6lLFUeTZ/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExMGo1N29zbjd2aG5paHM1ZWE5dnF3M2pkeTE1YW0yNHB1N285aDY1cCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/eIqj0vevEQ6lLFUeTZ/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Is there a Better Solution?
&lt;/h2&gt;

&lt;p&gt;For customization purposes, using iFrame or Open with New Tab may not be suitable. Although PDF.js is a possible option, using it effectively can take time and effort that Vue.js developers may not want to commit. It's because of all these reasons that the company I'm working for is building a new library, &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=building-a-pdf-viewer-for-vuejs"&gt;Vue PDF Viewer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18z1p9r0kbo3ekw4s4z5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18z1p9r0kbo3ekw4s4z5.gif" alt="Video demo of Vue PDF Viewer" width="600" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Made for Vue.js:&lt;/strong&gt; &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=building-a-pdf-viewer-for-vuejs"&gt;Vue PDF Viewer&lt;/a&gt; library is crafted to seamlessly integrate with Vue.js. With just a few lines of code. What's more, the library offers extensive customization options, enabling developers to easily match the PDF viewer's theme to their website's design.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatible with Vite:&lt;/strong&gt; For Vue.js developers who leverage Vite as their development tool, the library brings additional advantages. Developers can take advantage of unmatched performance and build speed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensive Feature Set:&lt;/strong&gt; Come equipped with an extensive set of over 20 features, catering to a wide range of user requirements. From essential functionalities like text highlighting and bookmarking, to advanced options such as search functionality, web responsive and  localization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User-Friendly Technical Doc:&lt;/strong&gt; Get started quickly with our starter toolkit. The documentation includes clear instructions, code examples, and extensive API references.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliable Support:&lt;/strong&gt; We understand the importance of reliable support during the integration process. From a responsive customer support team to regular updates addressing bug fixes and feature enhancements.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you find this library helpful, please check out please check out &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=building-a-pdf-viewer-for-vuejs"&gt;Vue PDF Viewer&lt;/a&gt;. It would encourage me to continue creating even more contents. Thank you in advance! 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExdzUxaWZzM2IwcDRtcm9mYmRzeWZ1c2hpc29tN2RucmQ1OXo3cmoyMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oz8xIsloV7zOmt81G/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExdzUxaWZzM2IwcDRtcm9mYmRzeWZ1c2hpc29tN2RucmQ1OXo3cmoyMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oz8xIsloV7zOmt81G/giphy.gif" width="480" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>⚡️Top 6 Vue.js UI Libraries (Vue 3) Trending in 2024 🔥</title>
      <dc:creator>Anson Ch</dc:creator>
      <pubDate>Tue, 12 Mar 2024 12:00:00 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/top-6-vuejs-ui-libraries-vue-3-trending-in-2024-4nf2</link>
      <guid>https://dev.to/vue-pdf-viewer/top-6-vuejs-ui-libraries-vue-3-trending-in-2024-4nf2</guid>
      <description>&lt;p&gt;&lt;em&gt;Edit: Previously I wrote about the "&lt;a href="https://dev.to/ansonch/6-most-popular-vuejs-ui-component-libraries-vue-3-in-2023-5ah5"&gt;6 Most Popular Vue.js UI Libraries (Vue 3) in 2023&lt;/a&gt;". As we are now in 2024, I have revisited the different libraries and updated them for the current year 🎉&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vue.js, a JavaScript framework, has been gaining a lot of attention in recent years due to its simplicity, flexibility, and performance. Also, User Interface (UI) component libraries have become an essential aspect of web development, providing a fast and convenient way to build beautiful and responsive user interfaces.&lt;/p&gt;

&lt;p&gt;Vue 3 has become the default choice to build modern applications since Vue 2 reaching its end of life on December 31, 2023. The need for UI component libraries designed specifically for Vue 3 has risen. In this article, we will take a look at the six most popular Vue.js UI component libraries for 2024, categorized based on their popularity within English and Chinese-speaking communities. &lt;/p&gt;

&lt;p&gt;I decided to categorize this way because of massive popularity of Vue.js in China according to &lt;a href="https://www.freecodecamp.org/news/between-the-wires-an-interview-with-vue-js-creator-evan-you-e383cbf57cc4/" rel="noopener noreferrer"&gt;an interview&lt;/a&gt; with Evan You, the creator of Vue.js, who was born in China and grew up in a city near Shanghai. &lt;/p&gt;

&lt;p&gt;Moreover, Vue has well written documents in Chinese. As teams from big companies in China such as Alibaba, Tencent and Baidu started using Vue.js, all these factors may have contributed to its popularity in the country.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue-PDF-Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;Just a quick background about what I’m working on. &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=top-6-vuejs-ui-libraries-vue-3-trending-in-2024"&gt;Vue-PDF-Viewer&lt;/a&gt; renders the PDF viewer on your Vue or Nuxt websites so that your users can interact with your PDF document without leaving your sites. The component has over 20 features including theme customization, built-in localization, web responsive and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcaxyyicw35mz9exhdc1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcaxyyicw35mz9exhdc1c.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;br&gt;
I would be grateful if you could check &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=top-6-vuejs-ui-libraries-vue-3-trending-in-2024"&gt;Vue-PDF-Viewer&lt;/a&gt; out. It will encourage me to make even more contents ❤️‍🔥&lt;/p&gt;




&lt;h2&gt;
  
  
  English focused community
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Vuetify
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdz7dykvyypxqcrtp6fjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdz7dykvyypxqcrtp6fjr.png" alt="Vuetify" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vuetify is a popular Vue.js UI component library based on Material Design specifications. It provides over 100 customizable components for creating beautiful and responsive user interfaces. With its modular design, developers can selectively import components, which keeps the bundle size small and improve performance. &lt;/p&gt;

&lt;p&gt;Additionally, Vuetify integrates seamlessly with Nuxt 3 and features powerful theming capabilities where developers can customize their application style and match it with their brand.&lt;/p&gt;

&lt;p&gt;As of February 2024, Vuetify has over 38,800 stars (from 37,900 stars in 2023) on GitHub and an average weekly downloads count of close to 500,000. (The &lt;a href="https://npmtrends.com/vuetify" rel="noopener noreferrer"&gt;trend line&lt;/a&gt; seems to be growing steadily over the years)&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://vuetifyjs.com" rel="noopener noreferrer"&gt;https://vuetifyjs.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Remark: There are still a couple of Vuetify 2 components including calendar, overflow-btn, speed-dial, time-picker and treeview that are not yet available in Vuetify 3. According to official Vuetify guide, they will be released by Vuetify Labs when development is completed.&lt;/em&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Quasar
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl00y4v6cv5nknl5hmkid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl00y4v6cv5nknl5hmkid.png" alt="Quasar" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quasar's UI Components feature 70 high performance customizable Material Design components and icons of various styles (bootstrap, material, fontawesome and many more). The documentation is detailed and well thought-out. The library also has pre-built features including animations and functions to handle dates and times. &lt;/p&gt;

&lt;p&gt;What makes Quasar, founded since 2015, different and standout from other UI component libraries is that Quasar is not only a UI component library but a dynamic Vue framework. You can develop Vue.js desktop, web and mobile applications with a single codebase. As the saying goes, write once and use everywhere.&lt;/p&gt;

&lt;p&gt;As of February 2024, Quasar has over 25,000 stars (from 24,200 stars in 2023) on GitHub and an average weekly downloads count of over 100,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://quasar.dev/" rel="noopener noreferrer"&gt;https://quasar.dev/&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. PrimeVue
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fah4q6p7gxmphxy25t6jl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fah4q6p7gxmphxy25t6jl.png" alt="PrimeVue" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PrimeVue is a sleek Vue.js component library that offers over 90 components and 200+ icons making it one of the most comprehensive libraries in the Vue.js community. It's a lightweight library with exclusive Tailwind CSS integration, enabling developers to build complex enterprise-level applications with ease.&lt;/p&gt;

&lt;p&gt;PrimeVue is powered by PrimeTek, which serves millions of developers of Fortune 500 companies such as Intel, Nvidia and American Express, lending it massive credibility in the enterprise space.&lt;/p&gt;

&lt;p&gt;PrimeVue also features an intuitive API, allowing developers to quickly customize the components to achieve their desired designs. &lt;/p&gt;

&lt;p&gt;As of February 2024, PrimeVue has over 6,800 stars (from 4,300 stars in 2023) on GitHub and an average weekly downloads count of over 170,000 (&lt;a href="https://npmtrends.com/primevue" rel="noopener noreferrer"&gt;Huge increase&lt;/a&gt; from around 100,000 downloads in September 2023).&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://primevue.org/" rel="noopener noreferrer"&gt;https://primevue.org/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Chinese focused community
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Element Plus
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2sqk6y4tq8utnkqcocls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2sqk6y4tq8utnkqcocls.png" alt="Element Plus" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Element Plus is a community developed project born from Element UI which supports only Vue 2.X. Due to its predecessor's popularity, it has naturally gained a lot of attention by developers, especially those in China.&lt;/p&gt;

&lt;p&gt;A TypeScript-based library with a complete type definition, Element Plus is not based on Material Design and has its own distinct UI style which can modified quite easily. Element Plus simplifies component utilization, making the code more maintainable and readable with Vue 3's Composition API.&lt;/p&gt;

&lt;p&gt;As of February 2024, Element Plus has over 22,600 stars (from 21,300 stars in 2023) on GitHub and an average weekly downloads count of over 200,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://element-plus.org/en-US/" rel="noopener noreferrer"&gt;https://element-plus.org/en-US/&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Ant Design Vue
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkco78xv5bjizk9unngqf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkco78xv5bjizk9unngqf.png" alt="Ant Design Vue" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ant Design Vue (Antdv) is a popular TypeScript-based UI component library based off Ant Design, a library that was developed for React and was originally created by a team from Alibaba. But it has gained traction in the Vue.js community for its ease of use and its rich feature set. It offers a comprehensive range of components like tree structures, forms, and data visualization components. &lt;/p&gt;

&lt;p&gt;Similar to Element Plus, Antdv has its own unique UI style. Although it may initially seem daunting to explore its huge sets of UI components and features, once you get the hang of it, Antdv can be a very powerful UI component library for projects of all sizes.&lt;/p&gt;

&lt;p&gt;As of February 2024, Ant Design Vue has over 19,300 stars (from 18,600 stars in 2023) on GitHub and an average weekly downloads count of over 80,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://antdv.com/" rel="noopener noreferrer"&gt;https://antdv.com/&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Naive UI
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpt29jj4bmf8v21d3sy2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpt29jj4bmf8v21d3sy2l.png" alt="Naive UI" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naive UI is a TypeScript-based UI component library developed by TuSimple, a Chinese autonomous truck company based in California. It has been mentioned by Evan You, the creator of Vue.js, in his Weibo blog back in 2021. &lt;/p&gt;

&lt;p&gt;Naive UI consists of over 90 components that can be imported to use in your project. Most impressively, all 90+ components can be &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking" rel="noopener noreferrer"&gt;treeshaken&lt;/a&gt;. This means that the component can be imported individually into your application without waste. Documentation of Naive UI is also well documented and easy to follow.&lt;/p&gt;

&lt;p&gt;As of February 2024, Naive UI has over 14,800 stars on GitHub and an average weekly downloads count of over 30,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://github.com/tusen-ai/naive-ui" rel="noopener noreferrer"&gt;https://github.com/tusen-ai/naive-ui&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Special Mention: Nut UI
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38b6bkuvbxiax8hi6lh0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38b6bkuvbxiax8hi6lh0.png" alt="Nut UI" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nut UI is a mobile UI component library that is developed by the Chinese e-commerce giant, JD.com (also known as Jingdong). It provides a JD-style mobile UI component library that is used by JD in production.&lt;/p&gt;

&lt;p&gt;Nut UI features high quality UI components that are well tested (unit test coverage more than 80%). It has clear documentation and supports TypeScript. Furthermore, it provides Sketch design resources for designers to easily create design screens.&lt;/p&gt;

&lt;p&gt;As of February 2024, Nut UI has over 5,700 stars on GitHub and an average weekly downloads count of over 3,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://github.com/jdf2e/nutui/blob/v4/README_EN.md" rel="noopener noreferrer"&gt;https://github.com/jdf2e/nutui/blob/v4/README_EN.md&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, Vue.js has gained popularity due to its flexibility, simplicity, and performance. The availability of different UI component libraries has made it easier for developers to build complex and elegant applications at speed with ease. Whether you're building large complex applications or small, highly performant ones, there is always the right Vue.js UI component library suitable for your needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue-PDF-Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6241dbbfzlm11eif49lk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6241dbbfzlm11eif49lk.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you feel like this article helped you, please check out &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=top-6-vuejs-ui-libraries-vue-3-trending-in-2024"&gt;Vue-PDF-Viewer&lt;/a&gt;. You can customize the PDF viewer component to your theme, add locales, configure panel and more. Each function has TS and JS codes, unit tests and interactive demos. With our starter kits, you can start rendering the &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=top-6-vuejs-ui-libraries-vue-3-trending-in-2024"&gt;Vue-PDF-Viewer&lt;/a&gt; in minutes.&lt;/p&gt;

&lt;p&gt;It would encourage me to continue creating even more contents. Thank you in advance! 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/QLtO7Hs5FXtJe/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/QLtO7Hs5FXtJe/giphy.gif" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>20++ Essential Articles for Vue.js (Vue 3) Beginner</title>
      <dc:creator>Anson Ch</dc:creator>
      <pubDate>Fri, 29 Sep 2023 10:12:38 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/20-essential-articles-for-vuejs-vue-3-beginner-1dmf</link>
      <guid>https://dev.to/vue-pdf-viewer/20-essential-articles-for-vuejs-vue-3-beginner-1dmf</guid>
      <description>&lt;p&gt;Vue.js is a progressive JavaScript framework used for building user interfaces. It emphasizes simplicity and reactivity, making it a popular choice for web development. Vue adoption rate has been growing steadily over the past few years, with &lt;a href="https://npmtrends.com/vue" rel="noopener noreferrer"&gt;millions of weekly npm downloads&lt;/a&gt; at this point of writing 😱  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/2YnutB6bmlLaX7eG89/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/2YnutB6bmlLaX7eG89/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://www.jetbrains.com/lp/devecosystem-2022/javascript/" rel="noopener noreferrer"&gt;Jetbrains' State of Developer Ecosystem survey from 2017-2022&lt;/a&gt;, Vue.js has grown to become the 2nd most popular framework used by Javascript developers. Vue.js is therefore a great choice to learn for a frontend Javascript framework.&lt;/p&gt;

&lt;p&gt;If this is your first JavaScript framework, you may be feeling nervous or uncertain. So to make this journey a little bit easier, I have curated 20+ relevant articles grouped by topics to help Vue.js beginners learn the core concepts and features of Vue.js. Here are the topics to follow along:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduction to Vue 3&lt;/li&gt;
&lt;li&gt;Options API and Composition API&lt;/li&gt;
&lt;li&gt;Vue Router&lt;/li&gt;
&lt;li&gt;Pinia Fundamentals&lt;/li&gt;
&lt;li&gt;Typescript&lt;/li&gt;
&lt;li&gt;Unit Testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: This article assumes that you have prior knowledge of JavaScript.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue-PDF-Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;Just a quick background about what I'm working on. &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=20-essential-articles-for-vuejs-vue-3-beginner"&gt;Vue-PDF-Viewer&lt;/a&gt; renders the PDF viewer on your Vue or Nuxt websites so that your users can interact with your PDF document without leaving your sites. The component has over 20 features including theme customization, built-in localization, web responsive and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0fwz6sh5ggcaap7jj10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0fwz6sh5ggcaap7jj10.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be grateful if you could check &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=20-essential-articles-for-vuejs-vue-3-beginner"&gt;Vue-PDF-Viewer&lt;/a&gt; out. It will encourage me to make even more contents ❤️‍🔥&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction to Vue 3:
&lt;/h2&gt;

&lt;p&gt;Before you start coding in Vue, it is essential to gain a solid grasp of its fundamental principles and key concepts. This knowledge will grant you a deeper understanding and lay a robust groundwork for your journey into Vue development.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/hi_iam_chris/series/24385"&gt;VueJS Part 1 to Part 5&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk283ne3ilyezcwdmr683.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk283ne3ilyezcwdmr683.png" alt="VueJS Part 1 to Part 5" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This 5-part series of short articles is a good read for any beginner looking to learn Vue 3. It covers topics from the very basics, from Hello World to directives to conditional rendering and events handling.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/hi_iam_chris/vuejs-part-1-intro-to-vuejs-32cj"&gt;VueJS Part 1: Intro to VueJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hi_iam_chris/vuejs-part-2-hello-vue-and-displaying-values-in-html-4eip"&gt;VueJS Part 2: Hello Vue and displaying values in HTML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hi_iam_chris/vuejs-part-3-vue-directives-and-conditional-rendering-4pam"&gt;VueJS part 3: Vue directives and conditional rendering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hi_iam_chris/vuejs-part-4-rendering-in-loop-n84"&gt;VueJS part 4: Rendering in loop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/hi_iam_chris/vuejs-part-5-handling-events-1p2a"&gt;VueJS part 5: Handling events&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be sure to check out all 5 parts to gain a good understanding on Vue 🎉&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.sitepoint.com/vue-3-beginner-guide/" rel="noopener noreferrer"&gt;A Beginner’s Guide to Vue 3&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0ojkvov28i2henqz6lc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0ojkvov28i2henqz6lc.png" alt="A Beginner’s Guide to Vue 3" width="800" height="458"&gt;&lt;/a&gt;&lt;br&gt;
This article dated back in 2021 showcases examples that uses Vue CLI of an older version. However, the article still provides a great step-by-step guide in creating a simple Vue 3 app and getting to know the basic functionalities of Vue.js. &lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/miracool/part-1-getting-started-with-vue-2d31"&gt;Vue Made Easy: Getting Started with Vue&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8fp75nfa9er0ywea6cju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8fp75nfa9er0ywea6cju.png" alt="Vue Made Easy: Getting Started with Vue" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
This article is part of a larger 4 parts series, and it offers a comprehensive beginner-friendly guide to getting started with Vue.js. It's easy to follow along, thanks to detailed explanations and code examples.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://huericnan.hashnode.dev/vuejs-for-beginners-1" rel="noopener noreferrer"&gt;Vue.js for Beginners #1&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5mrsslf2kg3s7nvrf9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5mrsslf2kg3s7nvrf9f.png" alt="Vue.js for Beginners #1" width="800" height="454"&gt;&lt;/a&gt;&lt;br&gt;
If you are looking for a clear guide with all you need to know to start developing in Vue 3, be sure to check out this 2 parts series written by Eric Hu. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://huericnan.hashnode.dev/vuejs-for-beginners-1" rel="noopener noreferrer"&gt;Vue.js for Beginners #1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://huericnan.hashnode.dev/vuejs-for-beginners-2" rel="noopener noreferrer"&gt;Vue.js for Beginners #2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;a href="https://huericnan.hashnode.dev/vuejs-for-beginners-1" rel="noopener noreferrer"&gt;Part 1&lt;/a&gt;, you will learn the very basics from installation to methods, interpolations and directives. You will also get hands on in building an app. Continue on to &lt;a href="https://huericnan.hashnode.dev/vuejs-for-beginners-2" rel="noopener noreferrer"&gt;Part 2&lt;/a&gt; to find out about event handling, forms and more!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://sweetcode.io/best-practices-for-writing-vue-js/" rel="noopener noreferrer"&gt;Best Practices for Writing Vue.js&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft785fbg1zg608ad804fk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft785fbg1zg608ad804fk.png" alt="Best Practices for Writing Vue.js" width="800" height="429"&gt;&lt;/a&gt;&lt;br&gt;
These best practices are like a helpful guide for beginners that are starting out on Vue. They ensure your code is clean and easy to understand so that you'll not only write better code but also gain confidence as a Vue.js developer.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: &lt;a href="https://roadmap.sh/vue" rel="noopener noreferrer"&gt;Vue Developer Roadmap&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy017bxb34e3la0hwxpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy017bxb34e3la0hwxpm.png" alt="Bonus - Vue Developer Roadmap" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
This cool looking roadmap provides a great guideline to becoming a Vue Developer. Clicking on each node will display links to useful resources for the related topic. After you are done with Vue, you can even proceed on to the Frontend developer or other roadmaps to see what you have missed on your learning journey!✨&lt;/p&gt;




&lt;h2&gt;
  
  
  Options API and Composition API:
&lt;/h2&gt;

&lt;p&gt;The Options API is a traditional way of building Vue components that has been around since 2013. However, since Composition API's release in Vue 3, it has been the preferred method that offers a more flexible and intuitive way to organize and reuse code. It allows developers to encapsulate logic into reusable functions called "composition functions." &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://medium.com/codex/options-api-vs-composition-api-4a745fb8610" rel="noopener noreferrer"&gt;Options API vs. Composition API&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhvp4s833nd8rd8o7ttx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhvp4s833nd8rd8o7ttx.png" alt="Options API vs. Composition API" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
If you have some prior knowledge of Vue 2, chances are you may be wondering if you should use Options API. This article starts by explaining the key concepts of the Options API, such as data, methods, and lifecycle hooks. Then, it introduces the Composition API, highlighting its simplicity and reduced code size.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/the_one/are-you-using-composition-api-the-right-way-4jmm"&gt;How to use Composition API the right way&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazdluf5gujssl28jsczq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazdluf5gujssl28jsczq.png" alt="How to use Composition API the right way" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
This article further dives into the usefulness of using Composition API and the issues with Options API. It explains how to use the Composition API properly and the benefits.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/mokkapps/why-i-love-vue-3s-composition-api-2n3m"&gt;Why I Love Vue 3's Composition API&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbu68smc1i5098bpiaa7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbu68smc1i5098bpiaa7d.png" alt="Why I Love Vue 3's Composition API" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
In this article, Michael Hoffman makes a clear comparison between Options API and Composition API by building the same application with each method.&lt;br&gt;&lt;br&gt;
Jump in if you want to further understand why you should be using Composition API 😎&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://fadamakis.com/from-vue-2-options-api-to-vue-3-composition-api-fe6d6a738c2f" rel="noopener noreferrer"&gt;Refactoring a Component from Vue 2 Options API to Vue 3 Composition API&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyifxok5lrjsulpjpgc34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyifxok5lrjsulpjpgc34.png" alt="Refactoring a Component from Vue 2 Options API to Vue 3 Composition API" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
To truly understand the Composition API, we have to first look back and understand how things work in Vue 2. In this article, it explains Options API from Vue 2 and how it evolves in Vue 3 and why Composition API should be the preferred method.&lt;br&gt;&lt;br&gt;
Great read to understand Composition API from a different perspective.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue Router
&lt;/h2&gt;

&lt;p&gt;Vue Router is a routing library for Vue.js that enables the creation of single-page applications. It allows developers to define routes, handle navigation, and load different components based on the current route. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://vueschool.io/articles/vuejs-tutorials/how-to-use-vue-router-a-complete-tutorial" rel="noopener noreferrer"&gt;How to Use Vue Router: A Complete Tutorial&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh82eijcqcekrqwgev8wu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh82eijcqcekrqwgev8wu.png" alt="How to Use Vue Router: A Complete Tutorial" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
Look no further if you are looking to learn routing in Vue 3. This article covers the basics from Vue Router Fundamentals to Dynamic routing and Lazy Loading.&lt;br&gt;&lt;br&gt;
Good article to read and save for future reference!&lt;br&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-navigate-between-views-with-vue-router" rel="noopener noreferrer"&gt;How To Navigate Between Views with Vue Router&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmxigdqvvp4l9a8auvh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmxigdqvvp4l9a8auvh6.png" alt="How To Navigate Between Views with Vue Router" width="800" height="452"&gt;&lt;/a&gt;&lt;br&gt;
Time to get hands on again! This article explains the need for Vue router and features a step-by-step guide from to build a Vue 3 application and route it with Vue router.&lt;br&gt;&lt;br&gt;
This is part of a 9 parts series with basic and advanced topics. Be sure to check them out as well&lt;/p&gt;




&lt;h2&gt;
  
  
  Pinia Fundamentals
&lt;/h2&gt;

&lt;p&gt;Pinia is a state management library specifically designed for Vue.js 3. It provides a minimalistic approach to managing application state by leveraging the new features of Vue 3, including the Composition API.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://javascript.plainenglish.io/pinia-state-management-in-vue-3-d093a33d66c" rel="noopener noreferrer"&gt;Easy State Management in Vue 3 Using Pinia&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhtg2nyzmkjnbvb1bkwn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhtg2nyzmkjnbvb1bkwn9.png" alt="Easy State Management in Vue 3 Using Pinia" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
This short article showcases the key aspects of Pinia, the superhero of state management in Vue 3. Understand the fundamentals of Pinia and say goodbye to the confusion of passing data around 🚀&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.vuemastery.com/blog/advantages-of-pinia-vs-vuex/" rel="noopener noreferrer"&gt;Advantages of Pinia vs Vuex&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0h2hnilsqhxefyqeeclu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0h2hnilsqhxefyqeeclu.png" alt="Advantages of Pinia vs Vuex" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
If you are working on state management, chances are you may be wondering to use Pinia or Vuex. And although Pinia is the recommended library for Vue.js state management, it helps to understand Vuex which is still used in Vue 3.&lt;br&gt;&lt;br&gt;
You'll find detailed Q&amp;amp;A styled explanations to your questions here!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://coderpad.io/blog/development/how-to-handle-state-management-in-vue-using-pinia" rel="noopener noreferrer"&gt;How To Handle State Management in Vue Using Pinia&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01hnd0u1murkz8fp0bv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01hnd0u1murkz8fp0bv5.png" alt="How To Handle State Management in Vue Using Pinia" width="800" height="419"&gt;&lt;/a&gt;&lt;br&gt;
This post provides a high-level overview of handling state management in a Vue application with Pinia. It elaborates on state management and dive deeper with code examples.&lt;/p&gt;




&lt;h2&gt;
  
  
  TypeScript:
&lt;/h2&gt;

&lt;p&gt;Vue.js 3 introduces enhanced support for TypeScript, a statically typed superset of JavaScript. TypeScript with Vue 3 improves code maintainability, type checking, and error prevention.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.freecodecamp.org/news/learn-typescript-basics/" rel="noopener noreferrer"&gt;Learn TypeScript Basics in this Beginner's Guide&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxtl9qa31f1zd7c5dkar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxtl9qa31f1zd7c5dkar.png" alt="Learn TypeScript Basics in this Beginner's Guide" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
If you are new to TypeScript, this article is a good place to start. Although it does not relate to Vue.js, it contains information to get you started with TypeScript. It guides you through what is TypeScript, the key concepts and also all the cool features of using TypeScript 😎&lt;br&gt;&lt;br&gt;
Be sure also to check out the &lt;a href="https://www.typescriptlang.org/docs/" rel="noopener noreferrer"&gt;TypeScript documentation&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://vueschool.io/articles/vuejs-tutorials/why-use-typescript-with-vue-js/" rel="noopener noreferrer"&gt;Why Use TypeScript with Vue.js?&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rd6pctnrrbuz86hj2bv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rd6pctnrrbuz86hj2bv.png" alt="Why Use TypeScript with Vue.js?" width="800" height="458"&gt;&lt;/a&gt;&lt;br&gt;
Need more convincing to start using TypeScript with Vue 3? Check this article out for more insights on using TypeScript in your Vue.js project. &lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://earnkay.hashnode.dev/getting-started-with-vuejs3-and-typescript-a-beginners-guide" rel="noopener noreferrer"&gt;Getting started with Vue.js3 and Typescript: A Beginners Guide&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13kbxeqmw7aglvbvff9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13kbxeqmw7aglvbvff9q.png" alt="Getting started with Vue.js3 and Typescript: A Beginners Guide" width="800" height="458"&gt;&lt;/a&gt;&lt;br&gt;
Now that you know TypeScript, it's time to dive in. Learn how to set up your project, create components, and effortlessly bind data for dynamic user interfaces 🌟&lt;/p&gt;




&lt;h2&gt;
  
  
  Unit Testing:
&lt;/h2&gt;

&lt;p&gt;Unit testing plays a crucial role in ensuring the quality and reliability of Vue.js applications. Unit testing can be implemented via popular testing frameworks and libraries such as Jest, Vite and Vue Test Utils.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://stackabuse.com/testing-vue-js-components-with-vue-test-utils" rel="noopener noreferrer"&gt;Testing Vue.js Components with Vue Test Utils&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcf8benbkkyax32obfmr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcf8benbkkyax32obfmr.png" alt="Testing Vue.js Components with Vue Test Utils" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
Vue 3 provides an official set of testing utilities known as Vue Test Utils. This article walks you through using Vue Test Utils and Jest to write unit tests. It provides examples to test your Vue.js codes and components such as forms and emitted events.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://medium.com/vue-mastery/getting-started-with-vitest-4897d153b41f" rel="noopener noreferrer"&gt;Getting Started with Vitest&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcqkeogg6g72efoi81jz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcqkeogg6g72efoi81jz.png" alt="Getting Started with Vitest" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
If you are already running your Vue.js projects with Vite, a build tool developed by Evan You, consider using the blazing fast Vitest for your tests instead 🔥 Get started by following the installation instructions and demos in this article.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://vuejsdevelopers.com/2019/08/26/vue-what-to-unit-test-components/" rel="noopener noreferrer"&gt;Knowing What To Test - Vue Component Unit Testing&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fithfg4mvd3q6iuzh7kz0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fithfg4mvd3q6iuzh7kz0.png" alt="Knowing What To Test - Vue Component Unit Testing" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
Learning the tools to unit testing is important, however it is just as crucial to know what to test. As a beginner, you may feel lost at first which components to test.  Understanding this will save you time and effort in testing only the key components and business logics.&lt;br&gt;&lt;br&gt;
Although the codes in this article is written in Vue 2, it is still a good read that provides valuable insights to unit testing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In the world of Vue.js 3, we've rounded up 21 articles that are pretty handy for beginners. These articles cover a bunch of stuff, from the basics of Vue.js to Composition API, Vue Router, Pinia, TypeScript, and unit testing. Whether you're just starting out or want to level up your Vue.js skills, these articles have got you covered. Vue.js is becoming more and more popular, so these resources will help you build web apps with ease. Dive into these articles and become a Vue.js whiz at your own pace! 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue-PDF-Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cb4xzo1wgh1rxqyat5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cb4xzo1wgh1rxqyat5o.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;br&gt;
If you feel like this article helped you, please check out &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=20-essential-articles-for-vuejs-vue-3-beginner"&gt;Vue-PDF-Viewer&lt;/a&gt;. You can customize the PDF viewer component to your theme, add locales, configure panel and more. Each function has TS and JS codes, unit tests and interactive demos. With our starter kits, you can start rendering the &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=20-essential-articles-for-vuejs-vue-3-beginner"&gt;Vue-PDF-Viewer&lt;/a&gt; in minutes.&lt;/p&gt;

&lt;p&gt;It would encourage me to continue creating even more contents. Thank you in advance! 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/ICOgUNjpvO0PC/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ICOgUNjpvO0PC/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>vue</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>⚡️6 Most Popular Vue.js UI Libraries (Vue 3) in 2023 🔥</title>
      <dc:creator>Anson Ch</dc:creator>
      <pubDate>Thu, 14 Sep 2023 12:30:00 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/6-most-popular-vuejs-ui-component-libraries-vue-3-in-2023-5ah5</link>
      <guid>https://dev.to/vue-pdf-viewer/6-most-popular-vuejs-ui-component-libraries-vue-3-in-2023-5ah5</guid>
      <description>&lt;p&gt;Vue.js, a JavaScript framework, has been gaining a lot of attention in recent years due to its simplicity, flexibility, and performance. Also, User Interface (UI) component libraries have become an essential aspect of web development, providing a fast and convenient way to build beautiful and responsive user interfaces.&lt;/p&gt;

&lt;p&gt;With Vue 2 reaching its end of life on December 31, 2023 😱, Vue 3 has become the default choice to build modern applications. The need for UI component libraries designed specifically for Vue 3 has risen. In this article, we will take a look at the six most popular Vue.js UI component libraries for 2023, categorized based on their popularity within English and Chinese-speaking communities.&lt;/p&gt;

&lt;p&gt;I decided to categorize this way because of massive popularity of Vue.js in China according to an interview with Evan You, the creator of Vue.js, who was born in China and grew up in a city near Shanghai.&lt;/p&gt;

&lt;p&gt;Moreover, Vue has well written documents in Chinese. As teams from big companies in China such as Alibaba, Tencent and Baidu started using Vue.js, all these factors may have contributed to its popularity in the country.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue-PDF-Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;Just a quick background about what I'm working on. &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=6-most-popular-vuejs-ui-component-libraries-vue-3-in-2023"&gt;Vue-PDF-Viewer&lt;/a&gt; renders the PDF viewer on your Vue or Nuxt websites so that your users can interact with your PDF document without leaving your sites. The component has over 20 features including theme customization, built-in localization, web responsive and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0fwz6sh5ggcaap7jj10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0fwz6sh5ggcaap7jj10.png" alt="Vue PDF Viewer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be grateful if you could check &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=6-most-popular-vuejs-ui-component-libraries-vue-3-in-2023"&gt;Vue-PDF-Viewer&lt;/a&gt; out. It will encourage me to make even more contents ❤️‍🔥&lt;/p&gt;




&lt;h2&gt;
  
  
  English focused community
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Vuetify
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwr1mdi65sl74yp45tvq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwr1mdi65sl74yp45tvq.png" alt="Vuetify"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vuetify is a popular Vue.js UI component library based on Material Design specifications. It provides over 100 customizable components for creating beautiful and responsive user interfaces. With its modular design, developers can selectively import components, which keeps the bundle size small and improve performance.&lt;br&gt;
Additionally, Vuetify integrates seamless with Nuxt 3 and features powerful theming capabilities where developers can customize their application style and match it with their brand.&lt;/p&gt;

&lt;p&gt;As of September 2023, Vuetify has over 37,900 stars on GitHub and an average weekly downloads count of over 400,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://vuetifyjs.com" rel="noopener noreferrer"&gt;https://vuetifyjs.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Remark: By November 2023, Vuetify 3 (Vue 3) will almost reach 100% feature parity with Vuetify 2.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. PrimeVue
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3jt99u2w4800non5lar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3jt99u2w4800non5lar.png" alt="PrimeVue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PrimeVue is a sleek Vue.js component library that offers over 90 components and 200+ icons making it one of the most comprehensive libraries in the Vue.js community. It's a lightweight library with exclusive Tailwind CSS integration, enabling developers to build complex enterprise-level applications with ease.&lt;/p&gt;

&lt;p&gt;PrimeVue is powered by PrimeTek, which serves millions of developers of Fortune 500 companies such as Intel, Nvidia and American Express, lending it massive credibility in the enterprise space.&lt;/p&gt;

&lt;p&gt;PrimeVue also features an intuitive API, allowing developers to quickly customize the components to achieve their desired designs.&lt;/p&gt;

&lt;p&gt;As of September 2023, PrimeVue has over 4,300 stars on GitHub and an average weekly downloads count of over 90,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://primevue.org/" rel="noopener noreferrer"&gt;https://primevue.org/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Quasar
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl99861e19hv5v8c7er0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl99861e19hv5v8c7er0e.png" alt="Quasar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quasar's UI Components feature 70 high performance customizable Material Design components and icons of various styles (bootstrap, material, fontawesome and many more). The documentation is detailed and well thought-out. The library also has pre-built features including animations and functions to handle dates and times.&lt;/p&gt;

&lt;p&gt;What makes Quasar, founded since 2015, different and standout from other UI component libraries is that Quasar is not only a UI component library but a dynamic Vue framework. You can develop Vue.js desktop, web and mobile applications with a single codebase. As the saying goes, write once and use everywhere.&lt;/p&gt;

&lt;p&gt;As of September 2023, Quasar has over 24,200 stars on GitHub and an average weekly downloads count of over 100,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://quasar.dev/" rel="noopener noreferrer"&gt;https://quasar.dev/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Chinese focused community
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Element Plus
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0sc34lkbmvuht7ccs4vm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0sc34lkbmvuht7ccs4vm.png" alt="Element Plus"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Element Plus is a community developed project born from Element UI which supports only Vue 2.X. Due to its predecessor's popularity, it has naturally gained a lot of attention by developers, especially those in China.&lt;/p&gt;

&lt;p&gt;A TypeScript-based library with a complete type definition, Element Plus is not based on Material Design and has its own distinct UI style which can modified quite easily. Element Plus simplifies component utilization, making the code more maintainable and readable with Vue 3's Composition API.&lt;/p&gt;

&lt;p&gt;As of September 2023, Element Plus has over 21,300 stars on GitHub and an average weekly downloads count of over 170,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://element-plus.org/en-US/" rel="noopener noreferrer"&gt;https://element-plus.org/en-US/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Ant Design Vue
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyny5wxu2zir4usq9ub2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyny5wxu2zir4usq9ub2o.png" alt="Ant Design Vue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ant Design Vue (Antdv) is a popular TypeScript-based UI component library based off Ant Design, a library that was developed for React and was originally created by a team from Alibaba. But it has gained traction in the Vue.js community for its ease of use and its rich feature set. It offers a comprehensive range of components like tree structures, forms, and data visualization components.&lt;/p&gt;

&lt;p&gt;Similar to Element Plus, Antdv has its own unique UI style. Although it may initially seem daunting to explore its huge sets of UI components and features, once you get the hang of it, Antdv can be a very powerful UI component library for projects of all sizes.&lt;/p&gt;

&lt;p&gt;As of September 2023, Ant Design Vue has over 18,600 stars on GitHub and an average weekly downloads count of over 80,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://antdv.com/" rel="noopener noreferrer"&gt;https://antdv.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Vant
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folnuo97qpg4bmc25mnwn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folnuo97qpg4bmc25mnwn.png" alt="Vant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vant is a TypeScript-based UI component library developed by Youzan, a leading merchant servicing platform in China. It offers 80+ easy-to-use and highly customizable components such as button groups, search boxes, and dropdown menus.&lt;/p&gt;

&lt;p&gt;Vant is designed to be lightweight and highly performant, and it provides an easy-to-use component API and user-friendly documentation that makes it very easy for developers to get started. The components are all tree-shakable so they can be imported individually to your application without waste.&lt;/p&gt;

&lt;p&gt;As of September 2023, Vant has over 21,900 stars on GitHub and an average weekly downloads count of over 50,000.&lt;/p&gt;

&lt;p&gt;Learn more on &lt;a href="https://vant-ui.github.io/" rel="noopener noreferrer"&gt;https://vant-ui.github.io/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, Vue.js has gained popularity due to its flexibility, simplicity, and performance. The availability of different UI component libraries has made it easier for developers to build complex and elegant applications at speed with ease. Whether you're building large complex applications or small, highly performant ones, there is always the right Vue.js UI component library suitable for your needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vue-PDF-Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cb4xzo1wgh1rxqyat5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6cb4xzo1wgh1rxqyat5o.png" alt="Vue PDF Viewer"&gt;&lt;/a&gt;&lt;br&gt;
If you feel like this article helped you, please check out &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=6-most-popular-vuejs-ui-component-libraries-vue-3-in-2023"&gt;Vue-PDF-Viewer&lt;/a&gt;. You can customize the PDF viewer component to your theme, add locales, configure panel and more. Each function has TS and JS codes, unit tests and interactive demos. With our starter kits, you can start rendering the &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=6-most-popular-vuejs-ui-component-libraries-vue-3-in-2023"&gt;Vue-PDF-Viewer&lt;/a&gt; in minutes.&lt;/p&gt;

&lt;p&gt;It would encourage me to continue creating even more contents. Thank you in advance! 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExejF1ODJiMm1oN3BkZTBucHhncW42ems2dGV0amF1bjBxNDJnY2tqdyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/QLtO7Hs5FXtJe/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExejF1ODJiMm1oN3BkZTBucHhncW42ems2dGV0amF1bjBxNDJnY2tqdyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/QLtO7Hs5FXtJe/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🤔 3 Major Problems of Reusable Components in Vue.js 🔥</title>
      <dc:creator>Fang Tanbamrung</dc:creator>
      <pubDate>Wed, 06 Sep 2023 12:45:20 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/challenges-of-reusable-components-in-vuejs-and-how-to-overcome-them-4g6d</link>
      <guid>https://dev.to/vue-pdf-viewer/challenges-of-reusable-components-in-vuejs-and-how-to-overcome-them-4g6d</guid>
      <description>&lt;p&gt;When we talk or discuss about creating UI components in Vue.js, reusability is often brought up. Yes, one of the key principles of Vue.js is its component-based architecture, which promotes reusability and modularity. But what does that even mean?&lt;/p&gt;

&lt;p&gt;Let's say you create a reusable component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can you or your colleagues really reuse (no pun intended) it in another part of the system?&lt;/li&gt;
&lt;li&gt;With a new requirement, you may have to consider modifying the "reusable component".&lt;/li&gt;
&lt;li&gt;What if you need to split the "reusable component" to so that you can apply the split component to another place?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/6HNonYwCD4yrHFk7ya/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/6HNonYwCD4yrHFk7ya/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating actually reusable components in Vue.js can be tricky. In this article, I will explore the concept of reusable components, the problems faced when applying them, and why it is essential to overcome these problems as best as I can.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue-PDF-Viewer: Flexible and Powerful Vue.js PDF Component
&lt;/h2&gt;

&lt;p&gt;Just a quick background about what I’m working on. &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=3-major-problems-of-reusable-components-in-vuejs"&gt;Vue-PDF-Viewer&lt;/a&gt; renders the PDF viewer on your Vue or Nuxt websites so that your users can interact with your PDF document without leaving your sites. The component has over 20 features including theme customization, built-in localization, web responsive and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9dwrv9kbsqwf0g8om6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9dwrv9kbsqwf0g8om6w.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be grateful if you could check &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=3-major-problems-of-reusable-components-in-vuejs"&gt;Vue-PDF-Viewer&lt;/a&gt; out. It will encourage me to make even more contents 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Reusable Components?
&lt;/h2&gt;

&lt;p&gt;Reusable components are UI building blocks that can be used in different parts of an application or even across multiple projects. They encapsulate specific functionality or UI patterns and can be easily integrated into other parts of the application without the need for extensive modifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Reusable Components
&lt;/h2&gt;

&lt;p&gt;By using Reusable Components in Vue.js, you can achieve several benefits like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency&lt;/strong&gt;: Allow developers to write code once and reuse it multiple times. This reduces redundancy and saves valuable development time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardization&lt;/strong&gt;: Promote consistency and standardization across a Vue.js project. They ensure that the same design patterns, styles, and functionality are maintained throughout the application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Make it easier to scale and adapt projects as they grow. By breaking down the application into smaller, reusable components, it becomes more manageable to handle complex functionalities and add new features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration&lt;/strong&gt;: Facilitate collaboration among team members working on a Vue.js project. They provide a shared vocabulary and set of UI elements that everyone in the team can use and understand.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3 Problems when Applying Reusable Concept
&lt;/h2&gt;

&lt;p&gt;While reusability is a desirable trait in Vue.js components, several problems can make it difficult to achieve:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modifying Existing Components&lt;/strong&gt;: One problem is modifying existing components that are already being used in the application. The component may need to be changed to support both existing and new requirements. Making changes to a component that is already used in other parts of the application may introduce unintended side effects and break functionality in other areas. Balancing the need for changes with maintaining compatibility can be complex.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design Components for Consistency and Flexibility&lt;/strong&gt;: Another problem is maintaining consistency across different instances of a reusable component while allowing for customization and flexibility. Reusable components should be versatile enough to adapt to different design requirements and styles. However, providing customization options without sacrificing the core functionality and consistency of the component can be tricky.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Managing Component Dependencies and State&lt;/strong&gt;: Using reusable components involves managing dependencies and ensuring that each component remains self-contained and independent. Components should not have tight dependencies on external resources or the application's state management system. This allows for easy integration into different projects and reduces the likelihood of conflicts or unintended side effects.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A Case Study
&lt;/h2&gt;

&lt;p&gt;Let's say, a client wants an internal employee directory system. The project is engaged based on Agile methodology and all requirements cannot be gathered before development. There are 3 phases (Prototype, Phase 1 and Phase 2). For the purpose of this demonstration, I will focus on a card component like below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feponz0u6ups2dtwi4g70.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feponz0u6ups2dtwi4g70.gif" alt="User card component and tooltip component" width="600" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Prototype
&lt;/h3&gt;

&lt;p&gt;As part of the prototype phase, I am required to deliver a User Profile page. The user profile will contain a basic user card component to include user avatar and name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7k2uwupv1mvkynw53uhr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7k2uwupv1mvkynw53uhr.png" alt="basic user card component" width="800" height="201"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// Prototype.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Teleport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"app-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"user-image"&lt;/span&gt;
            &lt;span class="na"&gt;:src=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt;
            &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.app-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.app-card&lt;/span&gt; &lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.app-card&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.user-image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 1
&lt;/h3&gt;

&lt;p&gt;In Phase 1, the client wants to add user detail (birthday, age, phone number and email) onto the user card component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ow3nbb3bx8187i2omu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ow3nbb3bx8187i2omu2.png" alt="user card component with user detail" width="800" height="253"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;//Phase1.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;birthDay&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;birthDay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;birthYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;birthDay&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;birthYear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
        &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"cardRef"&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"app-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"user-image"&lt;/span&gt;
            &lt;span class="na"&gt;:src=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt;
            &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; Birth day: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
                        &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;birthDay&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; Age: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
                        &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; Phone number: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
                        &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; Email: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
                        &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.app-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.app-card&lt;/span&gt; &lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.app-card&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.user-image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, the client is looking to add Employee Directory page and display user profiles in a card format.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17v24gpbm2k7sbq57ic6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17v24gpbm2k7sbq57ic6.gif" alt="search for user profile" width="600" height="560"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// SearchPage
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;SearchInput&lt;/span&gt; &lt;span class="na"&gt;v-model:value=&lt;/span&gt;&lt;span class="s"&gt;"searchValue"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt;
            &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"item.id"&lt;/span&gt;
            &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"item of list"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-bottom: 5px; margin-top: 5px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;UserCard&lt;/span&gt; &lt;span class="na"&gt;v-bind=&lt;/span&gt;&lt;span class="s"&gt;"item"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SearchInput&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/SearchInput.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;UserCard&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/Phase1.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;SearchInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;UserCard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dummyjson.com/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

            &lt;span class="nf"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://dummyjson.com/users/search?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="nf"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;searchValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this stage, the user card component is reusable on both pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2
&lt;/h3&gt;

&lt;p&gt;Users feedback that the Employee Directory page is cluttered. Too much information making the page hard to use. Therefore, the client wants the user detail to be shown in tooltip upon hovered. The requirement on the User Setting page remains unchanged.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feponz0u6ups2dtwi4g70.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feponz0u6ups2dtwi4g70.gif" alt="user card component and tooltip component" width="600" height="328"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// Phase 2
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Teleport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onBeforeUnmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDiveElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isMouseOver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dropdownRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dropdownStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;

&lt;span class="c1"&gt;// add modal element in body to prevent overflow issue&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modalElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;modalElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;modal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modalElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;birthYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;birthYear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onMouseOver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isMouseOver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;isMouseOver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dimension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;targetRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;dropdownStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollY&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onMouseLeave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;isMouseOver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"targetRef"&lt;/span&gt;
    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;mouseover=&lt;/span&gt;&lt;span class="s"&gt;"onMouseOver"&lt;/span&gt;
    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;mouseleave=&lt;/span&gt;&lt;span class="s"&gt;"onMouseLeave"&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"app-card"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"user-image"&lt;/span&gt; &lt;span class="na"&gt;:src=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Teleport&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"#modal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
      &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"dropdownRef"&lt;/span&gt;
      &lt;span class="na"&gt;:style=&lt;/span&gt;&lt;span class="s"&gt;"dropdownStyle"&lt;/span&gt;
      &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: absolute"&lt;/span&gt;
      &lt;span class="na"&gt;v-show=&lt;/span&gt;&lt;span class="s"&gt;"isMouseOver"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"app-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; Birth day: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;birthDate&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; Age: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; Phone number: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; Email: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/Teleport&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.app-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.app-card&lt;/span&gt; &lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.app-card&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.user-image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To look at the codes of Prototype, Phase 1 and Phase 2, you can find them in &lt;a href="https://codesandbox.io/s/reusable-components-in-vue-wwsd5y?file=/src/components/Prototype.vue" rel="noopener noreferrer"&gt;live demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This new requirement causes a headache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I modify the existing user card component to support the tooltip requirement and risk affecting the user card component in the User Setting page? OR&lt;/li&gt;
&lt;li&gt;Do I duplicate the existing user card component and add tooltip feature?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/rJVShwlm8uy9msUfhY/giphy-downsized-large.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/rJVShwlm8uy9msUfhY/giphy-downsized-large.gif" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because we do not want to break what is already in production, we tend to choose the latter option. At first, this may make sense but it can be quite damaging, especially for big and continuous projects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Large Codebase&lt;/strong&gt;: Leads to a larger codebase, as each duplicated component adds unnecessary lines of code. Become difficult to maintain, as developers need to make changes in multiple places whenever an update or bug fix is required. It also increases the chances of inconsistencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Short Term Gain, Long Term Pain&lt;/strong&gt;: Seem like a quick and easy solution in the short term, especially when dealing with tight deadlines or urgent requirements. However, as your project grows, maintaining duplicated components becomes increasingly difficult and time-consuming. Modifications or updates to duplicated components need to be replicated across multiple instances, leading to a higher chance of errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System Performance&lt;/strong&gt;: Can negatively impact system performance. Redundant code increases the size of the application, leading to slower rendering times and increased memory usage. This can result in a suboptimal user experience and reduced system efficiency.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/S79NL9AGw9Cye65fhn/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/S79NL9AGw9Cye65fhn/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Overcome the Above Problems
&lt;/h2&gt;

&lt;p&gt;It's to be mentally prepared that the reusable components may not always remain the same throughout your project. It may sound cliche but if you think about it, requirements are always evolving. You cannot control the future except do the best you can at the moment. Of course, experiences help you designing better components but it takes time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactor Reusable Components
&lt;/h3&gt;

&lt;p&gt;From my experience, I will redesign and refactor the reusable components. Refactoring is a process to restructure codes, while not changing its original functionality. I'm sure there are many ways to refactor and, for me, I refactor and breakdown the components into smaller components. Smaller components allow for flexibility in applying them across the system. Let's take a look how I will apply the case study mentioned above.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: It takes discipline to refactoring UI components. Also, it can be challenging at times since you will need to balance with project delivery deadlines and cleaner codes.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Apply Solution to the Case Study
&lt;/h4&gt;

&lt;p&gt;First, I will split the existing user card components into 4 components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Card component&lt;/li&gt;
&lt;li&gt;Avatar component&lt;/li&gt;
&lt;li&gt;Name component&lt;/li&gt;
&lt;li&gt;User detail component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gx94ikkkv3s8x50u9lc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gx94ikkkv3s8x50u9lc.png" alt="card, avatar, name and user detail components" width="800" height="408"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// Card.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"app-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.app-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.app-card&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// Avatar.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"user-image"&lt;/span&gt;
        &lt;span class="na"&gt;:src=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt;
        &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"avatar"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.user-image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// UserName.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// Description Item
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;: &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// UserDescription.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DescriptionItem&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./DescriptionItem.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;birthYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;birthYear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DescriptionItem&lt;/span&gt;
            &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Birth day"&lt;/span&gt;
            &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"birthDate"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DescriptionItem&lt;/span&gt;
            &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Age"&lt;/span&gt;
            &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"age"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DescriptionItem&lt;/span&gt;
            &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Phone number"&lt;/span&gt;
            &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"phone"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;DescriptionItem&lt;/span&gt;
            &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt;
            &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, I will create a tooltip component. Creating a separate tooltip allows me to reuse it in other parts of the system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytc5h32nn0p3t6qk3p73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytc5h32nn0p3t6qk3p73.png" alt="tooltip component" width="800" height="408"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// Tooltip.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Teleport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onBeforeUnmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isMouseOver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dropdownStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dropdownRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;existModalElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;modal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;existModalElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// add modal element in body to prevent overflow issue&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modalElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;modalElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;modal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modalElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onMouseOver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isMouseOver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;isMouseOver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dimension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;targetRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;dropdownStyle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollY&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onMouseLeave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;isMouseOver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;mouseover=&lt;/span&gt;&lt;span class="s"&gt;"onMouseOver"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;mouseleave=&lt;/span&gt;&lt;span class="s"&gt;"onMouseLeave"&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"targetRef"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"default"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Teleport&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"#modal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
      &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"dropdownRef"&lt;/span&gt;
      &lt;span class="na"&gt;:style=&lt;/span&gt;&lt;span class="s"&gt;"dropdownStyle"&lt;/span&gt;
      &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position: absolute"&lt;/span&gt;
      &lt;span class="na"&gt;v-show=&lt;/span&gt;&lt;span class="s"&gt;"isMouseOver"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Card&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"overlay"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/Card&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/Teleport&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, I will combine the components together like below&lt;/p&gt;

&lt;p&gt;For the &lt;strong&gt;User Setting&lt;/strong&gt; page, I will use the user card component which consists of card, avatar, name component and user detail components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zj5xhnqpe9iovsg676m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zj5xhnqpe9iovsg676m.png" alt="user card component and user detail component" width="800" height="268"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// UserWithDescription.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AppCard&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Card.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DescriptionItem&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./DescriptionItem.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Avatar&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Avatar.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;UserName&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./UserName.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;UserDescription&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./UserDescription.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;AppCard&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Avatar&lt;/span&gt; &lt;span class="na"&gt;:image=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;UserName&lt;/span&gt; &lt;span class="na"&gt;:firstName=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt; &lt;span class="na"&gt;:lastName=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;UserDescription&lt;/span&gt; &lt;span class="na"&gt;v-bind=&lt;/span&gt;&lt;span class="s"&gt;"props"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/AppCard&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As for the &lt;strong&gt;Employee Directory&lt;/strong&gt; page, I plan for 2 combined components&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The basic user card component which consists of card, avatar and name components.&lt;/li&gt;
&lt;li&gt;The user tooltip component which consists of card, tooltip and user detail components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi6me7d4lz3vh5gpv1fp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi6me7d4lz3vh5gpv1fp.gif" alt="user card component and tooltip component" width="600" height="469"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// UserCard.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AppCard&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Card.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DescriptionItem&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./DescriptionItem.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Avatar&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Avatar.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;UserName&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./UserName.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AppCard&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Avatar&lt;/span&gt; &lt;span class="na"&gt;:image=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;UserName&lt;/span&gt;
                    &lt;span class="na"&gt;:firstName=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;
                    &lt;span class="na"&gt;:lastName=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/AppCard&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;// UserCardWithTooltip.vue
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ToolTip&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Tooltip.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;UserDescription&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./UserDescription.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;UserCard&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./UserCard.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Card&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Card.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;birthDate&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ToolTip&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;UserCard&lt;/span&gt; &lt;span class="na"&gt;v-bind=&lt;/span&gt;&lt;span class="s"&gt;"props"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#overlay&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Card&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;UserDescription&lt;/span&gt; &lt;span class="na"&gt;v-bind=&lt;/span&gt;&lt;span class="s"&gt;"props"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/Card&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ToolTip&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details on the refactored codes of this case study, please check out the &lt;a href="https://codesandbox.io/s/reusable-components-in-vue-wwsd5y?file=/src/components/solution/UserCardWithTooltip.vue" rel="noopener noreferrer"&gt;solution&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: You may notice that the solution provide is based on Atomic Design concept. The concept can minimize the "reusability" challenge in the first place. If you are interested on how it can apply to Vue.js, please see my colleague's &lt;a href="https://dev.to/berryjam/introducing-atomic-design-in-vuejs-1l2h"&gt;article&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Do Unit Tests Help?
&lt;/h2&gt;

&lt;p&gt;Some may think that writing unit tests for reusable components will ease this problem. It's true comprehensive test coverage helps ensure that modifications and enhancements to components do not accidentally break functionality.&lt;/p&gt;

&lt;p&gt;However, unit tests do not make a component more reusable. It just makes it more robust. In fact, refactoring into smaller components breaks tasks into specific pieces and makes writing unit tests more manageable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Creating actual reusable components in Vue.js can be challenging due to issues related to modifying existing components, maintaining consistency, and managing dependencies and state. However, the benefits of reusable components make it worth overcoming these problems. Reusable components enhance code organization, improve development efficiency, and facilitate the creation of consistent user interfaces. As we face new requirements or tasks, we will improve so that we can better ourselves at designing reusable components.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Check Out Vue PDF Viewer for Your Next Project&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9dwrv9kbsqwf0g8om6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn9dwrv9kbsqwf0g8om6w.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re working with Vue.js and need a PDF viewer that’s easy to integrate and highly customizable, you should check out &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=3-major-problems-of-reusable-components-in-vuejs"&gt;&lt;strong&gt;Vue PDF Viewer&lt;/strong&gt;&lt;/a&gt;. It allows you to display PDFs directly within your Vue or Nuxt apps, with over 20 features including theme customization, localization, and responsive design.&lt;/p&gt;

&lt;p&gt;I’d really appreciate it if you could give &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_content=3-major-problems-of-reusable-components-in-vuejs"&gt;Vue PDF Viewer&lt;/a&gt; a try and let me know what you think! Your support will help me keep creating more useful tools and content 🙏🔥&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzp4dh79sn5fxfl6homj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzp4dh79sn5fxfl6homj.gif" width="500" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🎉Introducing Atomic Design in Vue.js [Updated]🔥</title>
      <dc:creator>Kittisak Ma</dc:creator>
      <pubDate>Wed, 23 Aug 2023 12:10:56 +0000</pubDate>
      <link>https://dev.to/vue-pdf-viewer/introducing-atomic-design-in-vuejs-1l2h</link>
      <guid>https://dev.to/vue-pdf-viewer/introducing-atomic-design-in-vuejs-1l2h</guid>
      <description>&lt;p&gt;In my experience of building and delivering systems for various clients, depending on their requirements or preferences, it’s inevitable that I may use UI frameworks and libraries like &lt;a href="https://antdv.com/" rel="noopener noreferrer"&gt;Ant Design&lt;/a&gt; and &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt;. Often, I have to build on top of each components. If you are working alone, it’s not such a big problem. But when working as a team, things get complicated quickly. So, I started looking at different methodologies which can provide development flexibility and system maintainability for the projects I’m leading. I choose Atomic Design methodology and want to share why it works for me. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7aq1o8l0u4bjkl7kd5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7aq1o8l0u4bjkl7kd5b.png" alt="Atomic Design Concept" width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bradfrost.com/blog/post/atomic-web-design/" rel="noopener noreferrer"&gt;Atomic Design&lt;/a&gt; is a methodology for creating design systems that breaks down user interfaces into small, reusable components, namely:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Atoms&lt;/li&gt;
&lt;li&gt;Molecules&lt;/li&gt;
&lt;li&gt;Organisms&lt;/li&gt;
&lt;li&gt;Templates&lt;/li&gt;
&lt;li&gt;Pages&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By following a modular approach to design, atomic design helps teams to create consistent, scalable, and maintainable UIs. &lt;/p&gt;

&lt;p&gt;In this post, for simplicity, we'll explore how to implement Atomic Design in &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;Vue.js&lt;/a&gt; with only HTML. I'll start with the basics of Atomic Design and then demonstrate how to apply its principles in Vue.js. &lt;/p&gt;

&lt;p&gt;At the end of the article, you will get a page that consists of a header, a form and a footer. You can use the example here to apply to any UI framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72snuh5xpg9g54cfqcvd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72snuh5xpg9g54cfqcvd.jpg" alt="Image of atomic design with vue components" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You may notice that each component has borders around it. This is intentional so you can identify whether it's an atom, a molecule, or an organism.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/jYLMZUnqZqLb2p113v/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/jYLMZUnqZqLb2p113v/giphy.gif" width="480" height="266"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  Vue-PDF-Viewer: A Versatile and Powerful PDF Solution for Vue.js
&lt;/h2&gt;

&lt;p&gt;Here’s a little background on what I’ve been working on—&lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=introducing-atomic-design-in-vuejs"&gt;Vue PDF Viewer&lt;/a&gt;. This library makes it easy to render PDF documents right within your Vue or Nuxt applications, allowing users to interact with PDFs directly on your site. With features like theme customization, built-in localization, and responsive design, it’s crafted to offer a flexible and seamless user experience tailored to your project’s needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rq93qvo31hksg1gg8gn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rq93qvo31hksg1gg8gn.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find this helpful, I’d love for you to check out &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=introducing-atomic-design-in-vuejs"&gt;Vue PDF Viewer&lt;/a&gt;. Your support inspires me to keep creating and improving tools for the developer community!&lt;/p&gt;

&lt;h2&gt;
  
  
  Anatomy of Atomic Design
&lt;/h2&gt;

&lt;p&gt;Atomic Design consists of five levels that represent the building blocks of UIs. For this example, I have created an inverted tree structure to visualizing how each anatomy is connected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Page
 - Full Layout Template
  - Header Organism
    - Logo Atom
    - Search Form Molecule
      - TextBox Atom
      - Button Atom
  - Content Organsim
    - Form Molecule
      - 2x TextBox Atoms
      - Button Atom
  - Footer Organism
    - Copyright Atom
    - Subscribe Form Molecule
      - TextBox Atom
      - Button Atom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;1. Atoms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Atoms are the smallest units of UI that cannot be broken down further without losing their meaning. Examples of atoms include icons, buttons, labels, inputs, and typography. &lt;/p&gt;

&lt;p&gt;In Vue.js, atoms can be created as reusable components that accept props to customize their appearance and behavior. For this instance, we have a few atoms to prepare for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Textbox
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Finjdmpjzmuofnttsqk1y.png" alt="Image textBoxAtom" width="586" height="142"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"component-wrapper"&lt;/span&gt; &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"textBoxAtom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;:placeholder=&lt;/span&gt;&lt;span class="s"&gt;"placeHolder"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TextBoxAtom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;labelName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; 
    &lt;span class="na"&gt;placeHolder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="p"&gt;},&lt;/span&gt; 
&lt;span class="p"&gt;};&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.75em&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Button
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuaqa6614jnivxhfxpcmh.png" alt="Image buttonAtom" width="264" height="140"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"component-wrapper"&lt;/span&gt; &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"buttonAtom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;:disabled=&lt;/span&gt;&lt;span class="s"&gt;"disabled"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;slot&amp;gt;&lt;/span&gt;Button&lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt; 
 &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ButtonAtom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;  
&lt;span class="p"&gt;};&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#4fc08d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5em&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Logo
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xfcbwy6vlpiz6wx04pw.png" alt="Image logoAtom" width="142" height="176"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"component-wrapper"&lt;/span&gt; &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"logoAtom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;:src=&lt;/span&gt;&lt;span class="s"&gt;"computedImageUrl"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"logo"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;computedImageUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`https://picsum.photos/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a closer look, you can check out the codes in the &lt;a href="https://codepen.io/collection/xKagKz" rel="noopener noreferrer"&gt;Atoms collection&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Molecules&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Molecules are combinations of two or more atoms that work together to perform a specific function. In Vue.js, molecules can be created by composing atoms as child components within a parent component. Examples of molecules include forms, search bars, navigation menus, and cards. &lt;/p&gt;

&lt;p&gt;Referring to the example above, we will need to combine the atoms to create the following molecules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subscribe Form Molecule 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8smh36m47d37aczvi51.png" alt="Image subscribeFormMolecule" width="800" height="180"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"component-wrapper"&lt;/span&gt; &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"subscribeFormMolecules"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TextboxAtom&lt;/span&gt; &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ButtonAtom&amp;gt;&lt;/span&gt;Subscribe&lt;span class="nt"&gt;&amp;lt;/ButtonAtom&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TextboxAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/LYXgdKg.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ButtonAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/BaGqrJg.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ButtonAtom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TextboxAtom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Search Form Molecule
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufa9v06h7i8rdg77kd2e.png" alt="Image searchFormMolecule" width="800" height="189"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"component-wrapper"&lt;/span&gt; &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"searchFormMolecules"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;InputAtom&lt;/span&gt; &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Search"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ButtonAtom&amp;gt;&lt;/span&gt;Search&lt;span class="nt"&gt;&amp;lt;/ButtonAtom&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;InputAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/LYXgdKg.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ButtonAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/BaGqrJg.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ButtonAtom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InputAtom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Form Molecule
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9jzqcoljqokgxp7b7bz.png" alt="Image formMolecule" width="608" height="488"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-molecule component-wrapper"&lt;/span&gt; &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"formMolecules"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;InputAtom&lt;/span&gt; &lt;span class="na"&gt;:label=&lt;/span&gt;&lt;span class="s"&gt;"nameLabel"&lt;/span&gt; &lt;span class="na"&gt;:placeholder=&lt;/span&gt;&lt;span class="s"&gt;"namePlaceholder"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;InputAtom&lt;/span&gt; &lt;span class="na"&gt;:label=&lt;/span&gt;&lt;span class="s"&gt;"emailLabel"&lt;/span&gt; &lt;span class="na"&gt;:placeholder=&lt;/span&gt;&lt;span class="s"&gt;"emailPlaceholder"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ButtonAtom&lt;/span&gt; &lt;span class="na"&gt;:disabled=&lt;/span&gt;&lt;span class="s"&gt;"isSubmitDisabled"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;submitLabel&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/ButtonAtom&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;InputAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/LYXgdKg.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ButtonAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/BaGqrJg.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FormMolecule&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;InputAtom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ButtonAtom&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;nameLabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;namePlaceholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;emailLabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;emailPlaceholder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;submitLabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isSubmitDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the codes in the &lt;a href="https://codepen.io/collection/qOkROP" rel="noopener noreferrer"&gt;Molecules collection&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Organisms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Organisms are combinations of molecules that form distinct sections of a UI, such as headers, footers, sidebars, and content blocks. In Vue.js, organisms can be created by composing molecules as child components within a layout component.&lt;/p&gt;

&lt;p&gt;For this exercise, three organisms are needed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Header Organism
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9y2wrre2pgleeryj1hh9.png" alt="Image headerOrganism" width="800" height="92"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"component-wrapper"&lt;/span&gt; &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"headerOrganism"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;LogoAtom&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"60"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SearchFormMoecules&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SearchFormMoecules&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/zYMmjqa.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LogoAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/xxQMbeJ.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SearchFormMoecules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LogoAtom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Content Organism
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxtlh251u7ppw5wpbgtz.png" alt="Image contentOrganism" width="800" height="212"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"page-organism"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content-wrapper-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Here might be a page title&lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Here might be a page description&lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;slot&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!--   This might includes some molecules or atoms   --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ContentOrganism&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.page-organism&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inset&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt; &lt;span class="m"&gt;-3px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.content-wrapper-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Footer Organism&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31uzkg2xmbv056t87qkq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31uzkg2xmbv056t87qkq.jpg" alt="Image of atomic design with Vue.js - footer" width="800" height="69"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;footer&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"component-wrapper"&lt;/span&gt; &lt;span class="na"&gt;data-name=&lt;/span&gt;&lt;span class="s"&gt;"footerOrganism"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;CopyrightAtom&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SubscribeFormMoecules&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SubscribeFormMoecules&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/ExOrarL.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LogoAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/xxQMbeJ.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CopyrightAtom&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/gOQqOBj.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SubscribeFormMoecules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LogoAtom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CopyrightAtom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;footer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Per usual, here's a &lt;a href="https://codepen.io/collection/LPJxPO" rel="noopener noreferrer"&gt;collection of organisms' codes&lt;/a&gt; that I've created.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Templates&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Templates are the structures that define the layout and composition of pages by specifying the placement and size of organisms within regions, such as headers, footers, and content areas. &lt;/p&gt;

&lt;p&gt;In Vue.js, templates can be created as parent components that accept named slots for child components. Applying the 3 organisms to the &lt;em&gt;Templates&lt;/em&gt; concept, here is how it could look like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frl41uqmlw0pnjgx8fx48.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frl41uqmlw0pnjgx8fx48.jpg" alt="Image of atomic design with Vue.js - full layout template" width="800" height="505"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"full-layout-template"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;HeaderOrganism&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ContentOrganism&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#title&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;default title&lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#description&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;default description&lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ContentOrganism&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;FooterOrganism&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"page-footer"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;HeaderOrganism&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/WNYaJGR.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ContentOrganism&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/vYQbOeO.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FooterOrganism&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/RwqvPRN.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FullLayoutTemplate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;HeaderOrganism&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ContentOrganism&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;FooterOrganism&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.full-layout-template&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;90vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.page-footer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex-shrink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here is the &lt;a href="https://codepen.io/9haroon/pen/GRwzpxx" rel="noopener noreferrer"&gt;CodePen's link&lt;/a&gt; of the template &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Pages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pages are the final presentation of UIs that combine templates with specific content to form complete views. In Atomic Design, pages are like instances of templates that represent unique experiences for users. &lt;/p&gt;

&lt;p&gt;In Vue.js, pages can be created by copying a template and replacing its slots with actual content. Although, in this example, I only change the content of &lt;em&gt;Content Organism&lt;/em&gt;, you could choose to change all or no content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy63d3v1xuee3r5us7v26.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy63d3v1xuee3r5us7v26.jpg" alt="Image of atomic design with Vue.js - HomePage" width="800" height="513"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;FullLayoutTemplate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#title&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;#description&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fixed-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;FormMolecule&lt;/span&gt; &lt;span class="na"&gt;nameLabel=&lt;/span&gt;&lt;span class="s"&gt;"Name"&lt;/span&gt; &lt;span class="na"&gt;emailLabel=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt; &lt;span class="na"&gt;submitLabel=&lt;/span&gt;&lt;span class="s"&gt;"Save"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/FullLayoutTemplate&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FullLayoutTemplate&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/GRwzpxx.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FormMolecule&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://codepen.io/9haroon/pen/PoxyRMo.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HomePage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;FullLayoutTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;FormMolecule&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to my example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is an example of Atomic Design in Vue.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;copyright&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Copyright © 2023&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Avenir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.fixed-width&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;350px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here is the &lt;a href="https://codepen.io/9haroon/pen/qBQgOGj" rel="noopener noreferrer"&gt;CodePen's link&lt;/a&gt; of the page &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExbXVmOHF4ZHczZG15Y281djFzb3U3ZXRqeWliZHg5Y2N5MWloaGVnNiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/Y655D2pOIBCQU/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExbXVmOHF4ZHczZG15Y281djFzb3U3ZXRqeWliZHg5Y2N5MWloaGVnNiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/Y655D2pOIBCQU/giphy.gif" width="524" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🆕 &lt;strong&gt;Update:&lt;/strong&gt; While this article uses Vue 2 in its code examples, I've also created a full Vue 3 + Composition API + TypeScript version on Stackblitz.&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://stackblitz.com/edit/atomic-design-with-vue3" rel="noopener noreferrer"&gt;Try it on Stackblitz&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Benefits of Atomic Design in Vue.js
&lt;/h2&gt;

&lt;p&gt;By using Atomic Design in Vue.js, you can achieve several benefits, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Consistency: By creating reusable components, you ensure that your UIs look and behave consistently across all pages. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalability: By breaking down UIs into small pieces, you can easily add, remove, or update components without affecting other parts of the system. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintainability: By organizing components into folders and files, you can easily find, edit, or debug them in isolation from other parts of the system. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reusability: By creating standalone components, you can reuse them in other projects or share them with the community, thus saving time and effort. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Atomic Design is a powerful methodology that can help you design better UIs in Vue.js. By following its principles, you can create reusable, modular, and scalable components that make your code more maintainable and your users more satisfied. So, go ahead, give it a try, and let me know how it worked for you!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3og0IPMeREHpEV0f60/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3og0IPMeREHpEV0f60/giphy.gif" width="480" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue PDF Viewer: A Complete PDF Solution for Vue.js
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rq93qvo31hksg1gg8gn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rq93qvo31hksg1gg8gn.png" alt="Vue PDF Viewer" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re looking for a powerful, flexible solution for rendering PDFs directly in your Vue or Nuxt applications, &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=introducing-atomic-design-in-vuejs"&gt;Vue PDF Viewer&lt;/a&gt; is the tool for you. Offering a wide array of features—like theme customization, localization support, and responsive layouts—it’s built to handle a range of project requirements while delivering a seamless, user-friendly experience.&lt;/p&gt;

&lt;p&gt;If this sounds useful to you, feel free to explore &lt;a href="https://www.vue-pdf-viewer.dev/?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=introducing-atomic-design-in-vuejs"&gt;Vue PDF Viewer&lt;/a&gt; and see how it can enhance your next project. It would mean the world and encourage me to create more content.&lt;/p&gt;

&lt;p&gt;Thank you in advance! 🙏&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
