Categories
Vue

vue-good-table — Options

Creating tables from scratch is a pain.

This is why there are many table plugins to let us add tables easily.

In this article, we’ll look at how to add tables to a Vue app with the vue-good-table plugin.

Changing Options

The vue-good-table plugin provides us with many options for customizing our tables.

One of them is the line number option. This lets us show the line number on each row.

To add this, we add the line-numbers prop:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows" line-numbers/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "1996-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2004-10-30" }
      ]
    };
  }
};
</script>

The row styles can be customized by adding a row-style-class prop to add a CSS class to each row.

For example, we can write:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows" :row-style-class="rowStyleClassFn"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "2011-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2011-10-30" }
      ]
    };
  },
  methods: {
    rowStyleClassFn(row) {
      return row.age > 18 ? "green" : "red";
    }
  }
};
</script>

<style>
.green {
  background-color: green;
}

.red {
  background-color: red;
}

td {
  color: white !important;
}
</style>

We set the rowStyleClassFn function as the row-style-class prop.

Then we can apply the styles we want according to the classes.

The rtl prop lets us enable the right to left layout for the table.

For example, we can write:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows" rtl/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "1996-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2004-10-30" }
      ]
    };
  }
};
</script>

We flip the columns once we added the rtl prop.

Conclusion

We can change our tables with various props with vue-good-table.

Categories
Vue

vue-good-table — Events

Creating tables from scratch is a pain.

This is why there are many table plugins to let us add tables easily.

In this article, we’ll look at how to add tables to a Vue app with the vue-good-table plugin.

Table Events

Tables created with the vue-good-table component emits various kinds of events.

We can listen to them to run what we want when they’re emitted.

One of them is the on-row-click event.

To listen to it, we can write:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows" @on-row-click="onRowClick"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "1996-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2004-10-30" }
      ]
    };
  },
  methods: {
    onRowClick(params) {
      console.log(params);
    }
  }
};
</script>

We listen to the on-row-click event with the onRowClick method.

The params parameter is an object with various properties.

It has the row , pageIndex , selected , and event properties.

row is an object with a row.

pageIndex has the index of the row.

selected is a boolean to indicate whether the table row is selected.

event has the MouseEvent object that’s created from clicking the row.

We can detect the double clicks on a row with the on-row-dblclick event.

For example, we can listen to it by writing:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows" @on-row-dblclick="onRowDoubleClick"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "1996-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2004-10-30" }
      ]
    };
  },
  methods: {
    onRowDoubleClick(params) {
      console.log(params);
    }
  }
};
</script>

params has the same properties as the one in onRowClick method.

We can detect cell clicks by listening to the on-cell-click event.

For instance, we can listen to it by writing:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows" @on-cell-click="onCellClick"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "1996-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2004-10-30" }
      ]
    };
  },
  methods: {
    onCellClick(params) {
      console.log(params);
    }
  }
};
</script>

The params object is slightly different from the ones in the other handler methods.

It has the row , column , rowIndex , and event properties.

row and event are the same as the other params objects.

column is the column that’s clicked.

rowIndex has the index of the row that’s clicked.

Conclusion

We can listen to various events triggered on the table with the vue-good-table plugin.

Categories
Vue

Add Tables in a Vue App with the vue-good-table Plugin

Creating tables from scratch is a pain.

This is why there are many table plugins to let us add tables easily.

In this article, we’ll look at how to add tables to a Vue app with the vue-good-table plugin.

Getting Started

We can get started by installing the package.

To do this, we run:

npm install --save vue-good-table

Then we can add the plugin to main.js by writing:

import Vue from "vue";
import App from "./App.vue";
import VueGoodTablePlugin from "vue-good-table";
import "vue-good-table/dist/vue-good-table.css";

Vue.use(VueGoodTablePlugin);

Vue.config.productionTip = false;

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

to add the styles and the plugin.

We can also import it into our component with:

import 'vue-good-table/dist/vue-good-table.css'
import { VueGoodTable } from 'vue-good-table';

//...
components: {
  VueGoodTable,
}

Now we can add a simple table by writing:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "1996-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2004-10-30" }
      ]
    };
  }
};
</script>

We add the column definitions with the columns pro[.

label is the heading that’s displayed.

field is the [property name of the field to display.

dateInputFormat is the format of the date in the table row objects.

And dateOutputFormat is the date output format that’s displayed.

The rows prop has an array of objects which are displayed as rows.

Table Options

We can change many options with vue-good-table.

One of them is the max height.

This can be changed with the max-height prop:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows" max-height="300px"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "1996-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2004-10-30" }
      ]
    };
  }
};
</script>

We can keep the header fixed with the fixed-header prop:

<template>
  <div>
    <vue-good-table :columns="columns" :rows="rows" fixed-header/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          label: "Name",
          field: "name"
        },
        {
          label: "Age",
          field: "age",
          type: "number"
        },
        {
          label: "Birthday",
          field: "birthDay",
          type: "date",
          dateInputFormat: "yyyy-MM-dd",
          dateOutputFormat: "MMM do yy"
        }
      ],
      rows: [
        { id: 1, name: "John", age: 20, birthDay: "2000-01-20" },
        { id: 2, name: "Jane", age: 24, birthDay: "2011-10-31" },
        { id: 3, name: "Susan", age: 16, birthDay: "2011-10-30" }
      ]
    };
  }
};
</script>

Conclusion

We can add tables easily into a Vue app with the vue-good-table plugin.

Categories
Nuxt.js

