Skip to content

Getting Started with Vuetify in Vue 3

If you're here to learn about Vuetify and how to use it with Vue 3, you've come to the right place. In this article, we'll introduce Vuetify, a Material Design component framework for Vue.js, and walk you through setting it up in a Vue 3 project.

We will also build a simple web app that allows us to create and vue jokes. Oh, sorry, view* jokes!

What is Vuetify?

Vuetify is a VueJS Material Design component framework. That is to say that Vuetify provides us with prebuilt components and features (e.g. internationalization, tree shaking, theming, etc.) to help us build Vue applications faster. Additionally, Vuetify components have built-in standard functionality, such as validation in form inputs, or various disabled states in buttons.

You can check out a full list of components supported by Vuetify on their official documentation website.

Setting things up

Before we get started, you will need the following on your machine:

  • NodeJS installed
  • A NodeJS package manager e.g. yarn or npm installed
  • Intermediate knowledge of Vue 3.x with the composition API

If you’d like to follow along, feel free to clone the github repository for this article.

git clone https://github.com/thisdot/blog-demos.git
# or `git@github.com:thisdot/blog-demos.git` for ssh

# then cd into the project directory
cd getting-started-with-vuetify

Installing Vuetify

We will be using yarn to install and setup Vuetify 3 (the version that supports Vue 3) in this case.

First, let's create a new Vuetify project. You can do this by running the following command in your terminal or command prompt:

yarn create vuetify

This will create a new Vuetify project. For our jokes app, we will use the Essentials (Vuetify, VueRouter, Pinia) preset when creating our app. We will also be using TypeScript for our app, but this is not necessary.

Since VueJS allows us to build incrementally, if you would like to instead add Vuetify to an existing project, you can use the manual steps provided by the Vuetify team.

Testing our application

Once we have installed and configured our application, cd into the project's directly, and run the app using the following command:

yarn dev #or `npm run dev` (if using npm instead)

Visit localhost:3000/ to see your app in action.

Vuetify project folder structure

Our Vuetify project is generally structured as follows:

  • public - Contains static assets that do not need preprocessing eg. our application favicon
  • src - Contains our VueJS source code. We'll mostly be working here.
    • assets - Assets that need to be preprocessed eg. our images that may need to be compressed when building for production
    • components
    • layouts - Layouts
    • plugins - Everything gets wired up here (registration of our app as well as vuetify, our router & pinia)
    • router - Vue router-related functionality
    • store - Pinia store
    • styles
    • views - our web app's "pages"

Worth noting before building

It is worth noting that all components in Vuetify start with a v- for example:

  • v-form is a form
  • v-btn is a button component
  • v-text-field is an input field

and so on and so forth.

When creating your own components, it is recommended to use a different naming approach so that it is easier to know which components are Vuetify components, and which ones are your components.

Building our Vuetify application

We will build a web app that allows us to add, view and delete jokes.

image

Here are the steps we will take to build our app:

  • Delete unnecessary boilerplate from generated Vuetify app
  • Add a joke pinia store - we'll be using this to store our jokes globally using Pinia
  • Create our joke components
    • components/jokes/CreateJokeForm.vue - the form that allows us to add jokes
    • components/jokes/JokeList.vue - Lists our jokes out.
  • Add our components to our Home.vue to view them in our home page

Setting up the jokes pinia store

In the src/store/ directory, create a new file called joke.ts that will serve as our Pinia store for storing our jokes. The file content for this will be as follows:

import { defineStore } from "pinia";

export interface Joke {
  id: number;
  title: string;
  punchline: string;
}

export const useJokeStore = defineStore({
  id: "joke",
  state: () => ({
    jokes: [] as Joke[],
  }),
  actions: {
    addJoke(joke: Joke) {
      this.jokes.push(joke);
    },
    removeJoke(id: number) {
      this.jokes = this.jokes.filter((joke) => joke.id !== id);
    },
  },
});

This code defines a special storage space called a "store" for jokes in our Vue.js app. This store keeps track of all the jokes we've added through our app's form. Each joke has an ID, title, and punchline.

The addJoke function in the store is used to add a new joke to the store when a user submits the form. The removeJoke function is used to delete a joke from the store when a user clicks the delete button.

By using this store, we can keep track of all the jokes that have been added through the app, and we can easily add or remove jokes without having to manage the list ourselves.

Creating the joke components

CreateJokeForm.vue

Create a file in src/components/jokes/ called CreateJokeForm.vue. This file defines a Vue.js component that displays a form for adding new jokes. The file should have the following contents:

