Categories
Vue

Add a Dialog Box to a Vue App with the vue-js-modal Library

The Vue.js modal library is a popular and useful modal library for Vue apps.

In this article, we’ll look at how to add a modal with the vue-js-modal library.

Dialogs

Dialogs are a simplified version of the modal which has most parameters set by default.

It’s useful for quick prototyping and showing alerts.

We can set the dialog to true when we call Vue.use to show the dialog.

For example, we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import VModal from "vue-js-modal";
Vue.use(VModal, {
  dialog: true
});

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <div>
    <v-dialog/>
  </div>
</template>
<script>
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show("dialog", {
        title: "Dialog title",
        text: "Lorem ipsum dolor sit amet.",
        buttons: [
          {
            title: "Cancel",
            handler: () => {
              this.$modal.hide("dialog");
            }
          },
          {
            title: "Like",
            handler: () => {
              alert("Like action");
            }
          },
          {
            title: "OK",
            handler: () => {
              alert("success");
            }
          }
        ]
      });
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We register the plugin with an object with the dialog property to true .

Then in the show method, we add the this.$modal.show method to show the dialog.

The first argument has the name of the dialog.

The object in the 2nd argument has various options we can set as the dialog.

The title has the dialog title.

The text has the text.

The buttons property has an array with the button options.

They are defined by objects. title has the button text.

handler has the event handler that’s run when clicking the button.

this.$modal.hide lets us hide the modal. We reference the dialog to close we reference the name of the dialog.

Events

The modal emits various events. To listen to them, we can write:

<template>
  <modal name="example" @before-open="beforeOpen" @before-close="beforeClose">
    <span>Hello, {{ name }}!</span>
  </modal>
</template>
<script>
export default {
  name: "Example",
  data() {
    return {
      name: "world"
    };
  },
  methods: {
    beforeOpen(event) {
      console.log("Opening...");
    },
    beforeClose(event) {
      console.log("Closing...");
      if (Math.random() < 0.5) {
        event.cancel();
      }
    }
  },
  mounted() {
    this.$modal.show("example");
  }
};
</script>

We listen to the before-open and before-close events emitted from the modal component.

before-open is emitted when the modal is opening.

before-close is emitted when the modal is closing.

The event parameter is an object with the cancel method that we can use to cancel the action.

Since we call event.cancel in the beforeClose method, it’ll cancel the close modal close action.

Slots

The modal component has a slot that we can populate with our own content.

For example, we can write:

<template>
  <modal name="example">
    <div slot="top-right">
      <button @click="$modal.hide('example')">❌</button>
    </div>Hello, ☀️!
  </modal>
</template>
<script>
export default {
  name: "App",
  mounted() {
    this.$modal.show("example");
  }
};
</script>

The top-right slot adds content to the top right of the modal.

The default slot has the main modal content.

Conclusion

We can add dialog boxes easily and customize its content with the vue-js-modal library.

Categories
Vue

Add a Modal to a Vue App with the vue-js-modal Library

The Vue.js modal library is a popular and useful modal library for Vue apps.

In this article, we’ll look at how to add a modal with the vue-js-modal library.

Installation

We can install the library by running:

npm i vue-js-modal

or

yarn add vue-js-modal

Add a Modal

Once we install the modal, then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import VModal from "vue-js-modal";
Vue.use(VModal);

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <modal name="hello-world-modal">hello world modal</modal>
</template>

