Vue.js Quickset

Rafa Rafael
4 min readFeb 24, 2020

This was part of my last note but then as time goes by I encountered more bottlenecks so I decided to put them in a different note to easily find the solutions.

Prevent request overhead

Never put a vuex store dispatch or requests in created or mounted method when a component is used inside a loop method. Why? of course it will always send a request to the server in every loop so for example if it will loop a 100x it will also send an equivalent request.

Vue component not rendering when used in laravel blade template

Example you have a blade view and lazy load a vue component like this.

resources/views/user/profile.blade.php

@section('content)
<vue-profile-component :user="{{ $user }} />
@section

resources/assets/js/app.js

Vue.component(
'vue-profile-component',
require('./components/UserProfile.vue)
);

But when you go to that endpoint it shows nothing. The workaround is so simple. Add default when instantiating the require method.

Vue.component(
'vue-profile-component',
require('./components/UserProfile.vue).default
);

[Vue warn]: Cannot find element: #app

Solution #1

Add an id=”app” in your div element.

app/resources/views/home.blade.php

@section('content')
<div class="card-body" id="app">
<vue-component :user="{{ auth()->user() }}" />
</div>
@section

Solution #2

Add defer keyword to the script tag to the compiled app.js in the main app layout view.

app/resources/views/layouts/app.blade.php

<script src="{{ asset('js/app.js') }}" defer></script>

CSS not working

You are sure that the style exists in your css or sass/less file. But then it is not applied in the element in your component. If this happens you needed to transfer or recreate the style inside of your component.

<style scoped>
/** Some styles here */
</style>

Modify child CSS property

Let say you have a parent component that has a child component then you want to modify the color of the h1 tag text in your child your component from the parent component.

Child Component
<template>
<div class="text-color">
<h1>Hello Vue!</h1>
</div>
</template>
<script></script>
Parent Component
<template>
<div>
<child-component />
</div>
</template>
<script></script>
<style scoped>
/deep/ .text-color {
color: #000 !important
}
</style>

Passing an Array as prop to a Vue.js component inside in blade template.

When you try like below, the array will be converted as String

<vue-user-component users="{{ userArray }}" />

To Fix it you should use v-bind or like below to properly assign the value as prop.

<vue-user-component :users="{{ userArray }}" />

Passing an collection as prop to a Vue.js component inside in blade template.

When you try like below the collection data is udefinedin the component

<vue-user-component :users="{{ users }}" />

To Fix it you should encode your data into json object toproperly assign the value as prop.

<vue-user-component :users="{!! users !!}" />

[Vue warn]: You may have an infinite update loop in a component render function.

I encounter this error when I used a method to display a title on a dropdown. This can be avoided if you are going to use computed but I am also assigning a value to an object container to be use as prop on the child component, so to remove this warning, I put conditional statement to update only the value of role object when the user id is equal to the selected user value;

<template>
<select v-model="selectedUser">
<option v-for="user in users" :key="user.id" :value="user.id">
{{ optionTitle(user) }}
</option>
</select>
</template>
----------------------------------------------data() {
return {
role: '',
selectedUser: '',
}
},
methods: {
optionTitle: function(user) {
if (this.selectedUser != user.id) {
this.role = user.role;
}
return `${user.role.name} - ${user.full_name}`
}
},

Vue Filters

Creating your custom filters

Example: Omitting post body

// app.js or main.js or your own filters fileVue.filter('ommit', value => {
if (!value || typeof(val) != 'string') {
return '';
}
return `value.slice(0,50) ${...}`;
});

Then you can use it like this post.body | ommit

Example: Simple Search

Assuming you have a list of users and want to only show the users that you want when you search.

//YourComponent
<template>
<input type="text" v-model="keyword" />
<ul>
<li v-for="user in filterUsers>user.name</li>
</ul>
</template>
<script>
props: ['users'],
data() {
return {
keyword: '',
}
},
computed: {
filterUsers() {
return this.users.filter(user => {
return user.title.match(this.keyword);
});
}
}

Having weird problems in the live server

In my machine it works fine, in the staging sometime it works some not, and in the live server it isn’t.

Error

Let say you have a user object and have a role child object and button to show specifically for the user role ex. admin and a guest user. And then when you deploy or update the live server the button for admin only is showing to the guest user.

Fix

Always validate the parent object first if it is not undefined

<button v-if="user && user.role === 'Admin'">Add</button><a href="/signup" v-else>Signup</a>

Error

I have multiple vue components inside on a blade template and only one of them are showing.

Fix

Instead of instantiating your vue components like this

<my-component-one />
<my-component-two />
<my-component-three />

Do it like this

<my-component-one></my-component-one>
<my-component-two></my-component-two />
<my-component-three></my-component-three />

Problem

When I want to get the real time value from an input with model binding, the update is delayed. e.g. When I press 1, it shows undefined and when I press 2 which supposedly displays 12, that’s the time it shows the 1 value.

Fix

Instead of using @keydown use @keyup to get the value from the input.

<input v-model="myInput" @keyup="methodToProcessInputValue" />

More To Come…

--

--

Rafa Rafael

Dad / Husband / Full Stack Developer / Lifelong Learner