Template section

<template>
  <v-form @submit.prevent="submitJoke">
    <v-text-field
      v-model="jokeTitle"
      label="Joke Title"
      outlined
      required
    ></v-text-field>
    <v-text-field
      v-model="jokePunchline"
      label="Joke Punchline"
      outlined
      required
    ></v-text-field>

    <v-btn
      color="primary"
      :disabled="!jokeTitle || !jokePunchline"
      type="submit"
      >Submit Joke</v-btn
    >
  </v-form>
</template>

In the template section, we define a form using the v-form component from Vuetify. We bind the form's submit event to the submitJoke method, which will be called when the form is submitted.

Inside the form, we have two text fields" one for the joke title, and one for the punchline. These text fields are implemented using the v-text-field component from Vuetify. The label prop sets the label for each text field, and the outlined prop creates an outlined style for each text field. The required prop sets the fields as required, meaning that they must be filled in before the form can be submitted.

Finally, we have a submit button implemented using the v-btn component from Vuetify. The button is disabled until both the title and punchline fields are filled in, which is accomplished using the :disabled prop with a computed property that checks if both fields are empty.

Script section

<script lang="ts" setup>
import { computed, ref } from "vue";
import { Joke, useJokeStore } from "@/store/joke";

const jokeStore = useJokeStore();

const jokeTitle = ref("");
const jokePunchline = ref("");

const joke = computed<Joke>(() => ({
  id: jokeStore.jokes.length + 1,
  title: jokeTitle.value,
  punchline: jokePunchline.value,
}));

function submitJoke() {
  jokeStore.addJoke(joke.value);
  jokeTitle.value = "";
  jokePunchline.value = "";
}
</script>

In the script section, we import some functions and types from Vue.js and the joke store. We then define a jokeStore variable that holds the instance of the useJokeStore function from the joke store.

We also define two refs, jokeTitle, and jokePunchline, which hold the values of the form's title and punchline fields, respectively.

We then define a computed property, joke, which creates a new Joke object using the jokeTitle and jokePunchline refs, as well as the length of the jokes array in the jokeStore to set the id property.

Finally, we define a submitJoke function that calls the addJoke method from the jokeStore to add the new joke object to the store. We also reset the jokeTitle and jokePunchline refs to empty strings.

JokeList.vue

Template section

This one looks bulky. But in essence, all we are doing is displaying a list of jokes when they are found, and a message that lets us know that there are no jokes if we have none that have been added.

<template>
  <v-card>
    <v-card-title>
      My Jokes
      <v-icon icon="mdi-emoticon-excited-outline"></v-icon>
    </v-card-title>
    <v-card-text>
      <v-list v-if="jokeStore.jokes.length">
        <v-list-item v-for="joke in jokeStore.jokes" :key="joke.id">
          <v-row>
            <v-col cols="10">
              <v-list-item-subtitle>{{ joke.title }}</v-list-item-subtitle>
              <v-list-item-title>
                {{ joke.punchline }}
              </v-list-item-title>
            </v-col>
            <v-col cols="2">
              <v-list-item-action>
                <v-btn
                  color="error"
                  variant="outlined"
                  @click="deleteJoke(joke)"
                >
                  <v-icon>mdi-delete</v-icon>
                </v-btn>
              </v-list-item-action>
            </v-col>
          </v-row>
        </v-list-item>
      </v-list>
      <v-alert v-else type="info"> You have no jokes. Add some! </v-alert>
    </v-card-text>
  </v-card>
</template>

In the template section, we define a v-card component, which is a container component used to group related content in Vuetify. The card contains a title, which includes an excited emoticon icon from the mdi-emoticon-excited-outline icon set from Material Design Icons, displayed using the v-icon component.

The jokes are displayed in a v-list, which is a component used to display lists in Vuetify. Each joke is represented by a v-list-item containing a title and subtitle. The v-row and v-col components from Vuetify are used to divide each list item into two columns: one column for the joke title and punchline, and another column for the delete button.

The delete button is implemented using the v-btn component from Vuetify. The button is red, and outlined using the color="error" and variant="outlined" props, respectively. The @click event is used to call the deleteJoke function when the button is clicked.

If there are no jokes in the jokeStore, the component displays an v-alert component with a message to add some jokes.

Script section

<script setup lang="ts">
import { Joke, useJokeStore } from "@/store/joke";

const jokeStore = useJokeStore();