<script>
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show("hello-world-modal");
    },
    hide() {
      this.$modal.hide("hello-world-modal");
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We add the modal component with the name prop so that we can assign the name to it.

This way, we can show and hide the modal.

Also, we can create dynamic modals by call the this.$modal.show method with a component.

For example, we can write:

components/ModalContent.vue

<template>
  <div>{{text}}</div>
</template>

<script>
export default {
  name: "ModalContent",
  props: {
    text: String
  }
};
</script>

App.vue

<template>
  <div></div>
</template>

<script>
import ModalContent from "./components/ModalContent.vue";
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show(
        ModalContent,
        { text: "hello world" },
        { draggable: true }
      );
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We call the show method with the component as the first argument.

The 2nd argument is an object with the props.

The last argument has the options for the modal.

The draggable property makes the modal draggable if it’s true .

We can also pass in a component that’s defined inline instead of importing it:

<template>
  <div></div>
</template>
<script>
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show(
        {
          template: `
            <div>
              <p>{{ text }}</p>
            </div>
          `,
          props: ["text"]
        },
        { text: "hello world" },
        { draggable: true },
        { "before-close": event => console.log("before close") }
      );
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We added a 4th argument to listen to the before-close event emitted by the modal before it’s closed.

Also, we can set the options globally when we register the plugin.

For example, we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import VModal from "vue-js-modal";
Vue.use(VModal, {
  dynamicDefaults: {
    draggable: true,
    resizable: true,
    height: "auto"
  }
});

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <div></div>
</template>
<script>
export default {
  name: "App",
  methods: {
    show() {
      this.$modal.show(
        {
          template: `
            <div>
              <p>{{ text }}</p>
            </div>
          `,
          props: ["text"]
        },
        { text: "hello world" }
      );
    }
  },
  mounted() {
    this.show();
  }
};
</script>

We make all the modals added with the draggable and resizable properties added when we call Vue.use .

Conclusion

The vue-js-modal library lets us add modals easily into our Vue app.

Categories
Vue

Add a Circular Progress Display with vue2-circle-progress

The add a circular spinner easily into a Vue app, we can use the vue-circle-progress library.

In this article, we’ll look at how to use it to add the spinner.

Installation

We can install the package by running:

npm i vue2-circle-progress

Usage

After installing the package, we can use it by writing:

<template>
  <div id="app">
    <vue-circle
      :progress="50"
      :size="100"
      :reverse="false"
      line-cap="round"
      :fill="fill"
      empty-fill="rgba(0, 0, 0, .1)"
      :animation-start-value="0.0"
      :start-angle="0"
      insert-mode="append"
      :thickness="5"
      :show-percent="true"
      @vue-circle-progress="progress"
      @vue-circle-end="progressEnd"
    >
      <p>Slot!</p>
    </vue-circle>
  </div>
</template>

<script>
import VueCircle from "vue2-circle-progress";
export default {
  components: {
    VueCircle
  },
  data() {
    return {
      fill: { gradient: ["red", "green", "blue"] }
    };
  },
  methods: {
    progress(event, progress, stepValue) {
      console.log(stepValue);
    },
    progressEnd(event) {
      console.log("Circle progress end");
    }
  }
};
</script>

The progress prop sets the progress to display at the end.

size is the diameter of the circular progress display.

reverse makes animation run counterclockwise.

line-cap sets the line cap.

fill has the fill color.

fill can also be a single color, we can set replace the gradient property with the color property.

And it can also be replaced with the image property.

So we can write:

{ color: "green" }

or

{ image: "https://picsum.photos/id/23/200/300" }

to add an image.

empty-fill has the fill color for an empty bar.

animation-start-value has the starting progress value.

start-angle is the starting angle of the circular progress spinner.

insert-mode specifies how the spinner is appended to the DOM.

thickness is the thickness of the line in pixels.

It also emits several events. The vue-circle-progress event is emitted when the circular progress spinner is loading.

vue-circle-end is emitted when the circle finishes loading.

The progress method has the stepValue parameter to get the progress value that’s being displayed.

The default slot has the content inside the circle.

Methods

It also comes with a few methods.

The updateProgress method updates the component progress value and animate the changes.

For example, we can write:

<template>
  <div id="app">
    <vue-circle
      :progress="50"
      :size="100"
      :reverse="false"
      line-cap="round"
      :fill="fill"
      empty-fill="rgba(0, 0, 0, .1)"
      :animation-start-value="0.0"
      :start-angle="0"
      insert-mode="append"
      :thickness="5"
      :show-percent="true"
      @vue-circle-progress="progress"
      @vue-circle-end="progressEnd"
      ref="circleProgress"
    >
      <p>Slot!</p>
    </vue-circle>
    <button @click="updateProgress">update progress</button>
  </div>
</template>

<script>
import VueCircle from "vue2-circle-progress";
export default {
  components: {
    VueCircle
  },
  data() {
    return {
      fill: { gradient: ["red", "green", "blue"] }
    };
  },
  methods: {
    progress(event, progress, stepValue) {
      console.log(stepValue);
    },
    progressEnd(event) {
      console.log("Circle progress end");
    },
    updateProgress() {
      this.$refs.circleProgress.updateProgress(21);
    }
  }
};
</script>

to add an update progress button to change the progress percentage.

We call updateProgress by assigning the component a ref and call it from the ref.

Conclusion

We can add a circular progress display with the vue-circular-progress library.

Categories
Vue

Create a Simple Vue.js Registration Form

Registrations forms are a part of many web apps.

We can create one easily.

In this article, we’ll look at how to create a registration form with Vue and Express.

Back End

We can create a simple login form that takes some data in the back end.

To do that, we create an Express app by installing some packages:

npm i express cors body-parser

Then we can use them by writing:

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors')
const app = express();
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/register', (req, res) => {
  res.json(req.body);
});

