link959 link960 link961 link962 link963 link964 link965 link966 link967 link968 link969 link970 link971 link972 link973 link974 link975 link976 link977 link978 link979 link980 link981 link982 link983 link984 link985 link986 link987 link988 link989 link990 link991 link992 link993 link994 link995 link996 link997 link998 link999 link1000 link1001 link1002 link1003 link1004 link1005 link1006 link1007 link1008 link1009 link1010 link1011 link1012 link1013 link1014 link1015 link1016 link1017 link1018 link1019 link1020 link1021 link1022 link1023 link1024 link1025 link1026 link1027 link1028 link1029 link1030 link1031 link1032 link1033 link1034 link1035 link1036 link1037 link1038 link1039 link1040 link1041 link1042 link1043 link1044 link1045 link1046 link1047 link1048 link1049 link1050 link1051 link1052 link1053 link1054 link1055 link1056 link1057 link1058 link1059 link1060 link1061 link1062 link1063 link1064 link1065 link1066 link1067 link1068 link1069 link1070 link1071 link1072 link1073 link1074 link1075 link1076 link1077 link1078 link1079 link1080 link1081 link1082 link1083 link1084 link1085 link1086 link1087 link1088 link1089 link1090 link1091 link1092 link1093 link1094 link1095

[Vue.js] watch not update change vue

i’m try to change variable by watch and change it in to html

<p>{customer.creditsLeft}</p>

and vue

data() {
customer: {},
}
watch: {
‘$store.state.jobs.listBooking.customer’: function (newVal) {
this.customer.creditsLeft = newVal;
console.log(‘current credit now’ + this.customer.creditsLeft);
return this.customer.creditsLeft;
}
},

console.log is woking but creditsLeft still not change. i’m a new bie in vue.js . pls help me

Solution :

If you want to add new property to customer object you need to use set, otherwise it’s not reactive.

this.$set(this.customer, ‘creditsLeft’, newVal)

https://vuejs.org/v2/guide/reactivity.html

Or you can set it before hand so you don’t need to use set

data() {
customer: {
creditsLeft: 0
},
}

[Vue.js] Passing props values to component

there is this component: InputField.vue

<template>
<div class=”w-full”>
<label class=”sr-only” :for=”name”></label>
<input
:placeholder=”label”
:name=”name”
class=”border-b border-black w-full appearance-none w-full py-4 px-3 text-grey-darker leading-tight”
/>
</div>
</template>
<script>
export default {
props: {
label: {
type: String,
required: true,
default: ‘label’, /* <——— Always prints default */
},
name: {
type: String,
required: true,
default: ‘name’, /* <——— Always prints default */
},
},
data() {
return {}
},
}
</script>

And this is how i’m using it from another component:

<inputField :label=”Hola” :name=”nombre” />

But label and name are allways the default values defined in the component declaration,

Any idea what i’m missing?

Solution :

I’m going to capitalize on the snippet done by Utlime but there a lot of problems in that answer, in fact you must NOT take out the “:” as it is the thing that binds it as props and actually will let multiple instances of the component to have their “own” props states, just call it like :aProp=”‘something’” if you are using hard coded values, if you’re passing a variable then go with :aProp=’variable’
The correct example would be:

Vue.component(‘InputField’, {
template: `
<div class=”w-full”>
<label class=”sr-only” :for=”name”></label>
<input
:placeholder=”label”
:name=”name”
class=”border-b border-black w-full appearance-none w-full py-4 px-3 text-grey-darker leading-tight”
/>
</div>
`,

props: {
label: {
type: String,
required: true,
default: ‘label’, /* <——— No longer prints default if props are given */
},
name: {
type: String,
required: true,
default: ‘name’,
},
},
});

new Vue({
el: ‘#app’,
})
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”app”>
<input-field :label=”‘Hola’” :name=”‘nombre’”></input-field>
<input-field :label=”‘Que tal Toni’” :name=”‘toni’”></input-field>
</div>

Solution 2:

You need to remove :

<inputField label=”Hola” name=”nombre” />

Passing Static or Dynamic Props

