Categories
JavaScript Vue

How to Deep Watch Data in a Vue App

There are a few ways to deep watch data in a Vue app.

We can add a deep watcher by writing:

watch: {
  item: {
     handler(val){
       // do stuff
     },
     deep: true
  }
}

The most import part is the deep property. We must set it to true to enable deep watch on an object property.

We can create a computed property to return a value based on one or more values.

For example, we can write:

new Vue({
  el: '#app',
  computed: {
    foo() {
      return this.item.foo;
    }
  },
  data: {
    item: {
      foo: 'foo'
    }
  }
})

The foo computed property is computed by using the value of this.item.foo.

We can reference the value as this.foo in our component code and write:

{{ foo }}

to reference it in the template.

We can also write:

watch:{
   'item.foo': function (newVal, oldVal){
       // ...
   },
   'item.bar': function(newVal, oldVal){
       // ...
   }
}

Then we watch the value of item.foo and item.bar in our code.

newVal has the new value and oldVal has the old value of each property.

We can watch data in a few ways with Vue apps.

If we just need a value that’s derived from one or more other values, then we use computed properties.

Otherwise, we can use deep watchers.

Categories
JavaScript Vue

Save Time From Creating Vue Filters with vue2-filters

To save us time from creating our own filters in our Vue app, we can use the vue-filters plugin.

It has filters for basic string formatting operations like capitalization, changing case, truncating strings, and more.

Also, it has filters for formatting numbers like percent, currency, and bytes.

There are also array manipulation filters.

To install it, we run:

npm install vue2-filters

Then we can register it in main.js as follows:

import Vue from "vue";
import App from "./App.vue";
import Vue2Filters from "vue2-filters";

Vue.use(Vue2Filters);
Vue.config.productionTip = false;

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

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

Then we can use the filters.

String Filters

We can use the capitalize filter by writing:

<template>
  <div id="app">{{ 'abc' | capitalize }}</div>
</template>

<script>
export default {
  name: "App"
};
</script>

Then abc is displayed as Abc.

Likewise, we can do the same for the other string filters.

The uppercase filter can be used by writing:

{{ msg | uppercase }}

The lowercase filter can be used the same way:

{{ msg | lowercase }}

The rest of the string filters follow the same pattern.

The truncate filter can be used to cut off text.

For instance, we can write:

<template>
  <div id="app">{{ msg | truncate(10) }}</div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      msg: "hello world, james"
    };
  }
};
</script>

Then we get hello worl... displayed.

The argument is for the number of characters to truncate to. The ‘…’ isn’t included in the count.

Number Filters

The number filters can be used to format numbers.

For instance, we can specify the number format with the number filrter.

We can write:

{{ 123456 | number('0,0') }} 

Then we use , as the decnimal separator.

So we get 123,456 displayed.

We can specify the number of decimal digits we display by changing the number of digits after the decimal separator.

For instance, we can write:

{{ 12345.67 | number('0.0000') }} 

Then we get 12345.6700 displayed.

We can also add a plus or minus sign to the format string:

{{ 123456 | number('+0') }}
{{ 123456 | number('-0') }}

Then we get +123456 and -123456 respectively.

We can display K for thousand and M for million with the a formatting tag:

{{ 222222 | number('0 a') }}

Then we get 222 K displayed.

if we write:

{{ 222222222 | number('0a') }}

Then we get 222M displayed.

We can also change thousands separator. It can be changed to anything we want.

We can write:

{{ 1234567 | number('0,0', { thousandsSeparator: ' ' }) }}

Then we see 1 234 567 on the screen.

Also, we can change the decimal separator.

If we write:

{{ 12345.67 | number('0.00', { decimalSeparator: '|' }) }}

Then we get 12,345|67 on the screen.

Display Bytes

We can display numbers as the number of bytes.

For instance, we can write:

{{ 3000000 | bytes }}    

Then we get 2.86 MB on the screen.

We can change the number of decimal points by passing in an argument:

{{ 3000000 | bytes(3) }}   

We have 2.861 MB displayed.

Display Percentages

We can use the percent filter to display percentages.

If we have:

{{ 0.05 | percent }}

We have 5% displayed.

