Vuetify confirm dialog component with callback function

Learn how to create a reusable confirmation popup with the Vuetify dialog. In this tutorial, we will create a confirm popup component that triggers back the yes/no callback function passed by the component that used the popup component.

Install Vuetify via CLI

vue add vuetify

This will prompt you to choose a preset. Choose a “Vuetify 2 - Vue CLI (recommended)”. This will automatically set up the Vuetify for you, by creating a plugins/vuetify.js and adding it to main.js also there is an override change to the App.vue with some newly created files example HelloWorld.vue.

Create confirm popup dialog component

In the ./src/components/ConfirmPopup.vue

<template>
  <v-dialog v-model="dialog" max-width="290">
    <v-card>
      <v-card-title class="text-h5">
        {{ title }}
      </v-card-title>

      <v-card-text>
        {{ message }}
      </v-card-text>

      <v-card-actions>
        <v-spacer></v-spacer>

        <v-btn color="red darken-1" text @click="disagree">
          {{ options.btnDisagree }}
        </v-btn>

        <v-btn color="green darken-1" text @click="agree">
          {{ options.btnAgree }}
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
export default {
  name: "ConfirmPopup",
  data() {
    return {
      dialog: false,
      title: "",
      message: "",
      options: {
        btnDisagree: "Disagree",
        btnAgree: "Agree",
      },
      agreeCallback: null,
      disagreeCallback: null,
    };
  },
  methods: {
    open({
      title,
      message,
      options = {
        btnDisagree: "Disagree",
        btnAgree: "Agree",
      },
      agree = () => {},
      disagree = () => {},
    }) {
      this.dialog = true;
      this.title = title;
      this.message = message;
      this.options = options;
      this.agreeCallback = agree;
      this.disagreeCallback = disagree;
    },
    disagree() {
      this.dialog = false;
      this.disagreeCallback();
    },
    agree() {
      this.dialog = false;
      this.agreeCallback();
    },
  },
};
</script>

Setup the confirm component to the Vue app

Setup component to the main application and reference it with mounted.

In the ./src/App.vue

<template>
  <v-app>
    <v-app-bar app color="primary" dark>
      <div class="d-flex align-center">
        <v-img
          alt="Vuetify Logo"
          class="shrink mr-2"
          contain
          src="https://cdn.vuetifyjs.com/images/logos/vuetify-logo-dark.png"
          transition="scale-transition"
          width="40"
        />

        <v-img
          alt="Vuetify Name"
          class="shrink mt-1 hidden-sm-and-down"
          contain
          min-width="100"
          src="https://cdn.vuetifyjs.com/images/logos/vuetify-name-dark.png"
          width="100"
        />
      </div>

      <v-spacer></v-spacer>

      <v-btn
        href="https://github.com/vuetifyjs/vuetify/releases/latest"
        target="_blank"
        text
      >
        <span class="mr-2">Latest Release</span>
        <v-icon>mdi-open-in-new</v-icon>
      </v-btn>
    </v-app-bar>

    <v-main>
      <HelloWorld />
    </v-main>
    <confirm-popup ref="confirm" />
  </v-app>
</template>

<script>
import HelloWorld from "./components/HelloWorld";
import ConfirmPopup from "./components/ConfirmPopup";

export default {
  name: "App",
  components: {
    HelloWorld,
    ConfirmPopup,
  },
  data() {
    return {};
  },
  mounted() {
    this.$root.$confirm = this.$refs.confirm.open;
  },
};
</script>

Usage

The sample usage of the confirm popup dialog will be called the popup from the HelloWorld.vue component as a sample.

In the ./src/components/HelloWorld.vue

<template>
  <v-container>
    <button @click="confirm">Confirm</button>
    <button class="d-block" @click="confirmParams">
      Confirm callback with params
    </button>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  methods: {
    confirm() {
      this.$root.$confirm({
        title: "Confirm",
        message: "Confirm message",
        options: {
          btnDisagree: "No",
          btnAgree: "Yes",
        },
        agree: this.agree,
        disagree: this.disagree,
      });
    },
    agree() {
      console.log("agree!");
    },
    disagree() {
      console.log("disagree!");
    },
    confirmParams() {
      this.$root.$confirm({
        title: "Confirm",
        message: "Confirm message",
        options: {
          btnDisagree: "No",
          btnAgree: "Yes",
        },
        agree: () => this.agreeParams("passed 1", "passed 2"),
        disagree: () => {
          console.log("disagree callback");
        },
      });
    },
    agreeParams(param1, param2) {
      console.log(`param 1: ${param1}, param 2: ${param2}`);
    },
  },
};
</script>