Vue.component(‘InputField’, {
template: `
<div class=”w-full”>
<label class=”sr-only” :for=”name”></label>
<input
:placeholder=”label”
:name=”name”
class=”border-b border-black w-full appearance-none w-full py-4 px-3 text-grey-darker leading-tight”
/>
</div>
`,

props: {
label: {
type: String,
required: true,
default: ‘label’, /* <——— Always prints default */
},
name: {
type: String,
required: true,
default: ‘name’, /* <——— Always prints default */
},
},
});

new Vue({
el: ‘#app’,
})
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”app”>
<input-field label=”Hola” name=”nombre” /></input-field>
</div>

[Vue.js] Type-checking of Vue w/ Typescript but w/o Webpack/ts-loader

Since August 2018 it’s possible to compile Typescript code with Babel and have type checking as a separate process.

I wonder if it is possible to do type checking of custom file formats like .vue.js with <script lang=”ts”> sections w/o Webpack/ts-loader? (I reckon in that case Typescript would need to support file preprocessing in order to be able to digest different file formats).

Right now there is to maintain a separate webpack configuration with ts-loader and compile Vue.js project, though all I need is to type-check it. So this approach looks more like a hack and overhead.

Solution :

It is perfectly fine to use ts-loader with Webpack. Our Vue.js is extremely large-scale and we have multipage SPA with Webpack as our bundler. You don’t really need to have a separate configuration for ts-loader. Have a look at our Webpack config (three instances of ts-loader):

const rules = [
{
test: /\.tsx?$/,
loader: ‘ts-loader’,
include: […PATHS.shared, path.join(__dirname, ‘node_modules’)],
options: {
transpileOnly: isDev,
appendTsSuffixTo: [/\.vue$/],
instance: ‘common’,
configFile: path.join(__dirname, ‘tsconfig.json’)
}
},
{
test: /\.tsx?$/,
loader: ‘ts-loader’,
include: [PATHS.app1],
options: {
transpileOnly: isDev,
appendTsSuffixTo: [/\.vue$/],
instance: ‘app1’,
configFile: path.join(PATHS.app1, ‘tsconfig.json’)
}
},
{
test: /\.tsx?$/,
loader: ‘ts-loader’,
include: [PATHS.app2],
options: {
transpileOnly: isDev,
appendTsSuffixTo: [/\.vue$/],
instance: ‘app2’,
configFile: path.join(PATHS.app2, ‘tsconfig.json’)
}
}
];

Coming back to the question, there is had success with @babel/preset-typescript but we do not use .vue.js files as there are problems when processing .vue.js files. Note: We set transpileOnly to false during development.

If you can switch to using class syntax with @Component decorator and use vue-template-loader, then you can switch to using Babel + TypeScript. There are little nasty surprises like no support for const enums, namespaces, etc.

Note: Using ts-loader over @babel/preset-typescript has its own advantages. Coupled with Webpack, ts-loader is more hackable. If you need typed JSX i.e. TSX support with Vue.js, then babel route makes more sense. If you are using .vue.js files, then there is no considerable difference.

[Vue.js] How to handle errors with Laravel and Vue.js

when just starting to develop an application with Laravel and Vue.js

Currently there is it setup so that Laravel acts like a backend API, while Vue.js renders all of the front-end views. All working well and when getting the hang of working with a SPA.

One thing when struggling with. When I was using only Laravel, I was getting the Whoops error handling screen if the were any exceptions being generated on the PHP’s end. However since switching over to a SPA, I no longer see the exceptions being thrown (I feel like it something to do with Laravel running on the server, but vue.js in the browser, clarification would be amazing though…).

I tried searching the internet for ways to make this happen, most suggested using something like Clockwork or Debugbar. However I don’t know if that actually fits the requirements I want.

Whoops was beneficial that it let me see the source of the issue, so I could investigation further, and for someone still learning this was great.

Are there any standard processes that are typically adopted to get the above result? Or is there something when missing, and as a result when going about it the wrong way (perhaps there is a reason the exceptions don’t get thrown the same way).

Any advice would be really appreciated.

Solution :