We can adjust the decimal point the same way.

If we write:

{{ 0.97574849 | percent(3) }}

We see 97.575%.

Also, we can change the multiplier:

{{ 0.97574849 | percent(3, 150) }}

And we get 146.362%. The filter multiplies 150 by 0.97574849 to get that value.

Currency

vue2-filters also comes with a filter to format currencies.

We can write:

{{ 123.45 | currency }} 

And we get $123.45.

The currency symbol can be changed. For instance, we can write:

{{ 123.45 | currency('£') }}

We get £123.45.

The number of decimal places can be changed.

We write:

{{123.45 | currency('£', 0)}}

to remove decimals. So we get £123.

Thousands separator can be changed with:

{{ amount | currency('$', 0, { thousandsSeparator: '.' }) }}

The decimal separator can be changed with:

{{ amount | currency('$', 2, { decimalSeparator: ',' }) }} 

We can move the currency symbol to the right with:

{{ amount | currency('$', 0, { symbolOnLeft: false }) }}

Pluralization

This package has the pluralize filter for adding singular or plural words.

For instance, we can write:

{{ count }} {{ count | pluralize('item') }} 

Then if count is 2, we get 2 items.

We can add our own words for singular and plural.

For instance, we can write:

{{ count }} {{ count | pluralize(['car', 'cars']) }} 

Then if count is 1, we get 1 car. If count is 2, we get 2 cars.

Ordinals

The ordinal filter formats the number into an ordinal number.

For instance:

{ 1 | ordinal }}

displays as st.

Limit Array Items to Display

There’s the limitBy filter to limit the number of array items to display.

For instance, we can write:

<div v-for="item in limitBy(items, 20)">{{ item }}</div>

to display the first 20 items.

If we write:

<div v-for="item in limitBy(items, 20, 5)">{{ item }}</div>

To display the 5th to 25th item, we pass in 5 as the 2nd argument, and 20 to display 20 items.

Filter Items

The filterBy filter lets us filter by values of property values.

For instance, we can write:

<div v-for="item in filterBy(items, 'james')">

to display the entries with the string 'james' in it.

If we want to filter by a value in a property, we can write:

<div v-for="user in filterBy(users, 'james', 'name')">

Then we only display items with the name property value that includes 'james'.

We can have multiple properties:

<div v-for="user in filterBy(users, 'james', 'firstName', 'lastName')">

Then the filter searches for strings with 'james' in the firstName and lastName fields.

The find filter is like filter but only displays the first item.

Conclusion

There are many filters in the vue2-filters package. It saves us lots of effort from formatting strings and numbers.

It also saves us from having to filter array entries ourselves.

Categories
JavaScript Vue

How to Scroll to the Bottom of the Page in a Vue App

We can use the vue-scrollto package to scroll down to the bottom of a page.

First, we install it by running:

npm install --save vue-scrollto

Next, we register it in main.js:

import Vue from "vue";
import App from "./App.vue";
const VueScrollTo = require("vue-scrollto");

Vue.use(VueScrollTo);
Vue.config.productionTip = false;

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

We called the Vue.use method to register it.

Then in App.vue, we write:

<template>
  <div id="app">
    <a href="#" v-scroll-to="`#num-${nums[nums.length - 1]}`">scroll to bottom</a>

    <div :id="`num-${n}`" v-for="n of nums" :key="n">{{n}}</div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      nums: Array(100)
        .fill()
        .map((_, i) => i)
    };
  }
};
</script>

In the code above, we created the nums array with the Array constructor, fill and map methods.

Then in the template, we have an a element that scrolls to the element at the bottom of the page with the v-scroll-to prop’s value.

We set its value to the ID of the div at the bottom of the page.

Then below it, we have 100 divs with the id prop that’s dynamically set to the ID num and the value of n.

Now, when we click on the a element, then it’ll scroll to the bottom of the page because the ID is set to the ID of the div at the bottom of the page.

Categories
JavaScript Vue

How to Add an Accordion to Our Vue App

We can use the vue-accordion to create a vertical accordion.

To use it we install it by running:

npm install vue-accordion

Next, we register the plugin in main.js:

import Vue from "vue";
import App from "./App.vue";
import { vueAccordion } from "vue-accordion";

Vue.component("vue-accordion", vueAccordion);
Vue.config.productionTip = false;

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

We called the Vue.component method to register the component.

Then we use it in our component by writing:

<template>
  <div id="app">
    <vue-accordion :items="items" :styles="styles"></vue-accordion>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      items: [
        {
          title: "First",
          text: "First",
          url: "http://placekitten.com/200/200",
          image: "http://placekitten.com/200/200"
        },
        {
          title: "Second",
          text: "Second",
          url: "#",
          image: "http://placekitten.com/200/200"
        }
      ],
      styles: {
        div: {
          height: "350px"
        }
      }
    };
  }
};
</script>

We have the items array with objects that have the title, text, url, and image properties.

They are all required.

title is rendered as the title, text is the body. url is the URL to go to. image is the URL of the image to display.

styles has the styles we want to apply to each accordion item.

In the template, we use the vue-accordion component, which is made available by registering it earlier.

Noe we should see images displayed.

When we hover over the image then we should see our text.

And when we click on the item, then the browser would go to the URL set as the value of the url property.

Categories
JavaScript Vue

Add a Datepicker to a Vue App

The vue-datepicker package lets us add a datepicker with ease.

To use it, first we have to install it by running:

npm i vuejs-datepicker

Then we can use it in our component by adding:

<template>
  <div id="app">
    <datepicker v-model="date"></datepicker>
    <p>{{date}}</p>
  </div>
</template>

<script>
import Datepicker from "vuejs-datepicker";

export default {
  name: "App",
  components: {
    Datepicker
  },
  data() {
    return {
      date: new Date()
    };
  }
};
</script>

We registered the component in the components property.

The data method returns an object with the date field which we use with v-model.

The datepicker component is used to show the date picker and let users pick a date.

We have the date displayed below the date picker.

We can set the language of the date picker with the language prop.

To use it, we write:

<template>
  <div id="app">
    <datepicker v-model="date" :language="fr"></datepicker>
    <p>{{date}}</p>
  </div>
</template>

<script>
import Datepicker from "vuejs-datepicker";
import { fr } from "vuejs-datepicker/dist/locale";

export default {
  name: "App",
  components: {
    Datepicker
  },
  data() {
    return {
      date: new Date(),
      fr
    };
  }
};
</script>

We import the locale object from the vuejs-datepicker package so we can set it as the value of the language prop.

Also, we can disable dates by setting the disable-dates prop.

For instance, we can write:

<template>
  <div id="app">
    <datepicker v-model="date" :disabled-dates="disabledDates"></datepicker>
    <p>{{date}}</p>
  </div>
</template>

<script>
import Datepicker from "vuejs-datepicker";

export default {
  name: "App",
  components: {
    Datepicker
  },
  data() {
    return {
      date: new Date(2020, 4, 1),
      disabledDates: {
        from: new Date()
      }
    };
  }
};
</script>

Then we disable dates from today and on.

We set the from property to disable a date from this date onwards.

The same object can have the to property to set the end range of the disabled dates.

We can also have a dates array property to disable individual dates.

In addition, we can have the days property to disable one or more dates of the week.

Also, we have daysOfMonth to disable dates by the days of the month.

And we can also have a customPredictor method that returns true to disable dates.

We can add a date formatted function to format our dates.

For instance, we can write:

<template>
  <div id="app">
    <datepicker v-model="date" :format="customFormatter"></datepicker>
    <p>{{date}}</p>
  </div>
</template>

<script>
import Datepicker from "vuejs-datepicker";

export default {
  name: "App",
  components: {
    Datepicker
  },
  data() {
    return {
      date: new Date(2020, 4, 1)
    };
  },
  methods: {
    customFormatter(date) {
      return date.toLocaleString();
    }
  }
};
</script>

We have a customFormatter method to return the locale date string instead of the regular one.

It’s set as the value of the format prop.

Then the selected date will be displayed as the formatted version.

The vuejs-datepicker package is a flexible date picker that’s also easy to use.

It supports locale changes and disabling date ranges so users can’t select them.

We can also format the date that’s selected.