function deleteJoke(joke: Joke) {
  jokeStore.removeJoke(joke.id);
}
</script>

In the script section, we import some functions and types from the joke store. We then define a jokeStore variable that holds the instance of the useJokeStore function from the joke store.

We also define a deleteJoke function that takes a joke object as an argument and calls the removeJoke method from the jokeStore to remove the joke from the store.

This component is called JokeList.vue and displays a list of jokes using Vuetify components like v-card, v-list, v-list-item, v-row, v-col, and v-btn. The component includes a deleteJoke function to remove a joke from the jokeStore as well.

Wiring it up

To display our form as well as list of jokes, we will go to the src/views/Home.vue file and change its contents to the following:

<template>
  <v-container>
    <v-row>
      <v-col cols="12" md="6">
        <CreateJokeForm />
      </v-col>
      <v-col cols="12" md="6">
        <JokeList />
      </v-col>
    </v-row>
  </v-container>
</template>

<script lang="ts" setup>
import CreateJokeForm from "@/components/jokes/CreateJokeForm.vue";
import JokeList from "@/components/jokes/JokeList.vue";
</script>

The Home.vue file defines a Vue.js view that displays the home page of our app. The view contains a v-container component, which is a layout component used to provide a responsive grid system for our app.

Inside the v-container, we have a v-row component, which is used to create a horizontal row of content. The v-row contains two v-col components, each representing a column of content. The cols prop specifies that each column should take up 12 columns on small screens (i.e. the entire row width), while on medium screens, each column should take up 6 columns (i.e. half the row width).

The first v-col contains the CreateJokeForm component, which displays a form for adding new jokes. The second v-col contains the JokeList component, which is used to display a list of jokes that have been added through the form.

In the script section of the file, we import the CreateJokeForm and JokeList components, and register them as components for use in the template.

This view provides a simple and responsive layout for our app's home page, with the CreateJokeForm and JokeList components displayed side by side on medium screens and stacked on small screens.

Bonus: Layouts & Theming

Layouts

Even though we had no need to adjust our layouts in our current jokes application, layouts are an important concept in Vuetify. They allow us to pre-define reusable layouts for our applications. These could include having a different layout for when users are logged in, and when they are logged out or layouts for different types of users.

In our application, we used the default Layout (src/layouts/default/Default.vue) but Vuetify offers us the flexibility to build different layouts for the different domains in our applications. Vuetify also supports nested layouts. You can learn more about layouts in Vuetify in the official Vuetify documentation.

Theming

If you have specific brand needs for your application. Vuetify has a built-in theming system that allows you to customize the look and feel of your application. You can learn more about theming in the official Vuetify theming documentation.

Conclusion

In this article, we introduced Vuetify, and covered how to set it up with Vue 3. We built a VueJS app that allows us to add and manage jokes. We also discussed how to use various Vuetify components to compose our UI, from v-form for declaring forms to v-row for creating a row/column layout, and v-list for displaying a list of items among others.

With this knowledge, you can start using Vuetify in your Vue 3 projects and create stunning user interfaces. Also, if you'd like to start your own VueJS project but need help with how to structure it or would like to skip the tedious setup steps of setting up a VueJS project, you can use the Vue 3 Starter.dev kit to skip the boilerplate and start building!

Next steps for learning Vuetify and Vue 3 development

Now that you have an understanding of Vuetify, it's time to dive deeper into its features, and explore more advanced use cases. To continue your learning journey, consider the following resources:

  1. Official Vuetify documentation: The Vuetify documentation is an excellent resource for learning about all the features and components Vuetify offers.

  2. Vue 3 documentation: To get the most out of Vuetify, it's essential to have a solid understanding of Vue 3. Read the official Vue 3 documentation and practice building Vue applications.

Happy coding, and have fun exploring the world of Vuetify and Vue 3!

This Dot Labs is a development consultancy that is trusted by top industry companies, including Stripe, Xero, Wikimedia, Docusign, and Twilio. This Dot takes a hands-on approach by providing tailored development strategies to help you approach your most pressing challenges with clarity and confidence. Whether it's bridging the gap between business and technology or modernizing legacy systems, you’ll find a breadth of experience and knowledge you need. Check out how This Dot Labs can empower your tech journey.

You might also like

How to automatically deploy your full-stack JavaScript app with AWS CodePipeline cover image

How to automatically deploy your full-stack JavaScript app with AWS CodePipeline