You can use the “network tab” within the browsers developer tools (available in chrome (CTRL + SHIFT + I), firefox, edge etc.) and investigate the detailed response of the request. It is not as pretty as the actual Woops screen (since it heavily relies on JS and nice css formatting) but it usually meets the requirement of being able to track down the actual source of the issue.

Example of chrome dev tool network tab

[Vue.js] Mutate object to use in MDbootstrap Vue

when using MDBootstrap for vue.js js, the way to use datatable is to to use prop :data=”data” which I calling here tableData and there is columns ready but I need to mutate the rows inside my object,

I couldn’t do that with rows:this.data or rows:data which is where I handle getting data from my server.

How can I handle this and mutate rows inside tableData ?

<template>
<div class=”container-fluid”>
<ProgressSpinner v-if=”isLoading”/>

<mdb-datatable :data=”tableData” striped bordered/>
</div>
</template>
<script>
import ProgressSpinner from ‘./Preloader’
import DataTable from ‘vue-materialize-datatable’
import { mdbDatatable } from ‘mdbvue’

export default {
name: ‘Companies’,
data: () => ({
data: [],
tableData: {
columns: [
{ label: ‘ID’, field: ‘id’, sort: ‘asc’ },
{ label: ‘Name’, field: ‘name’ },
{ label: ‘Phone’, field: ‘phone’, sort: ‘asc’ },
{ label: ‘Email’, field: ‘email’, sort: ‘asc’ },
{ label: ‘City’, field: ‘city’, sort: ‘asc’ },
{ label: ‘Join Date’, field: ‘joined_at’ }
],
rows: []
},
}),
created() {
this.$store
.dispatch(‘allCompanies’)
.then(() => {
this.data = this.$store.getters.getAllCompanies
})
.catch(() => {
this.customerErrors = this.$store.getters.customerError
})
},
computed: {
isLoading() {
return this.$store.getters.customersAreLoading
},
},
components: {
ProgressSpinner,
datatable: DataTable,
mdbDatatable
},
mounted() {
$(‘.container-fluid’).bootstrapMaterialDesign()
}
}
</script>

Solution :

You should assign the value to tableData.rows when available.

this.$store
.dispatch(‘allCompanies’)
.then(() => {
this.tableData.rows = this.$store.getters.getAllCompanies
})

[Vue.js] Vuex Child component wait for parent component dispatch action

Parent component (Dashboard):

<template>
<div id=”dashboard”>
<Header />
<b-container>
<div>
<b-row>
<b-col>
<Overview />
</b-col>
</b-row>
</div>
</b-container>
</div>
</template>

<script>
import Header from ‘@/components/common/Header’;
import Overview from ‘@/components/dashboard/Overview’;
import { mapGetters } from ‘vuex’;

export default {
name: ‘dashboard’,
components: {
Header,
Overview
},
mounted() {
const sessionId = this.$cookie.get(‘connect.sid’);
this.$store.dispatch(‘user/getUser’, sessionId).then((userData) => {
this.$store.dispatch(‘project/getProject’, userData.data.user);
});
},
computed: {
…mapGetters(‘user’, {
user: ‘getUser’
})
}
}
</script>

Child component (Overview):

<template>
<div class=”overview”>
<div class=”overview__title”>
<h1>
Welcome {user.cn[0]} // Works
</h1>
</div>
<div class=”overview__project”>
<p v-for=”project in runningprojects” :key=”project._id”>
{project.name} // Does not work at refresh
</p>
</div>
</div>
</template>

