link3014 link3015 link3016 link3017 link3018 link3019 link3020 link3021 link3022 link3023 link3024 link3025 link3026 link3027 link3028 link3029 link3030 link3031 link3032 link3033 link3034 link3035 link3036 link3037 link3038 link3039 link3040 link3041 link3042 link3043 link3044 link3045 link3046 link3047 link3048 link3049 link3050 link3051 link3052 link3053 link3054 link3055 link3056 link3057 link3058 link3059 link3060 link3061 link3062 link3063 link3064 link3065 link3066 link3067 link3068 link3069 link3070 link3071 link3072 link3073 link3074 link3075 link3076 link3077 link3078 link3079 link3080 link3081 link3082 link3083 link3084 link3085 link3086 link3087 link3088 link3089 link3090 link3091 link3092 link3093 link3094 link3095 link3096 link3097 link3098 link3099 link3100 link3101 link3102 link3103 link3104 link3105 link3106 link3107 link3108 link3109 link3110 link3111 link3112 link3113 link3114 link3115 link3116 link3117 link3118 link3119 link3120 link3121 link3122 link3123 link3124 link3125 link3126 link3127 link3128 link3129 link3130 link3131 link3132 link3133 link3134 link3135 link3136 link3137 link3138 link3139 link3140 link3141 link3142 link3143 link3144 link3145 link3146 link3147 link3148 link3149 link3150

[Vue.js] Vue watch unexpectedly called twice

udpate #2: It is not a bug, it was my own fault. I extended the BaseComponent by a extend() method as well as putting extends: BaseComponent into the options. I thought I needed both, but extends: BaseComponent in the options seems to be enough.
So the double “extend” has apparently duplicated the watcher which lead to the strange behavior I documented in my question.

update: I found out what causes this problem: The watcher seems to be duplicated, because it’s in a BaseComponent which is extended by the Component which is used in my example.
so export default BaseComponent.extend({ name: ‘Component’, …}) seems to duplicate the watch object instead of “merging” it - there is now one in the BaseComponent (where it is implemented initially) and one in the Component - and of course both react to prop-updates.
This seems to be a bug IMHO.

Using vue-cli with single file components.
when setting a prop in one component via a method:

<template>
<div>
<other-component :my-object=”myObject” />
</div>
</template>

<script>
export default (vue.js as VueConstructor).extend({
data() {
return {
myObject: null
}
},

methods: {
actionButtonClicked(action, ID) {
console.log(‘actionButtonClicked’);

this.myObject = {
action: action,
ID: ID
}
}
}
});
</script>

then when watching the prop in the other component with a watcher - but watch gets called twice on every execution of the method.

<script>