How to automatically deploy your full-stack JavaScript app from an NX monorepo with AWS CodePipeline In our previous blog post (How to host a full-stack JavaScript app with AWS CloudFront and Elastic Beanstalk) we set up a horizontally scalable deployment for our full-stack javascript app. In this article, we would like to show you how to set up AWS CodePipeline to automatically deploy changes to the application. APP Structure Our application is a simple front-end with an API back-end set up in an NX monorepo. The production built API code is hosted in Elastic Beanstalk, while the front-end is stored in S3 and hosted through CloudFront. Whenever we are ready to make a new release, we want to be able to deploy the new API and front-end versions to the existing distribution. In this article, we will set up a CodePipeline to deploy changes to the main branch of our connected repository. CodePipeline CodeBuild and the buildspec file First and foremost, we should set up the build job that will run the deploy logic. For this, we are going to need to use CodeBuild. Let's go into our repository and set up a build-and-deploy.buildspec.yml` file. We put this file under the `tools/aws/` folder. `yaml version: 0.2 phases: install: runtime-versions: nodejs: 18 on-failure: ABORT commands: - npm ci build: on-failure: ABORT commands: # Build the front-end and the back-end - npm run build:$ENVIRONMENTTARGET # TODO: Push FE to S3 # TODO: Push API to Elastic beanstalk ` This buildspec file does not do much so far, we are going to extend it. In the installation phase, it will run npm ci` to install the dependencies and in the build phase, we are going to run the build command using the `ENVIRONMENT_TARGET` variable. This is useful, because if you have more environments, like `development` and `staging` you can have different configurations and builds for those and still use the same buildspec file. Let's go to the Codebuild page in our AWS console and create a build project. Add a descriptive name, such as your-appp-build-and-deploy`. Please provide a meaningful description for your future self. For this example, we are going to restrict the number of concurrent builds to 1. The next step is to set up the source for this job, so we can keep the buildspec file in the repository and make sure this job uses the steps declared in the yaml file. We use an access token that allows us to connect to GitHub. Here you can read more on setting up a GitHub connection with an access token. You can also connect with Oauth, or use an entirely different Git provider. We set our provider to GitHub and provided the repository URL. We also set the Git clone depth to 1, because that makes checking out the repo faster. In the Environment` section, we recommend using an AWS CodeBuild managed image. We use the Ubuntu Standard runtime with the `aws/codebuild/standard:7.0` version. This version uses Node 18. We want to always use the latest image version for this runtime and as the `Environment type` we are good with `Linux EC2`. We don't need elevated privileges, because we won't build docker images, but we do want to create a new service role. In the Buildspec` section select `Use a buildspec file` and give the path from your repository root as the `Buildspec name`. For our example, it is `tools/aws/build-and-deploy.buildspec.yml`. We leave the `Batch configuration` and the `Artifacts` sections as they are and in the `Logs` section we select how we want the logs to work. For this example, to reduce cost, we are going to use S3 logs and save the build logs in the `aws-codebuild-build-logs` bucket that we created for this purpose. We are finished, so let's create the build project. CodePipeline setup To set up automated deployment, we need to create a CodePipeline. Click on Create pipeline` and give it a name. We also want a new service role to be created for this pipeline. Next, we should set up the source stage. As the source provider, we need to use GitHub (version2)` and set up a connection. You can read about how to do it here. After the connection is set up, select your repository and the branch you want to deploy from. We also want to start the pipeline if the source code changes. For the sake of simplicity, we want to have the Output artefact format as CodePipeline default. At the Build stage, we select AWS CodeBuild` as the build provider and let's select the build that we created above. Remember that we have the `ENVIRONMENT_TARGET` as a variable used in our build, so let's add it to this stage with the `Plaintext` value `prod`. This way the build will run the `build:prod` command from our `package.json`. As the `Build type` we want `Single build`. We can skip the deployment stage because we are going to set up deployment in our build job. Review our build pipeline and create it. After it is created, it will run for the first time. At this time it will not deploy anything but it should run successfully. Deployment prerequisites To be able to deploy to S3 and Elastic Beanstalk, we need our CodeBuild job to be able to interact with those services. When we created the build, we created a service role for it. In this example, the service role is codebuild-aws-test-build-and-deploy-service-role`. Let's go to the IAM page in the console and open the `Roles` page. Search for our codebuild role and let's add permissions to it. Click the `Add permissions` button and select `Attach policies`. We need two AWS-managed policies to be added to this service role. The `AdministratorAccess-AWSElasticBeanstalk` will allow us to deploy the API and the `AmazonS3FullAccess` will allow us to deploy the front-end. The `CloudFrontFullAccess` will allow us to invalidate the caches so CloudFront will send the new front-end files after the deployment is ready. Deployment Upload the front-end to S3 Uploading the front-end should be pretty straightforward. We use an AWS CodeBuild managed image in our pipeline, therefore, we have access to the aws` command. Let's update our buildspec file with the following changes: `yaml phases: ... build: on-failure: ABORT commands: # Build the front-end and the back-end - npm run build:$ENVIRONMENTTARGET # Delete the current front-end and deploy the new version front-end - aws s3 sync dist/apps/frontend/ s3://$FRONTEND_BUCKET --delete # Invalidate cloudfront caches to immediately serve the new front-end files - aws cloudfront create-invalidation --distribution-id $CLOUDFRONTDISTRIBUTION_ID --paths "/index.html" # TODO: Push API to Elastic beanstalk ` First, we upload the fresh front-end build to the S3 bucket, and then we invalidate the caches for the index.html` file, so CloudFront will immediately serve the changes. If you have more static files in your app, you might need to invalidate caches for those as well. Before we push the above changes up, we need to update the environment variables in our CodePipeline. To do this open the pipeline and click on the Edit` button. This will then enable us to edit the `Build` stage. Edit the build step by clicking on the edit button. On this screen, we add the new environment variables. For this example, it is aws-hosting-prod` as `Plaintext` for the `FRONT_END_BUCKET` and `E3FV1Q1P98H4EZ` as `Plaintext` for the `CLOUDFRONT_DISTRIBUTION_ID` Now if we add changes to our index.html file, for example, change the button to HELLO 2`, commit it and push it. It gets deployed. Deploying the API to Elastic Beanstalk We are going to need some environment variables passed down to the build pipeline to be able to deploy to different environments, like staging or prod. We gathered these below: - COMMIT_ID`: `#{SourceVariables.CommitId}` - This will have the commit id from the checkout step. We include this, so we can always check what commit is deployed. - ELASTIC_BEANSTALK_APPLICATION_NAME`: `Test AWS App` - This is the Elastic Beanstalk app which has your environment associated. - ELASTIC_BEANSTALK_ENVIRONMENT_NAME`: `TestAWSApp-prod` - This is the Elastic Beanstalk environment you want to deploy to - API_VERSION_BUCKET`: `elasticbeanstalk-us-east-1-474671518642` - This is the S3 bucket that was created by Elastic Beanstalk With the above variables, we can make some new variables during the build time, so we can make sure that every API version is unique and gets deployed. We set this up in the install phase. `yaml ... phases: install: runtime-versions: nodejs: 18 on-failure: ABORT commands: - APPVERSION=`jq '.version' -j package.json` - APIVERSION=$APP_VERSION-build$CODEBUILD_BUILD_NUMBER - APIZIP_KEY=$COMMIT_ID-api.zip - 'APPVERSION_DESCRIPTION="$AP_VERSION: $COMMIT_ID"' - npm ci ... ` The APP_VERSION` variable is the version property from the `package.json` file. In a release process, the application's version is stored here. The `API_VERSION` variable will contain the `APP_VERSION` and as a suffix, we include the build number. We want to upload this API version by indicating the commit ID, so the `API_ZIP_KEY` will have this information. The `APP_VERSION_DESCRIPTION` will be the description of the deployed version in Elastic Beanstalk. Finally, we are going to update the buildspec file with the actual Elastic Beanstalk deployment steps. `yaml phases: ... build: on-failure: ABORT commands: # ... # ZIP the API - zip -r -j dist/apps/api.zip dist/apps/api # Upload the API bundle to S3 - aws s3 cp dist/apps/api.zip s3://$APIVERSION_BUCKET/$ENVIRONMENT_TARGET/$API_ZIP_KEY # Create new API version in Elastic Beanstalk - aws elasticbeanstalk create-application-version --application-name "$ELASTICBEANSTALK_APPLICATION_NAME" --version-label "$API_VERSION" --description "$APP_VERSION_DESCRIPTION" --source-bundle "S3Bucket=$API_VERSION_BUCKET,S3Key=$ENVIRONMENT_TARGET/$API_ZIP_KEY" # Deploy new API version - aws elasticbeanstalk update-environment --application-name "$ELASTICBEANSTALK_APPLICATION_NAME" --version-label "$API_VERSION" --environment-name "$ELASTIC_BEANSTALK_ENVIRONMENT_NAME" # Wait until the Elastic Beanstalk environment is stable - aws elasticbeanstalk wait environment-updated --application-name "$ELASTICBEANSTALK_APPLICATION_NAME" --environment-name "$ELASTIC_BEANSTALK_ENVIRONMENT_NAME" ` Let's make a change in the API, for example, the message sent back by the /api/hello` endpoint and push up the changes. --- Now every time a change is merged to the main` branch, it gets pushed to our production deployment. Using these guides, you can set up multiple environments, and you can configure separate CodePipeline instances to deploy from different branches. I hope this guide proved to be helpful to you....

