Solving Common Vue Problems — List Filtering, Global Libraries, Vuex, and More
Tags: vue, webdev, programming, javascript
Published: 2021-01-26 01:17:51

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


Vue.js makes developing front end apps easy. However, there are still chances that we’ll run into problems.

In this article, we’ll look at some common issues and see how to solve them.

### Filtering Lists in Vue Components

The proper way to filter lists is to use a computed property.

This is because computed properties return a value before `v-for` is run.

For instance, we can write:

```
computed: {
  filteredItems() {
    return this.items.filter(item => item.type.toLowerCase().includes(this.search.toLowerCase()))
  }
}
```

We put our filtering logic in the `filterItems` computed properties.

Then we can loop through the computed properties by writing:

```
<div v-for="item of filteredItems" >
  <p>{{item.name}}</p>
</div>
```

We just pass in the `filteredItems` computed property as a variable into our template.

### Making HTTP Calls in Vue Components

We can make HTTP calls in Vue components with the Fetch API or a 3rd party HTTP client library like Axios.

For example, we can write:

```
methods: {
  async getData(){
    const res = await fetch('/some/url')
    const data = await res.json();
    this.data = data;
  }
}
```

`fetch` returns a promise so we can use `async` and `await` with it.

### Remove the Hash from a URL

We can remove hashes from URLs generated by Vue Router by using history mode.

To enable it, we can write:

```
const router = new VueRouter({
  mode: 'history'
})
```

We set the `mode` to `'history'` so that we can remove the hash.

### Listening to Props Changes

We can listen to props changes by using the watchers.

To add a watcher for a prop, we can add a method to the `watch` property.

For instance, we can write:

```
{
  ...
  `props: ['myProp'],
  watch: {
    myProp(newVal, oldVal) {
      console.log(newVal, oldVal)
    }
  }
  ...
`}
```

We have the `watch` property and the `myProp` prop as indicated by the `props` property’s value.

We just make a method with the same name as the prop with a signature that takes the new and old values respectively.

Then we get the `newVal` value to get the new value, and the `oldVal` value to get the old value.

To start watching immediately when the prop value is set, we can add the `immediate` property and set it to `true` .

For example, we can write:

```
watch: {
  myProp: {
    immediate: true,
    handler (val, oldVal) {
      // ...
    }
  }
}
```

### Communication Across Any Components

We can communicate between any components with the `this.$dispatch` method to dispatch an event that’s propagated to all components.

Then we can use `this.$on` to listen to the event that’s dispatched by `this.$dispatch` .

For example, we can write the following in one component:

```
export default {
  ...
  `created() {
    this.$dispatch('child-created', this)
  }
  ...
}`
```

Then in another component, we can write:

```
export default {
  ...
  `created() {
    this.$on('child-created', (child) => {
      console.log(child)
    })
  }
  ...
}`
```

We emit the event in the `created` hook so the event is emitted when the component is created but DOM content isn’t loaded yet.

In the 2nd component, we add the event listener in the `created` hook so that we can listen to events as soon as the component code is loaded.

`child-created` is the event name.

The `child` parameter has the event data in the 2nd argument of `$dispatch` .

### Using Axios Globally in a Vue App

To make Axios available globally, we can set it as the property of `Vue.prototype` before we create the `Vue` instance.

This way, it’ll be returned with the `Vue` instance if we create the `Vue` instance.

For example, we can write:

```
import Axios from 'axios'

Vue.prototype.$http = Axios;
```

Then in our components, we can access it by using the `this.$http` variable.

For instance, if we want to make a get request, we can write:

```
this.$http.get('https://example.com')
```

### Vuex Action vs Mutations

Vuex mutations are synchronous code that takes a name and a handler.

It’s used to update a state.

For instance, we can write:

```
import Vuex from 'vuex'

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

Then `state.count++` updates the `count` state when we dispatch the `'increment'` action.

An action is like a mutation, but it can dispatch multiple mutations.

It can also be async.

For example, we can write:

```
incrementBy({ dispatch }, amount) {
  dispatch('INCREMENT', amount)
}
```

The `dispatch` function is a function to dispatch mutations.

### Conclusion

There are differences between Vuex actions and mutations.

To filter items, we should do them in computed properties.

We can put things in `Vue.prototype` to make them available globally.