Categories
JavaScript Vue

Basic Vuex Store Example

Vuex is one state management that’s made to work with Vue apps.

To use it, we install it by running:

npm i vuex

Then we can register the Vuex plugin and create a basic Vuex store with:

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

Vue.config.productionTip = false;

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

The store is created with the Vuex.Store constructor:"

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

The object we passed into the constructor has the state property with the count state inside it.

The initial value of count is 0.

The mutations property has methods that change the state.

We have the increment method which takes the state parameter.

It has the same content as the state property above it.

So we can run state.count++ to increment the value of the count state.

To make the store available to the rest of our app, we put store into the object we passed into the Vue constructor.

Then in a component, we can use the store as follows:

<template>
  <div id="app">
    <button @click="increment">Increment</button>
    <p>{{count}}</p>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    increment() {
      this.$store.commit("increment");
    }
  }
};
</script>

We have this.$store, which is the Vuex store. We have this object since we registered the Vuex plugin and put the store into the object we passed into the Vue constructor.

this.$store.state.count has the count state’s value.

And this.$store.commit lets us commit values to the store.

The 'increment' indicates that we call the increment method in the mutations property in the object we pass into the Vuex.Store constructor.

We also have an Increment button to call increment.

Now when we click the button, we’ll see the count value displayed below the button go up.

The commit method takes a 2nd argument, which is the payload.

So we can write:

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state, payload) {
      state.count += payload;
    }
  }
});

Vue.config.productionTip = false;

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

and write:

<template>
  <div id="app">
    <button @click="increment">Increment</button>
    <p>{{count}}</p>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    increment() {
      this.$store.commit("increment", 2);
    }
  }
};
</script>

to increment by 2 instead of 1 when we click.

We have:

this.$store.commit("increment", 2);

instead of:

this.$store.commit("increment");

and:

mutations: {
  increment(state, payload) {
   state.count += payload;
  }
}

instead of:

mutations: {
  increment(state,) {
    state.count ++;
  }
}

payload is the 2 we passed in.

A basic Vuex store can let us store an app-wide state easily.

We just have to commit mutations to set the state and get the state from the store via the $this.store.state property.

We can return the latest value in the computed property so we can use it.

Categories
JavaScript Vue

Add a Numeric Input to a Vue App with vue-numeric

We can add a numeric input to our Vue app with the vue-numeric package.

We can install it by running:

npm install vue-numeric --save

Then we can register the plugin by writing the following in main.js:

import Vue from "vue";
import App from "./App.vue";
import VueNumeric from "vue-numeric";

Vue.use(VueNumeric);

Vue.config.productionTip = false;

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

to register the VueNumeric plugin globally.

Then we can write:

<template>
  <div id="app">
    <vue-numeric currency="$" separator="," v-model="price"></vue-numeric>
    <p>{{price}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      price: 0
    };
  }
};
</script>

We have the vue-numeric component.

It takes the currency prop to prepend a currency symbol to the input.

separator adds the separator to our input when it’s displayed.

v-model binds the inputted value to the price state.

The currency symbol and the separator are only displayed in the input when we move away from the input.

The value that’s set to price is still what we typed in, except when we type in something that’s not a whole number.

By default, it doesn’t let us enter decimals.

We can add the :precision prop to let us enter decimals.

There’s also the minus prop to let us enter negative numbers.

Also, the placeholder prop lets us add placeholders.

The output data type can be changed with output-type.

The empty-value prop lets us set a default value for the state.

So we can write:

<template>
  <div id="app">
    <vue-numeric currency="$" separator="," v-bind:precision="2" v-model="price"></vue-numeric>
    <p>{{price}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      price: 0
    };
  }
};
</script>

to allow up to 2 decimals to be entered.

The entered value will be converted automatically to the specified format when we move our focus away from the input.

The vue-numeric package lets us add a currency input easily.

It can be adjusted to use a different thousands separator, the numver of decimal digits, and more.

Categories
JavaScript Vue

Display a Toast in a Vue App with vue-toastr

A toast is a popup notification that has a black background color and disappears after a set time.

To add them easily to our Vue app, we can use the vue-toastr package.

To install it, we run:

npm install vue-toastr

Then we can register the plugin by writing:

import Vue from "vue";
import App from "./App.vue";
import VueToastr from "vue-toastr";
Vue.use(VueToastr);