Nuxt.js — Vuex

Nuxt.js is an app framework that’s based on Vue.js.

We can use it to create server-side rendered apps and static sites.

In this article, we’ll look at how to use Vuex with Nuxt.

Activate the Store

Vuex is built into Nuxt.

We can just import it and add the store option to the root Vue instance.

To add the store, we can write:

store/index.js

export const state = () => ({
  counter: 0
})

export const mutations = {
  increment(state) {
    state.counter++
  }
}

We created a root module for our Vuex store since the code is in the index.js file.

Then we can use it by writing:

page/counter.vue

<template>
  <div class="container">
    <button @click="increment">increment</button>
    <p>{{counter}}</p>
  </div>
</template>

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

We have access to the this.$store object.

The state property has the state.

And the commit method lets us run a mutation.

To create a namespaced module, we can change the name of the store file.

For example, we can create a store/counter.js file and write:

export const state = () => ({
  count: 0
})

export const mutations = {
  increment(state) {
    state.count++
  }
}

Then we can access the counter module by writing:

<template>
  <div class="container">
    <button @click="increment">increment</button>
    <p>{{count}}</p>
  </div>
</template>

<script>
import { mapMutations } from "vuex";

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

We add the namespace to access the state and commit our actions.

Also, we can use the map methods from Vuex to map the getters, mutations, and actions to properties in our component.

For example, we can write:

<template>
  <div class="container">
    <button @click="increment">increment</button>
    <p>{{count}}</p>
  </div>
</template>

<script>
import { mapMutations } from "vuex";

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

to map our counter/increment mutation to the increment method with the mapMutations method.

Plugins

We can add Vuex plugins to our Vuex store.

For example, we can add the Vuex logger to our app by writing:

store/index.js

import createLogger from 'vuex/dist/logger'

export const plugins = [createLogger()]

export const state = () => ({
  count: 0
})

export const mutations = {
  increment(state) {
    state.count++
  }
}

We just export the plugins array to add our plugins.

The nuxtServerInit Action

The nuxtServerInit action is defined in the store.

This runs in any environment.

To use it, we can add it to our store by writing:

store/index.js

export const actions = {
  nuxtServerInit({ commit }, { req }) {
    commit('core/load', { foo: 'bar' })
  }
}

store/core.js

export const state = () => ({
  obj: {}
})

export const mutations = {
  load(state, payload) {
    state.obj = payload;
  }
}

foo.vue

<template>
  <div class="container">{{obj}}</div>
</template>

<script>
export default {
  computed: {
    obj() {
      return this.$store.state.core.obj;
    },
  },
};
</script>

We have the nuxtServerInit action in the root module.

It has the commit function to let us commit mutations.

req is the request object.

Conclusion

We can add a Vuex store to an Nuxt app with a few changes.

Categories
Nuxt.js

Nuxt.js — Plugins and Modules

Nuxt.js is an app framework that’s based on Vue.js.

We can use it to create server-side rendered apps and static sites.

In this article, we’ll look at how to use plugins on client and server-side environments and create modules.

Client or Server-Side Plugins

We can configure plugins to be only available on client or server-side.

One way to do this is to add client.js to the file name to create a client-side only plugin.

And we can add server.js to the file name to create a server-side only plugin.

To do this, in nuxt.config.js , we can write:

export default {
  plugins: [
    '~/plugins/foo.client.js',
    '~/plugins/bar.server.js',
    '~/plugins/baz.js'
  ]
}

If there’s no suffix, then the plugin is available in all environments.

We can do the same thing with the object syntax.

For example, we can write:

export default {
  plugins: [
    { src: '~/plugins/both-sides.js' },
    { src: '~/plugins/client-only.js', mode: 'client' },
    { src: '~/plugins/server-only.js', mode: 'server' }
  ]
}

The mode property can be set to 'client' to make the plugin available on the client-side.

To make a plugin available on server-side, we can set the mode to 'server' .

For plugins that are only available on server-side, we can check if process.server is true in the plugin code before we run the code.

Also, we can check if process.static is true before we run the plugin code on static pages.

Nuxt.js Modules

Nuxt.js comes with a few modules that we can use to extend Nuxt’s core functionality.

@nuxt/http is used to make HTTP requests.

@nuxt/content is used to write content and fetch Markdown, JSON, YAML, and CSV files through a MongoDB like API.

@nuxtjs/axios is a module used for Axios integration to make HTTP requests.

@nuxtjs/pwa is used to create PWAs.

@nuxtjs/auth is used for adding authentication.

Write a Module

We can create our own modules.

To add one, we can create a file in the modules folder.

For example, we can create a modules/simple.js file and write:

export default function SimpleModule(moduleOptions) {
  // ...
}

Then we can add the module into nuxt.config.js so that we can use it:

modules: [
  ['~/modules/simple', { token: '123' }]
],

Then object in the 2nd entry is passed into the SimpleModule function as its argument.

Modules may be async.

Build-only Modules

We can create build-only modules and put them in the buildModules array in nuxt.config.js .

For example, we can write:

modules/async.js

import fse from 'fs-extra'

export default async function asyncModule() {
  const pages = await fse.readJson('./pages.json')
  console.log(pages);
}

We added the fs-extra module to read files.

The function is async, so it returns a promise with the resolved value being what we return.

In nuxt.config.js , we add:

buildModules: [
  '~/modules/async'
],

to add our module.

The module will be loaded when we run our dev server or at build time.

Conclusion

We can create modules and plugins that are available on the client or server-side with Nuxt.