Bun v1.0 cover image

Bun v1.0

On September 8, 2023, Bun version 1 was released as the first production-ready version of Bun, a fast, all-in-one toolkit for running, building, testing, and debugging JavaScript and TypeScript. Why a new JS runtime You may ask, we already have Node and Deno, so why would we need another javascript runtime, Well yes we had Node for a very long time, but developers face a lot of problems with it, and maybe the first problem is because it’s there for a very long time, it has been changing a lot between different versions and one of the biggest nightmares for JavaScript developers these days is upgrading the node version. Also, Node lacks support for Typescriptt. Zig programming language One of the main reasons that Bun is faster than Node, is the programming language it has been built with which is Zig. Zig is a very fast programming language, even faster than C) (here is some benchmarks), it focuses on performance and memory control. The reasons it’s faster than C is because of the LLVM optimizations it has, and also the way it handles the undefined behavior under the hood Developer Experience Bun delivers a better developer experience than Node on many levels. First, it’s almost fully compatible with Node so you can use Node packages without any issues. Also, you don’t need to worry about JS Common and ES Modules anymore, you can use both in the same file, yup you read that right, for example: `js import { useState } from 'react'; const React = require('react'); ` Also, it has a built-in test framework similar to Jest or Vitest in the project so no need to install a different test framework with different bundler in the same project like Webpack or Vite `js import { describe, expect, test, beforeAll } from "bun:test"; ` Also, it supports JSX out-of-the-box `bash bun index.tsx ` Also, Bun has the fastest javascript package manager and the most efficient you can find as of the time of this post `bash bun install ` Bun Native APIs Bun supports the Node APIs but also they have fun and easy APIs to work with like `Bun.serve()` : to create HTTP server `Bun.file()` : to read and write the file system `Bun. password.hash()`: to hash passwords `Bun.build()`: to bundle files for the browser `Bun.FileSystemRouter()`: a file system router And many more features Plugin system Bun also has an amazing plugin system that allows developers to create their own plugins and add them to the Bun ecosystem. `js import { plugin, type BunPlugin } from "bun"; const myPlugin: BunPlugin = { name: "Custom loader", setup(build) { // implementation }, }; ` Conclusion Bun is a very promising project, and it’s still in the early stages, but it has a lot of potential to be the next big thing in the JavaScript world. It’s fast, easy to use, and has a lot of amazing features. I’m very excited to see what the future holds for Bun and I’m sure it will be a very successful project....