Vue.config.productionTip = false;

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

Then in our component, we can display a toast by writing:

<template>
  <div id="app"></div>
</template>

<script>
export default {
  mounted() {
    this.$toastr.s("Success", "Success Toast Title");
  }
};
</script>

Display Toast

We display the toast after it’s loaded.

s is for success.

The first argument is the message and the 2nd is the title.

There are also other methods we can display toasts with:

this.$toastr.e("error");
this.$toastr.w("warning");
this.$toastr.i("information");

e is for error, w is for wanting, and i is for information.

Remove Toast

We can remove a toast with the removeByName, Close, or removeByTypeMethods.

For instance, we can create a toast by writing:

const toast = this.$toastr.Add({
  name: "name", 
  msg: "Hi", 
  type: "error"
});

And then write:

this.$toastr.Close(toast);

to close it.

We can also remove it by the name:

this.$toastr.removeByName("name");

The name is the value of the name property we have in the object we passed into Add.

Also, we can remove by type:

this.$toastr.removeByType("error");

We remove all toast with type error.

Options

In addition to name, type and msg, we can also pass in title to set the title.

classNames set the class names for the toast so we can style it.

timeout sets the amount of time before it’s closed.

closeOnHover makes the toast close on hover.

clickClose makes the toast close on click.

It also takes a few event handlers, including onCreated, onClosed, and onClicked, onMouseOver, and onMouseOut.

progressbar lets us enable or disable the progress bar.

And progressBarValue lets us change the initial value of the progress bar.

Conclusion

We can use vue-toastr to create very customizable toasts in our Vue.js apps.

We can change styles, timeouts, open and close toasts in various ways, and much more.

Categories
JavaScript Vue

Creating Masked Input in a Vue App with v-mask

We can use the v-mask package to add masked inputs into our Vue component.

To install it, we run:

npm install v-mask

Then we can use it by registering the plugin in main.js:

import Vue from "vue";
import App from "./App.vue";
import VueMask from "v-mask";
Vue.use(VueMask);

Vue.config.productionTip = false;

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

We called Vue.use(VueMask); to register the plugin globally.

Then we can add a mask to a component by writing:

<template>
  <div id="app">
    <input type="text" v-mask="'###-###-####'" v-model="phone">
    <p>{{phone}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      phone: ""
    };
  }
};
</script>

The v-mask directive is available after we registered the plugin/

We pass in a string with the phone number mask.

Now the input can only take phone numbers.

Also, we have v-model to bind the inputted value into a state.

Now when we type in a phone number, we’ll see it reflect in the p element below.

We can also use it as a filter.

If we have:

<template>
  <div id="app">
    <p>{{phone | VMask('(###) ###-####')}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      phone: "1234567890"
    };
  }
};
</script>

Then the value of phone will be displayed as a phone number.

We just pass in the mask format into the VMask filter to display the string our way.

v-mask is an easy to use plugin to let us add input masks into a Vue app.

It can also be used as a filter.

Categories
JavaScript Vue

Create a Class Vue Compnent with vue-class-component

We can create a Vue component in a class-style component with the vue-class-component package.

To get started, we can use the Vue CLI to create a project with the ‘Manually select features’ option.

Then we select ‘TypeScript’.

Then we press ‘y’ to the question ‘Use class-style component syntax’.

If we want to be able to create class-style Vue.js components in an existing project, we can install the vue-class-component package by running:

npm install --save vue vue-class-component

Then we can create a class-style component by writing:

<template>
  <div>
    <button @click="decrement">-</button>
    {{ count }}
    <button @click="increment">+</button>
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class Counter extends Vue {
  count = 0

  increment() {
    this.count++
  }

  decrement() {
    this.count--
  }
}
</script>

We imported the Component decorator from vue-class-component package and used it to modified our class to turn it into a component.

Also, we created the Counter class that extends the Vue class.

Like with regular single-file components, we have to export the component code. In this case, we export a class instead of an object with the export keyword.

Then we can have members inside it, including the count state and the increment and decrement methods.

The template section is the same as regular single-file components.

We have the @click directive that calls methods, except the methods are in a class rather than an object.

The count is displayed in a template.

Class-style components is an alternative syntax for creating single-file components.

We can use the vue-class-component package to create class-style components.

The Component decorator and the Vue class lets us create the component class.

The members are accessible in templates as with regular single-file components.