<script>
import {mapGetters} from ‘vuex’;
export default {
name: ‘dashboard-overview’,
data() {
return {
runningprojects: []
}
},
computed: {
…mapGetters(‘user’, {
user: ‘getUser’
}),
…mapGetters(‘project’, {
projects: ‘getProjects’,
allProjects: ‘getAllProjects’
})
},
mounted() {
console.log(“mounted this.projects”, this.projects);
// add something from this.projects to this.runningprojects
},
methods: {
calcReq() {

},

}
</script>

In my Dashboard component (parent) I fetch the user data with a vuex action dispatch(‘user/getUser) and after that I fetch the projects of this user dispatch(‘project/getProject).

In my Overview component (child) to show the project information of this user. I call my mapGetters and there is a component variable runningprojects inside data(). In my mounted() lifecycle to push data from my getters to this data array.

The following problem is given:

When I refresh my application, the console.log from my child component mounted() is called before the dispatch jobs are finished in the parent component (dashboard).

It only works if change something in my local files and vue-cli does a live reload.

Solution :

Because of the page lifecycle of the vue.js app. when component renders mounted is called after created and it wont wait for the ajax or any async calls.

One solution would be to not render the child component until the async return

<template>
<div id=”dashboard”>
<Header />
<b-container>
<div>
<b-row>
<b-col>
<Overview v-if=”finished”/>
</b-col>
</b-row>
</div>
</b-container>
</div>
</template>

<script>
import Header from ‘@/components/common/Header’;
import Overview from ‘@/components/dashboard/Overview’;
import { mapGetters } from ‘vuex’;

export default {
name: ‘dashboard’,
data() {
return {
finished: false,
}
},
components: {
Header,
Overview
},
mounted() {
const sessionId = this.$cookie.get(‘connect.sid’);
this.$store.dispatch(‘user/getUser’, sessionId).then((userData) => {
this.$store.dispatch(‘project/getProject’, userData.data.user);
this.finished = true;
});
},
computed: {
…mapGetters(‘user’, {
user: ‘getUser’
})
}
}
</script>

Just add a v-if in the child component and when dispatch has return then set the value to true which will render the child component and the then the mounted will have the values you want

Other solution would be.

Use updated function instead of mounted and which will be called when ever there is a change in the state.

[Vue.js] Popover not closing when clicking outside its focus area

I’m using Bootstrap vue.js with Vue.js and am experiencing a problem where I’m iterating over some items and displaying them to the user.

The issue is, when a user clicks on one of the popovers, every popover that was opened gets closed (as I desire), but when the user clicks outside the focus area of the targeted (opened) popover, it doesn’t close anymore.

It looks like the opening animation runs every time the user clicks on the targeted popover.

Here is the code:

<template>
<div>
<div class=”row” v-for=”(n, i) in 5” :key=”n”>
<div :id=”‘popover’ + visitor.id + ‘-‘ + i” @click=”$root.$emit(‘bv::hide::popover’)”>
<div class=”card”>
<b-popover :target=”‘popover’ + visitor.id + ‘-‘ + i”>
<template slot=”title”>
Edit image
<button
class=”close-popover”
@click=”$root.$emit(‘bv::hide::popover’, ‘popover’ + visitor.id + ‘-‘ + i)”
\>X</button>
</template>
</b-popover>
</div>
</div>
</div>
</div>
</template>

Any help is appreciated!

Solution :

Add this Jquery to the code and it will work, probably.

$(‘body’).on(‘click’, function (e) {
$(‘[target=popover]‘).each(function () {
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $(‘.popover’).has(e.target).length === 0) {
$(this).popover(‘hide’);
}
});
});

Also you can try this:

You can add this to the code and try.

<a class=”close” href=”#”>Close</a>

Also add this jquery:

$(‘.close’).click(function() {
$(“.class”).fadeOut(300);
});

Solution 2:

A possible solution is the vue.js directive v-click-outside.

Basically, you just install it: npm install –save v-click-outside

And use:

<template>
<div v-click-outside=”onClickOutside”></div>
</template>

[Vue.js] Is there any way to modify vue-good-table pagination style?

vue.js-good-table allows pagination like following:

But I need pagination like below image:

Is there any way to have that pagination style using vue-good-table?

Solution :

It would seem no. These are the available types.

https://xaksis.github.io/vue-good-table/guide/configuration/pagination-options.html#mode

Or you can edit the source code.

https://github.com/xaksis/vue-good-table/blob/master/src/components/VgtPagination.vue.js

[Vue.js] VueJS are multiple Single file components each a vue instance or nested objects?