Layouts & Theming in Vuetify 3 cover image

Layouts & Theming in Vuetify 3

Introduction Do you want to avoid tinkering with CSS to get your website looking just right? Branding is everything in today's digital landscape. With Vuetify 3's customizable theming options, you can create web projects that perfectly reflect your unique branding, and visual identity. Additionally, you can reduce the duplicated code by creating layouts representing your application's different page structures. In a previous article introducing Vuetify 3 with Vue 3, we created an application that allowed us to add, display, and delete jokes. ** If you'd like to follow along with this article, please clone the GitHub repository. `shell git clone https://github.com/thisdot/blog-demos.git or `git@github.com:thisdot/blog-demos.git` for ssh then cd into the project directory cd layouts-and-theming-in-vueityf ` In this article, we'll go over how you can create layouts in Vuetify 3 to allow you to reuse the same layout for pages that share the same structure. We will also go over how you can customize the look and feel of your application to match your brand's visual identity through the powerful theming tools that Vuetify 3 offers us. Layouts in Vuetify 3 What are layouts, and how are they useful? In web development, layouts are akin to blueprints for the structure of your web pages. They provide a consistent and reusable frame for the different pages of an application. A well-designed layout can improve the user experience by providing familiarity and predictability as the user navigates through other parts of your application. Layouts are particularly helpful in reducing code duplication. Instead of defining the same structure for each page—headers, footers, and navigation menus, you define them once in a layout, and then apply that layout to any page that uses the same structure. This speeds up development, and makes your code easier to maintain. Using Layouts in Vuetify 3 Creating a layout in Vuetify 3 is as simple as creating a new Vue component. This component will include the common elements shared across multiple pages like headers, footers, and navigation bars. Here is an example of a basic layout: `html ... ... ... ` This layout has a header, a navigation drawer, and a footer. The ` component is where the content of the specific pages will be injected. Building a layout for our application Let's create a layout for our application. We'll have a top navigation bar and a footer. Inside the layouts` directory, create a new file named `Default.vue` and add the following code: `html Joke Machine &copy; 2023 Joke Machine ` Additionally, in order for us to use our layout, we will need to modify our router/index.ts file to use the Default.vue component: `js const routes = [ { //... component: () => import('@/layouts/Default.vue'), //... } ` This will make sure that our respective pages use the Default.vue` layout that we created. The contents of the pages will appear in place of `` in the layout. It is also worth noting that you can create, and nest as many layouts as you want. Theming in Vuetify 3 Themes allow you to customize your application's default colors, surfaces, and more. If your brand has specific colors and styling, you can theme your Vuetify application to resemble your brand through theming better. Additionally, Vuetify 3 allows you to modify your theme in real-time programmatically. [Vuetify 3] also comes with light and dark themes pre-installed. Theming API Vuetify 3 offers us 2 main APIs for working with themes: - useTheme` is a composable that allows us to get information about the current theme and will enable us to modify the existing theme. - v-theme-provider` is used in the `` section of your Vue files to modify the theme of all of its children. Updating the theme of our application Updating the theme of our application is straightforward with Vuetify 3. Let's customize our application's primary and secondary colors. In the vuetify.ts file, modify the themes section to contain the following styles: `ts import { createVuetify } from 'vuetify' import 'vuetify/styles' const vuetify = createVuetify({ theme: { themes: { light: { background: '#FFFFFF', surface: '#F2F5F8', primary: '#6200EE', secondary: '#03DAC6', error: '#B00020', info: '#2196F3', success: '#4CAF50', warning: '#FB8C00', }, }, }, }) ` In this example, we're defining a custom 'light' theme. If you want to use a dark theme, or any other named theme, you can add those as additional properties within the themes` object. For example: `ts themes: { light: { / ... */ }, dark: { / ... */ }, } ` And... That's it! By changing the various config options in the vuetify.ts` file, you can modify how your application looks and feels to match your brand. If you'd like to learn more about themes and all the options you can provide, please check out the official Vuetify documentation. Conclusion In this article, we've gone through the concepts of layouts and theming in Vuetify 3. We've seen how layouts can reduce code duplication, and provide consistency across your application. We've looked at how Vuetify's theming features allow you to customize your application to match your brand's visual identity. Understanding and utilizing these features effectively can significantly enhance the development experience and the end user's interaction with your application. Remember, a well-structured and visually appealing application not only attracts users, but also retains them. Happy coding!...