export default (vue.js as VueConstructor<Vue>).extend({
/* … */
props: {
myObject: {
type: Object,
default: null
},

watch: {
‘myObject.ID’(value, oldValue) {
console.log(‘watcher executed’);
}
}

/* … */
});

</script>

so in the console i get the output:

actionButtonClicked
watcher executed
watcher executed

.. every time the method gets called.

I already tried all different variants of watchers - for example with deep: true + handler. but this all didn’t change anything about the watcher being called twice.

Solution :

My watcher was duplicated because I was extending my BaseComponent in two ways:

by the extend() method of the component itself
by putting extends: BaseComponent into the options of the “outer” component

I thought you needed to use both pieces of code to extend another component, but apparently this is wrong and can lead to bad side effects.

[Vue.js] Using a Vue.js filter in a conditional statement

when using the vue-currency-filter

and it works great. But there are times when the value it filters is not a number in my application. When that occurs it just show $0. it to show the text value that is not a number.
when there is 345.23 I get $345.23
when there is ‘No limit’ I get $0 and i really want ‘No Limit’

there is tried to include a ternary in my view but it fails. And i think that is related to this.
Which i get but how can i solve this with a method?

Here is my relevant view html:

<div>{ ch.Limit | currency }</div>

and i tried something like:

<div>{ Number.isNaN(ch.Limit) ? ch.Limit : ch.Limit | currency }</div>

which doesn’t work.
I also tried to create a method like this:

valueIsCurrency(k) {
return Number.isNaN(k) ? k | currency : k;
},

coupled with:

<div>{ valueIsCurrency(ch.Limit) }</div>

but the currency filter is not respected in the method. I suppose it is only for use in the render html portion.
How can i fix this?

Solution :

template

<div v-if=”isNumber(ch.Limit)”>{ ch.Limit | currency }</div>
<div v-else>{ ch.Limit }</div>

code

isNumber(n) {
return Number(n);
}

[Vue.js] Bootstrap x search clear button does not work in edgeHTML CODE Update

There is a little “x” which appears when I type in the following search control, when I click it my filter is cleared and my page re-renders. This works fine in chrome. However, it does not work in Edge 17.17134, clicking the “x” does nothing. How can I make it work?

HTML:

<div class=”input-group search”>
<div class=”input-group-prepend”>
<span class=”input-group-text”>
<i class=”fa fa-search”></i>
</span>
</div>
<input type=’search’
class=”form-control”
placeholder=”Type to filter…”
v-model=”filter”
@input=”performFilter” />
</div>

CODE:

data: function () {
return {
filter: ‘’
};
},
methods: {
performFilter() {
var filter = this.filter.toLowerCase();
this.objs.forEach(function (obj) {
obj.visible = obj.name.toLowerCase().includes(filter);
});
}
}

Update:

Seems its a bug in Edge https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/17584515/

Solution :

This has nothing to do with Vue.js or bootstrap, it’s just how Chrome renders <input type=”search”>.

If you want the same behavior on all browsers, use type=”text” and create the own “x” which clears input on click.

Solution 2:

Agree with you, it seems like a publish bug in Edge browser.

As a workaround, I suggest you could attach the mouseup event of the textbox, then using this event to capture the clear action. Please refer to the following code:

<head>
<meta charset=”utf-8”>
<title>iview example</title>
<script type=”text/javascript” src=”http://vuejs.org/js/vue.min.js"></script>
<script type=”text/javascript” src=”http://unpkg.com/iview/dist/iview.min.js"></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src=”findindexpolyfill.js”></script>
</head>
<body>
<div id=”app”>
<input type=’text’ id=”txtfilter”
placeholder=”Type to filter…”
v-model=”filter”
@input=”performFilter” @mouseup=’mouseupEvent’ />
</div>
<script>
new Vue({
el: ‘#app’,
data: {
show: false,
filter:””
},
methods: {
performFilter() {
var filter = this.filter.toLowerCase();
console.log(“input event!” + filter +”<br/>”);
//this.objs.forEach(function (obj) {
// obj.visible = obj.name.toLowerCase().includes(filter);
//});
},
mouseupEvent(e) {
var oldvalue = $(“#txtfilter”).val();

if (oldvalue == “”) {
console.log(‘focus Input!’);
return;
}

//// When this event is fired after clicking on the clear button
//// the value is not cleared yet. We have to wait for it.
setTimeout(function () {
var newValue = $(“#txtfilter”).val();
if (newValue == “”) {
//
console.log(‘Clear Input!’);
}
}, 1);
}
}
})
</script>
</body>

the result as below:

[Vue.js] How to trigger keyup with enter key

When writing unit tests with ava and vuejs how can I trigger the Enter keyup event?

For example, with the following component how can I test that someFunction has been called?

<input
@keyup.enter=”someFunction”
/>

Solution :

I’ve found on vue-test-utils docs. I need to call input.trigger(‘keyup.enter’);

Here is a full example:

test(‘it should call add mutation’, t => {
const wrapper = mount(Todo, { localVue, store: createStore() });
const input = wrapper.find(‘.todo-value’);

input.setValue(‘New todo item’);
input.trigger(‘keyup.enter’);

t.true(mutations.add.called);
});

[Vue.js] Will vuex work properly with generic mutations that don't reference `state`?

Im using vuex with a tree of data. It’s reactive and works well because we have a corresponding tree of components. Since the structure is a tree, its common to want to mutate a deeply nested child object. The easy way to implement that is with a mutation that accepts the child in its payload:

removeLeaf(state, { child, leaf }) {
child.children = child.children.filter((i: any) => i !== leaf);
state = state; // silence warning
},

A different way would be to change the mutation to work like this:

removeLeaf(state, { child_, leaf }) {
let child = searchForChild(state, child_);
child.children = child.children.filter((i: any) => i !== leaf);
},

Im happy with the first way. Are there any drawbacks to writing mutations that modify a child object of state by using payload instead of the state parameter?

Solution :

I don’t think it’ll work properly.

Vue’s and Vuex’s reactivity system is based on Javascript Getter and Setter.

If you console.log the state in any mutation, you will see something like this:

The get and set is the getter and setter of the Vuex States.

Without the setter, Vue’s reactivity system likely wouldn’t work.

Try console.log state and child in the mutation. You will likely see that the child doesn’t contain setter.

If the setter is not there, vue.js wouldn’t know that you have updated the state of child, and you will likely have reactivity problem.

[Vue.js] Nuxt JS LocalStorage in Universal mode not working

I’m working on a Nuxt JS application which utilises LocalStorage. When compiling in SPA mode it functions correctly, however I need to switch my project to universal mode to get my SEO meta titles and descriptions to work when generating my project, after switching I get an error on a few pages which utilise LocalStorage:

localStorage is not defined

Has anyone got any suggestions to fix this?

Solution :

You don’t have localStorage because there is no such thing in Node.js environment. You also don’t have window and document objects.

https://ssr.vuejs.org/guide/universal.html#access-to-platform-specific-apis

Nuxt.js uses vue.js SSR under the hood.

However, you still have a store (Vuex). And it will be synchronized between node and browser.

[Vue.js] Cannot read property 'indexOf' of undefined when using Vue Carousel

I’m using the latest version of vue.js Carousel in my Nuxt JS application. It seems that I get errors on each of my blog posts whenever using the universal mode for Nuxt JS. If I take out vue.js Carousel and do a standard v-for loop, the blogs show perfectly fine, there’s something causing the error when using the carousel.

My code:

<carousel :paginationEnabled=”false” :navigationEnabled=”true” :perPageCustom=”[[250, 1], [1024, 2]]“>
<slide v-for=”blog in blogs.blogs” :key=”blog.id” v-if=”currentBlogDate >= blog.created && blog.created”>
<b-card class=”text-center m-3 p-0 p-md-3”>
<h4 class=”display-4 font-weight-normal mb-3”>{ blog.title | striphtml | truncate(32, ‘…’) }</h4>
<b-card-text class=”text-muted”>{ blog.body | striphtml | truncate(32, ‘…’) }</b-card-text>
<b-button :to=”‘/posts/view/‘ + blog.title” size=”sm” variant=”primary”>Read More<i class=”fas fa-angle-right pl-2”></i></b-button>
</b-card>
</slide>
</carousel>

The error:

TypeError: Cannot read property ‘indexOf’ of undefined

Solution :

Seems like the component is not optimized for server-side rendering.

Keep in mind that Nuxt.js universal has neither window nor document objects during server-side rendering.

Quick fix for you - is to wrap the SSR incompatible components with <no-ssr></no-ssr> component.

https://nuxtjs.org/api/components-no-ssr#the-lt-no-ssr-gt-component

[Vue.js] Vuetify router alignment

I’m trying to setup at route that contains just a table with a layout inspired by the Vuetify team.
there is a problem that the table does not take only a small part of the screen.

there is tried using v-layout with “row”, “column” and different paddings and marging.

App.vue:

<template>
<v-app>
<router-view/>
</v-app>
</template>

<script>
export default {
name: ‘App’,
};
</script>

Menu.vue:

<template>
<v-container>
<v-navigation-drawer
clipped
fixed
v-model=”drawer”
app
\>
<v-list dense>
<v-list-tile
:to=”{name: ‘dashboard’}”
\>
<v-list-tile-action>
<v-icon>dashboard</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Dashboard</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile
:to=”{name: ‘settings’}”
\>
<v-list-tile-action>
<v-icon>settings</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Settings</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile
@click=”logout();”
\>
<v-list-tile-action>
<v-icon>logout</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Logout</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar app fixed clipped-left>
<v-toolbar-side-icon @click.stop=”drawer = !drawer”></v-toolbar-side-icon>
<v-toolbar-title>Hello, { name }</v-toolbar-title>
</v-toolbar>
<v-content>
<v-container fluid fill-height>
<v-layout justify-center align-center>
<v-flex shrink>
<router-view></router-view>
</v-flex>
</v-layout>
</v-container>
</v-content>
<v-footer app fixed>
<span>© arcyfelix 2019</span>
</v-footer>
</v-container>
</template>

<script>
export default {
name: ‘MainMenu’,
data() {
return {
drawer: false,
name: ‘Wojciech’,
};
},
methods: {
logout() {
this.$router.push({ name: ‘home’ });
},
},
};
</script>

Dashboard.vue:

<template>
<v-layout full-width>
<v-data-table
:items=”desserts”
class=”elevation-1”
hide-actions
hide-headers
expand
:loading=”true”
\>
<template v-slot:items=”props”>
<td class=”text-xs-left”>2019-07-01</td>
<td>{ props.item.name }</td>
<td>
<v-btn
small
depressed
flat
\>
Edit
</v-btn>
</td>
</template>
</v-data-table>
</v-layout>
</template>

<script>
export default {
name: ‘Dashboard’,
data() {
return {
desserts: [
{
name: ‘Frozen Yogurt’,
},
{
name: ‘Donut’,
},
{
name: ‘KitKat’,
},
],
};
},
};
</script>

router.js:

import vue.js from ‘vue’;
import Router from ‘vue-router’;

import Menu from ‘./layouts/Menu.vue’;
import MainMenu from ‘./layouts/MainMenu.vue’;
import Dashboard from ‘./views/Dashboard.vue’;
import Login from ‘./views/Login.vue’;
import Home from ‘./views/Home.vue’;

Vue.use(Router);

export default new Router({
mode: ‘history’,
base: process.env.BASE_URL,
routes: [
{
path: ‘auth’,
name: ‘auth’,
component: Menu,
children: [
{
path: ‘dashboard’,
name: ‘dashboard’,
component: Dashboard,
},
{
path: ‘settings’,
name: ‘settings’,
component: () => import(/* webpackChunkName: “about” */ ‘./views/Settings.vue’),
},
],
},
{
path: ‘/‘,
name: ‘mainMenu’,
component: MainMenu,
children: [
{
path: ‘home’,
name: ‘home’,
component: Home,
},
{
path: ‘login’,
name: ‘login’,
component: Login,
},
{
path: ‘register’,
name: ‘register’,
component: () => import(/* webpackChunkName: “about” */ ‘./views/Register.vue’),
},
],
},
],
});

I would like to take it 2/3 or full width of the screen.

Solution :

What you really want is to put the menu outside of the router-view otherwise it has to reload on each page load. You also want to move the container definition inside of the v-content element and make sure it uses fill-height too less you end up with an odd background mesh.

<v-app>
<my-menu></my-menu>
<v-content>
<v-container fluid fill-height>
<router-view></router-view>
</v-container>
</v-content>
</v-app>

Now just change the Dashboard code and layout:

<v-layout row wrap>
<v-flex xs12>
//the rest of the dashboard code
</v-flex>
</v-layout

And you’re good to go.

[Vue.js] vue router Cannot read property 'push' of undefined

i’m using vue.js router and its work and navigate to other pages but gives me errors:

Error in created hook: “TypeError: Cannot read property ‘push’ of undefined”

Cannot read property ‘push’ of undefined

i didn’t used router.push or something like this.

this is my loop and router link:

<swiper-slide v-for=”(item, i) in items” :key=”i”>
<div class=”text-center”>
<router-link :to=”`/tour/` + item.slug”>
<img :src=”item.img” class=”img-fluid img-thumbnail rounded rounded-circle” :alt=”item.title”>
<h3 class=”pt-3”>{ item.title }</h3>
</router-link>
</div>
</swiper-slide>

and this is my route:

{
path: ‘/tour/:tour’,
component: Tour,
name: ‘tour’
},

Solution :

Try

<router-link :to=”{ name: ‘tour’, params: { tour: ‘mySlug’ }”>…</router-link>

[Vue.js] How do I use Vue.set() properly?

when trying to make an array within my store reactive.

there is currently tried using :key to force update, $forceUpdate() and Vue.set(). I originally was getting and updating the data within the calendar component, but I moved the get data logic to the store in hopes that somehow it would make it reactive. The current attribute shows a red dot on the prescribed v-calendar date. From what I can tell the array is populating with objects with the exact same structure as the single attribute, but it is not reactive.

import vue.js from ‘vue’
import Vuex from ‘vuex’
import axios from ‘axios’

Vue.use(Vuex)

export default new Vuex.Store({
state: {
loading: true,
odata: [],
attributes: [{
dates: new Date(),
dot: ‘red’,
customdata: {
programEventsSystemrecordID: 1234
}
}]

},
mutations: {
updateAtts (state) {
let singleAtt = {}
let index = 0

state.odata.forEach((ticket) => {
Vue.set(singleAtt, ‘dot’, ‘red’)
Vue.set(singleAtt, ‘dates’, new Date(ticket.ProgramEventsStartdate))
Vue.set(singleAtt, ‘customData’, {})

singleAtt.customData = {
programEventsSystemrecordID: ticket.ProgramEventsSystemrecordID
}

Vue.set(state.attributes, index, singleAtt)

index++
})
},
updateOdata (state, odata) {
state.odata = odata
},
changeLoadingState (state, loading) {
state.loading = loading
}

},
actions: {
loadData ({ commit }) {
axios.get(‘https://blackbaud-odata-cal-bizcswpdjy.now.sh')
.then((response) => {
commit(‘updateOdata’, response.data)
})
.catch((err) => {
console.log(err)
})
.finally(() => {
console.log(commit(‘updateAtts’))
commit(‘changeLoadingState’, false)
})
}

}
})

I expect the array that is being populated within vue.js to update the DOM. There are no error messages.

Solution :

Vue.set is useless in the case. In mostly all cases, it’s useless.

It’s needed to add new properties in the state that where not initially.

Here, you just have one state property that is build from another.

import vue.js from ‘vue’
import Vuex from ‘vuex’
import axios from ‘axios’

Vue.use(Vuex)

export default new Vuex.Store({
state: {
loading: true,
odata: [],
attributes: [{
dates: new Date(),
dot: ‘red’,
customdata: {
programEventsSystemrecordID: 1234
}
}]

},
mutations: {
updateAtts (state) {
state.attributes = state.odata.map(t=>({
dot: ‘red’,
dates: new Date(t.ProgramEventsStartdate),
customData: {programEventsSystemrecordID: t.ProgramEventsSystemrecordID}
}))
},
updateOdata (state, odata) {
state.odata = odata
},
changeLoadingState (state, loading) {
state.loading = loading
}

},
actions: {
loadData ({ commit }) {
axios.get(‘https://blackbaud-odata-cal-bizcswpdjy.now.sh')
.then((response) => {
commit(‘updateOdata’, response.data)
})
.catch((err) => {
console.log(err)
})
.finally(() => {
console.log(commit(‘updateAtts’))
commit(‘changeLoadingState’, false)
})
}

}
})