In VueJS, are multiple Single file components (as parent-child), each a vue.js instance nested inside root instance? Why I’ve this assumption, is because each component can have the same properties i.e. data, methods, template, life-cycle hooks (mounted, created etc) akin to a root vue.js instance or say like a vue.js instance in a non SFC setup.

To me it appears, any web-pack + vue-loader Single File Components setup are nested objects exported as JS objects and imported in parent component i.e. child is nested inside parent component which is nested inside a single root vue.js instance.

Basically, simply put there is only a single root instance and SFC are nested objects. As Sarah Drasner writes in the below linked css-tricks article:

You can have more than one instance in an application. Typically, we’ll have one instance and several components, as the instance is the main app. src

Can anybuddy shed more light on this as to which assertion is correct i.e SFC are each vue.js instances or they are nested objects inside a single root vue.js instance. If the latter turns out to be the correct case, why each can have lifecycle hooks akin to the root vue.js instance.

Technically, how does vue.js make SFC act like separate vue.js instances but still be nested objects inside a single root instance?

Thanks

Solution :

First of all, there is no difference between “single file components” and “global components” when it comes to their properties and lifecycle hooks. They only differ in how they are packaged, how they are referenced by other components and and how/where their HTML template is stored.

Secondly, all components, including the “root component” are vue.js instances. If you look at the source code, you’ll see that the root instance is identified by the absence of any parents like this:

const isRoot = !vm.$parent

Have a look at this component tree from a vue.js app using vue.js devtools:

Here is what the console shows:

\> var root = $vm0
\> var app = $vm0.$children[0]
\> var link = $vm0.$children[0].$children[0]

// How they are named in vue.js dev tools
\> link.$options._componentTag
< “router-link”
\> app.$options.__file
< “src/App.vue”

// How the root instance is identified
\> !root.$parent
< true
\> !app.$parent
< false
\> !link.$parent
< false

// Constructors
// Each component has its own class (or prototype), but they all extend the vue.js base class
\> Object.getPrototypeOf(root) === Object.getPrototypeOf(Object.getPrototypeOf(app))
< true
\> Object.getPrototypeOf(root) === Object.getPrototypeOf(Object.getPrototypeOf(link))
< true

Therefore, components are both vue.js instances and nested objects inside a single root vue.js instance.

[Vue.js] Watch two mutually related variables on Vue

there is two variables, for example, priceInUSD and priceInRub and rate USD/Ruble.

data: () => ({
priceInUSD: 0,
priceInRub: 0,
rate: 65.395402,
});

When user changing one variable, the second should be recalcualted. But If when using watch() for both, it causing of redundant calculation calling and potentially infinity loop. One recalculating second, second calling watch for first, first calling watch for second, and at infinity.

When when using computed and getters/setters…

computed: {
priceInUSD: {
get(){
return this.statePriceInUSD;
},

set(newValue){
this.statePriceInUSD = newValue;
this.statePriceInRub = newValue * this.rate;
}
},

priceInRub: {
get(){
return this.statePriceInRub;
},

set(newValue){
this.statePriceInRub = newValue;
this.statePriceInUSD = +newValue / this.rate;
}
},
}

… it too causing redundant recalculating of other variable.

Changing price in USD
Recalculating price in rubles (ok)
Firing again recalculating price in USD (not ok)

It is possible recalculate two mutually related variables, without redunant recalculating first variable?

Solution :

This solutions works (you probably screwed up with variables):

new Vue({
el: “#app”,
data: {
statePriceInUSD:0,
statePriceInRub: 0,
rate: 65.395402,
},
computed: {
priceInUSD: {
get(){
return this.statePriceInUSD;
},

set(newValue){
console.log(‘USD new value: ‘ + newValue);
this.statePriceInUSD = newValue;
this.statePriceInRub = newValue * this.rate;
}
},

priceInRub: {
get(){
return this.statePriceInRub;
},

set(newValue){
console.log(‘RUB new value: ‘ + newValue);
this.statePriceInRub = newValue;
this.statePriceInUSD = +newValue / this.rate;
}
},
}
})

Working example is here https://jsfiddle.net/a4ped21h/