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.