app.listen(3000, () => console.log('server started'));

The cors package lets us do cross-domain communication.

We used it with app.use(cors()) .

bodyParser parses the JSON request body that we’ll submit from the front end.

bodyParser.json() lets us parse JSON.

We also have a register route to get the request data.

req.body has the parsed JSON data.

If we need logic for checking for data, we can add them.

Register Form Front End

After we added the back end for accepting the registration data, we can add the registration form with Vue.js.

To do that, we can write:

<template>
  <div id="app">
    <form @submit.prevent="login">
      <div>
        <label for="username">username</label>
        <input name="username" v-model="username" placeholder="username">
      </div>
      <div>
        <label for="password">password</label>
        <input name="password" v-model="password" placeholder="password" type="password">
      </div>
      <div>
        <label for="firstName">first name</label>
        <input name="firstName" v-model="firstName" placeholder="first name">
      </div>
      <div>
        <label for="lastName">last name</label>
        <input name="lastName" v-model="lastName" placeholder="last name">
      </div>
      <div>
        <label for="age">age</label>
        <input name="age" v-model="age" placeholder="age" type="number">
      </div>
      <div>
        <label for="address">address</label>
        <input name="address" v-model="address" placeholder="address">
      </div>
      <input type="submit" value="register">
    </form>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      username: "",
      password: "",
      firstName: "",
      lastName: "",
      age: "",
      address: ""
    };
  },
  methods: {
    async login() {
      const { username, password, firstName, lastName, age, address } = this;
      const res = await fetch(
        "https://SomberHandsomePhysics--five-nine.repl.co/register",
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({
            username,
            password,
            firstName,
            lastName,
            age,
            address
          })
        }
      );
      const data = await res.json();
      console.log(data);
    }
  }
};
</script>

We added a registration form with the form element.

The submit.prevent listen runs the login method on submit and runs preventDefault at the same time.

The form fields are created by the label and input tags.

for has the name attribute value of the input field.

v-model binds to the values that we submit.

We also set the type attribute of some inputs.

password is for password inputs.

number is for number inputs.

The login method calls fetch to make a POST request to the back end.

We get all the reactive properties we want to submit in the first line.

Then we put them all in the JSON string.

headers must have the Content-Type set to application/json to submit the JSON.

Then we get back the response from the register route once the request is made.

Conclusion

We can create a registration form with Vue.js with the v-model directive and the fetch function to make requests.

Categories
Vue

Create a Simple Vue.js Login Form — an Example

Login forms are a part of most web apps.

We can create one easily.

In this article, we’ll look at how to create a login form with Vue and Express.

Back End

We can create a simple login form that takes some data in the back end.

To do that, we create an Express app by installing some packages:

npm i express cors body-parser

Then we can use them by writing:

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors')
const app = express();
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/login', (req, res) => {
  res.json(req.body);
});

app.listen(3000, () => console.log('server started'));

The cors package lets us do cross-domain communication.

We used it with app.use(cors()) .

bodyParser parses the JSON request body that we’ll submit from the front end.

bodyParser.json() lets us parse JSON.

We also have a login route to get the request data.

req.body has the parsed JSON data.

We should add logic for user validation when we create a production app.

Login Form Front End

We add the login form in our Vue app.

To do that, we can write:

<template>
  <div id="app">
    <form @submit.prevent="login">
      <input v-model="username" placeholder="username">
      <input v-model="password" placeholder="password" type="password">
      <input type="submit" value="log in">
    </form>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      username: "",
      password: ""
    };
  },
  methods: {
    async login() {
      const { username, password } = this;
      const res = await fetch(
        "https://SomberHandsomePhysics--five-nine.repl.co/login",
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({ username, password })
        }
      );
      const data = await res.json();
      console.log(data);
    }
  }
};
</script>

We created the login form in the template.

v-model binds the data to the reactive properties we initialized in the data method.

The input with type submit will trigger the submit event.

We listen to the submit event with submit.prevent to call preventDefault automatically.

This way, we can submit our login credentials with JavaScript.

Then in the login method, we called fetch to make a request to the login route we created.

The method property has the request method.

headers has the request headers. We need to set Content-Type to application/json so that we can submit JSON.

The body has the requests body.

Then we get back the response with res.json() .

When we type in something and click ‘log in’, we should get a response logged.

Conclusion

We can create a simple login form with Vue and Express easily.