Nuxt DevTools v1.0: Redefining the Developer Experience Beyond Conventional Tools cover image

Nuxt DevTools v1.0: Redefining the Developer Experience Beyond Conventional Tools

In the ever-evolving world of web development, Nuxt.js has taken a monumental leap with the launch of Nuxt DevTools v1.0. More than just a set of tools, it's a game-changer—a faithful companion for developers. This groundbreaking release, available for all Nuxt projects and being defaulted from Nuxt v3.8 onwards, marks the beginning of a new era in developer tools. It's designed to simplify our development journey, offering unparalleled transparency, performance, and ease of use. Join me as we explore how Nuxt DevTools v1.0 is set to revolutionize our workflow, making development faster and more efficient than ever. What makes Nuxt DevTools so unique? Alright, let's start delving into the features that make this tool so amazing and unique. There are a lot, so buckle up! In-App DevTools The first thing that caught my attention is that breaking away from traditional browser extensions, Nuxt DevTools v1.0 is seamlessly integrated within your Nuxt app. This ensures universal compatibility across browsers and devices, offering a more stable and consistent development experience. This setup also means the tools are readily available in the app, making your work more efficient. It's a smart move from the usual browser extensions, making it a notable highlight. To use it you just need to press Shift + Option + D` (macOS) or `Shift + Alt + D` (Windows): With simple keystrokes, the Nuxt DevTools v1.0 springs to life directly within your app, ready for action. This integration eliminates the need to toggle between windows or panels, keeping your workflow streamlined and focused. The tools are not only easily accessible but also intelligently designed to enhance your productivity. Pages, Components, and Componsables View The Pages, Components, and Composables View in Nuxt DevTools v1.0 are a clear roadmap for your app. They help you understand how your app is built by simply showing its structure. It's like having a map that makes sense of your app's layout, making the complex parts of your code easier to understand. This is really helpful for new developers learning about the app and experienced developers working on big projects. Pages View lists all your app's pages, making it easier to move around and see how your site is structured. What's impressive is the live update capability. As you explore the DevTools, you can see the changes happening in real-time, giving you instant feedback on your app's behavior. Components View is like a detailed map of all the parts (components) your app uses, showing you how they connect and depend on each other. This helps you keep everything organized, especially in big projects. You can inspect components, change layouts, see their references, and filter them. By showcasing all the auto-imported composables, Nuxt DevTools provides a clear overview of the composables in use, including their source files. This feature brings much-needed clarity to managing composables within large projects. You can also see short descriptions and documentation links in some of them. Together, these features give you a clear picture of your app's layout and workings, simplifying navigation and management. Modules and Static Assets Management This aspect of the DevTools revolutionizes module management. It displays all registered modules, documentation, and repository links, making it easy to discover and install new modules from the community! This makes managing and expanding your app's capabilities more straightforward than ever. On the other hand, handling static assets like images and videos becomes a breeze. The tool allows you to preview and integrate these assets effortlessly within the DevTools environment. These features significantly enhance the ease and efficiency of managing your app's dynamic and static elements. The Runtime Config and Payload Editor The Runtime Config and Payload Editor in Nuxt DevTools make working with your app's settings and data straightforward. The Runtime Config lets you play with different configuration settings in real time, like adjusting settings on the fly and seeing the effects immediately. This is great for fine-tuning your app without guesswork. The Payload Editor is all about managing the data your app handles, especially data passed from server to client. It's like having a direct view and control over the data your app uses and displays. This tool is handy for seeing how changes in data impact your app, making it easier to understand and debug data-related issues. Open Graph Preview The Open Graph Preview in Nuxt DevTools is a feature I find incredibly handy and a real time-saver. It lets you see how your app will appear when shared on social media platforms. This tool is crucial for SEO and social media presence, as it previews the Open Graph tags (like images and descriptions) used when your app is shared. No more deploying first to check if everything looks right – you can now tweak and get instant feedback within the DevTools. This feature not only streamlines the process of optimizing for social media but also ensures your app makes the best possible first impression online. Timeline The Timeline feature in Nuxt DevTools is another standout tool. It lets you track when and how each part of your app (like composables) is called. This is different from typical performance tools because it focuses on the high-level aspects of your app, like navigation events and composable calls, giving you a more practical view of your app's operation. It's particularly useful for understanding the sequence and impact of events and actions in your app, making it easier to spot issues and optimize performance. This timeline view brings a new level of clarity to monitoring your app's behavior in real-time. Production Build Analyzer The Production Build Analyzer feature in Nuxt DevTools v1.0 is like a health check for your app. It looks at your app's final build and shows you how to make it better and faster. Think of it as a doctor for your app, pointing out areas that need improvement and helping you optimize performance. API Playground The API Playground in Nuxt DevTools v1.0 is like a sandbox where you can play and experiment with your app's APIs. It's a space where you can easily test and try out different things without affecting your main app. This makes it a great tool for trying out new ideas or checking how changes might work. Some other cool features Another amazing aspect of Nuxt DevTools is the embedded full-featured VS Code. It's like having your favorite code editor inside the DevTools, with all its powerful features and extensions. It's incredibly convenient for making quick edits or tweaks to your code. Then there's the Component Inspector. Think of it as your code's detective tool. It lets you easily pinpoint and understand which parts of your code are behind specific elements on your page. This makes identifying and editing components a breeze. And remember customization! Nuxt DevTools lets you tweak its UI to suit your style. This means you can set up the tools just how you like them, making your development environment more comfortable and tailored to your preferences. Conclusion In summary, Nuxt DevTools v1.0 marks a revolutionary step in web development, offering a comprehensive suite of features that elevate the entire development process. Features like live updates, easy navigation, and a user-friendly interface enrich the development experience. Each tool within Nuxt DevTools v1.0 is thoughtfully designed to simplify and enhance how developers build and manage their applications. In essence, Nuxt DevTools v1.0 is more than just a toolkit; it's a transformative companion for developers seeking to build high-quality web applications more efficiently and effectively. It represents the future of web development tools, setting new standards in developer experience and productivity....