Common Vue Problems — Bootstrap, Vuex Route Restrictions, and More
Tags: vue, webdev, programming, javascript
Published: 2021-01-26 01:18:41

**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.

### Using Bootstrap in our App

If we only want to use the CSS from Bootstrap, then we can add the plain Bootstrap package and load the SASS files from it.

To load SASS files, we can use the `sass-loader` and `node-sass` .

To install them, we run:

```
npm install sass-loader node-sass --save-dev
```

Then we add the path to load the SASS files in the Webpack config file:

```
...
sassLoader: {
  includePaths: [
    path.resolve(projectRoot, 'node_modules/bootstrap/scss/'),
  ],
},
...
```

Now we can import the Bootstrap SASS file in our components:

```
<style lang="scss">
  @import "bootstrap";
</style>
```

If we want to use the JavaScript components from Bootstrap, then we should use BootstrapVue instead.

### Using SASS Resource Loader

We can add the SASS preprocessor to our `vue.config.js` file by writing:

```
module.exports = {
  css: {
    loaderOptions: {
      sass: {
        data: `
          @import "@/scss/_variables.scss";
          @import "@/scss/_mixins.scss";
        `
      }
    }
  }
};
```

There’s no need for extra dependencies since they’re included with Vue CLI projects.

### Call Method in Another Component in Vue

We can’t call another component’s method directly if we aren’t calling a method from a child component in the parent.

Instead, we’ve to pass events around by adding a global Vue instance that we can use to emit and listen to events.

For instance, we can write:

```
window.Event = new Vue();
```

to create a `Vue` instance.

Then we can call `$emit` on it by writing:

```
Event.$emit('createImage', item, response)
```

in one component.

Then in the `mounted` hook on another component then we can write:

```
mounted() {
  Event.$on('createImage', (item, response) => {
    // ...
  }
}
```

We listen to the `createImage` event and get the arguments that are passed into `$emit` in the callback parameters.

### Adding Web Components in Vue Component

We can add web components in a Vue component directly.

For example, we can write:

```
<template id="app">
  <web-component>...</web-component>
</template>
```

Given that `web-component` is a web component, we can include it directly.

### The Limits of v-html

`v-html` can only be used to render plain HTML code.

We can’t render Vue components with it.

For instance, if we have a component:

```
Vue.component('component', {
  template: '<span>component</span>',
})
```

Then we can’t have code like:

```
new Vue({
  el: '#app',
  data(){
    return {
      comp: '<component></component>'
    }
  }
})

...
<div id="app">
  <span v-html="comp"></span>
</div>
```

This will not work because `component` is a component.

All data bindings and Vue components are ignored.

Instead, we have to render plain HTML:

```
new Vue({
  el: '#app',
  data(){
    return {
      comp: '<p>foo</p>'
    }
  }
})
...
<div id="app">
  <span v-html="comp"></span>
</div>
```

That will be rendered with `v-html` since we have a p element.

### Mount Multiple Vue Instances on Multiple Elements

If we want to attach multiple `Vue` instances on multiple elements, we can write:

```
const vues = document.querySelectorAll(".app");
[...vues].forEach((el, index) => new Vue({el, data: { message: `hello ${index}`}}))
```

We get all the elements with class `app` .

Then we use the spread operator on `vues` so we can use `forEach` on it,

In the callback, we can create new `Vue` instances.

### Regex in Vue Router Paths

We can use regex in Vue Router paths.

For instance, we can write:

```
{ path: 'item/:id(d+)', name: 'itemCard', component: ItemCard }
```

Then we specified that the `id` parameter must be digits.

### Custom Select Component that Binds to v-model

If we want to create custom select component that binds to `v-model` , then our component has to emit the `input` event and takes the `value` prop.

`v-model` is shorthand for both of those things together.

For instance:

```
<custom-select v-bind:value="val" v-on:input="val = $event.target.value"></custom-select>
```

can be rewritten as:

```
<custom-select v-model="val"></custom-select>
```

Then we can do anything in `custom-event` to emit the `input` event and take the `value` prop.

### Conclusion

`v-model` is short for emitting the `input` event and taking the `value` property.

We can add Bootstrap SASS files with the SASS loader package.

Vue Router routes can have regex to restrict the values of parameters.