link548 link549 link550 link551 link552 link553 link554 link555 link556 link557 link558 link559 link560 link561 link562 link563 link564 link565 link566 link567 link568 link569 link570 link571 link572 link573 link574 link575 link576 link577 link578 link579 link580 link581 link582 link583 link584 link585 link586 link587 link588 link589 link590 link591 link592 link593 link594 link595 link596 link597 link598 link599 link600 link601 link602 link603 link604 link605 link606 link607 link608 link609 link610 link611 link612 link613 link614 link615 link616 link617 link618 link619 link620 link621 link622 link623 link624 link625 link626 link627 link628 link629 link630 link631 link632 link633 link634 link635 link636 link637 link638 link639 link640 link641 link642 link643 link644 link645 link646 link647 link648 link649 link650 link651 link652 link653 link654 link655 link656 link657 link658 link659 link660 link661 link662 link663 link664 link665 link666 link667 link668 link669 link670 link671 link672 link673 link674 link675 link676 link677 link678 link679 link680 link681 link682 link683 link684

[Vue.js] What's the right approach to update a parent's component array of objects from a child component? Subscribe to RSS

there is a complex form with different tabs. I use vue-router to switch between these and display different modular components in a router-view for each one of them. In these tabs there is child components with sometimes other nested child components. I use the event bus approach to pass data from these child components up in tree. I’m doing this because the final tab will be a summary of the form, and I will need access to all the form data. At the moment I’m using something like the below.

For example using this structure:

|App
--|Start
--|Question 1
--|Answer 1
--|Answer 2
--|Question 2

In the root component (App):

data() {
return {
questions: 0,
answers: []
}
},
created() {
eventBus.$on(‘answer-added’, answer => {
let answer_exists = false
this.answers.forEach( (e, i) => {
if(e.id == answer.answer_id) answer_exists = true
});
if(!answer_exists) this.answers.push({
id: answer.answer_id,
answer: answer.answer_text
})
});
}

What’s the proper way to create/update/delete the array of answers in the App component every time an event from the child is fired?
I’m sure there must be a much better way than iterating over the array elements to check whether the answer already existed or not… Just can’t figure it out.

Solution :

Do you mean something like:

if (!this.answers.find(a => a.id === answer.answer_id)) {
this.answers.push(/* … */);
}

Solution 2:

What you are doing is more or less right. There is no escape from the loop. However, there are certain things you can improve upon. Instead of forEach, you can use Array.some method. Alternately, you can use Array.find method:

eventBus.$on(‘answer-added’, answer => {

// Instead of using forEach, you can use Array.some() method
const answerExists = this.answers.some((x) => e.id == answer.answer_id);

if (!answerExists) {
this.answers.push({
id: answer.answer_id,
answer: answer.answer_text
});
}
});

Second, there is no problem with using an event bus, but it is generally used for a sibling or cross-component communication. When all the components are in the same ancestor or parent hierarchy, using $emit for events is the right way.

In the case, even though you have a nested components hierarchy, as the application evolves, a hierarchy can get really deep and you will quickly lose the track of typical publish-subscribe mechanism of the event bus. Even if it means re-emitting the same events from intermediate components, you should follow this practice.

Solution 3:

For anyone who comes across with the same issue, the problem I encountered is resolved by using a Simple Global Store. Other more complex scenarios would possibly require Vuex as suggested by @Dan above.

Solution 4:

Pass a callback from parent to child. Now they can communicate bottom up. The child can pass any data the parent might want and then the parent can take back control and use its state or closure state.

[Vue.js] How to bind Vue js watchers to an array of objects Subscribe to RSS

there is an array that contains many objects like this :

[{x: updateX}, {y: updateY} ]

By using this array, to generate vue.js js watchers automatically like this:

watch: {
x(){
this.updateX()
},
y(){
this.updateY()
}
}

I only know that vue.js keep watchers as array.

Solution :

you can create an array and return from it a list of functions something like this:

data(){ return {
watcherArray: [];
}
}
methods: {
pushToWatchersArray() {
this.watcherArray.push(someValue);
}
returnNewWatchers(){
return { this.watchersArray.map(watcher => return `${watcher}(){
this.updatewatcher()}
}
watch: {
[…this.returnNewWatchers()]
}

You may also need to rerender the component when changing the watchers, when not sure about this, in addition you may need a separate watcher to watch for changes on the array to do this rerender.

Solution 2:

You can use a deep watcher for that

watch: {
arr: {
handler(val){
// do stuff
},
deep: true
}
}

[Vue.js] error SWIFT_VERSION '5.0' is unsupported, supported versions are 3.0, 4.0, 4.2. (in target 'Starscream') Subscribe to RSS

Steps to recreate

$ vue.js init nativescript-vue/vue-cli-template transport
$ cd transport
$ npm install
$ tns run ios –bundle

Log error:

error: SWIFT_VERSION ‘5.0’ is unsupported, supported versions are: 3.0, 4.0, 4.2. (in target ‘Starscream’)
note: Using new build systemnote: Planning buildnote: Constructing build description
** ARCHIVE FAILED **

Mac OS High Sierra 10.13.6
Darwin Aerosol.local 17.7.0 Darwin Kernel Version 17.7.0: Wed Feb 27 00:43:23 PST 2019; root:xnu-4570.71.35~1/RELEASE_X86_64 x86_64

node -v v11.7.0
npm -v 6.9.0
vue.js -v 3.6.3

I was able to create new apps and run them on my iOS devices but for some reason things have changed last 1-2 week. It looks like I can not develop NativeScript apps anymore. Any hints?

Solution :

if you have problems with SWIFT_VERSION on the build you can configure manually it adding a PodFile to the project (App_Resources/iOS) setting the version you want, something like this in the PodFile should solve the problem

pre_install
do |installer|
installer.analysis_result.specifications.each
do |s|
if s.name == ‘Starscream’
s.swift_version = ‘4.2’
end
end
end

I wish this can help you

Solution 2:

The last time I had issues with Swift versions an Pods, downgrading cocoapodsfrom 1.6.x to 1.5 resolved the issue:

sudo gem uninstall cocoapods
sudo gem install cocoapods -v 1.5.3

Looking at the release notes for cocoapods1.6 back in march showed some changes regarding this.

The error messages were different, though but it might be worth a try.

[Vue.js] vue-router how to check if current route is a route or one of its subroutes? Subscribe to RSS

I’m wrapping router-link to add some features.

I need to check if current route is a route or a subdolder of a route.

Something like the following

I know it cannot works, because :active need a boolean, but javascript String.match returns an array;: it’s to explain my goal

:active=”$route.name.match(‘customer_users*‘)”

In my router.js I definied that /customer/{customer_id}/users is named customer_users and that /customer/{customer_id}/users/{user_id} is named customer_users_edit.

So i’d like to be able to set “:active” in my wrapper for both these routes.

Solution :

Use the $route.matched property to see if the current route is the customer_users or any of its children.

For example, using Array.prototype.some()

:active=”$route.matched.some(({ name }) => name === ‘customer_users’)”

See https://router.vuejs.org/api/#route-object-properties

$route.matched

type: Array<RouteRecord>

An Array containing route records for all nested path segments of the current route.

[Vue.js] how to handle vars that do not exist in a vue js template? Subscribe to RSS

In my vue.js templates there is numerous instances of

{ jobs[0].stages[0].node.name }

and similar. If a job does not have any stages - then the entire template will fail to load and vue.js admin gives me the following warning.

Error in render: “TypeError: Cannot read property ‘node’ of undefined”

Is there a way to handle this more gracefully so for example if the stages or node does not exist - the template continues to load and this value is replaced with ‘N/A’ or something similar?

Im hoping the solution can be in the template itself rather than some complicated js (i’m new to js so its’ all complicated to me)

Solution :

Okay, so I’m going to base this answer on the fact that you have something like that :

<div>{ jobs[0].stages[0].node.name }</div>

What you can do is using the v-if directive :

<div v-if=”jobs[0].stages && jobs[0].stages.length”>{ jobs[0].stages[0].node.name }</div>
<div v-else>N/A</div>

Here is the documentation : https://vuejs.org/v2/guide/conditional.html

Solution 2:

If want to do this in the template it can be done, but doing so is fairly ugly:

<div>{ jobs[0] && jobs[0].stages && jobs[0].stages[0] && jobs[0].stages[0].node.name }</div>

You’ll need to add more or fewer && conditions depending on how paranoid you’d like to be about the existence of the nested properties. E.g. if you think either all of the data are there or the stages array is null/undefined, you could write it like this:

<div>{ jobs[0].stages && jobs[0].stages[0].node.name }</div>

Instead, I’d recommend using a computed property to apply the necessary guards so the template isn’t a mess. The commonly used function for fetching a possibly nonexistent deep property is get from lodash. You can just import get without importing all of lodash as shown in this example:

<template>
<div>{ stageName }</div>
</template>

<script>
import get from ‘lodash/get’;

export default {
props: {
jobs: {
type: Array,
required: true,
},
},
computed: {
stageName() {
return get(this.jobs, ‘[0].stages[0].node.name’, ‘missing name’);
},
},
};
</script>

Note that the last argument to get is the default value. In this case’missing name’ will appear if one or more of the properties is missing.

[Vue.js] Recenter google map with vue2-google-maps Subscribe to RSS

to create a button to refocus the map. Why does not this code work?

<GmapCustomMarker
@click=”center={lat:latitude, lng: longitude}”
\>
</GmapCustomMarker>

Solution :

Based on the documentation here:
https://www.npmjs.com/package/vue2-google-maps
It seems that you need to have an <GmapMap> and a <GmapMarker> element nested inside but not as you wrote it in one element of <GmapCustomMarker>.
Try this:

<GmapMap
:center=”{lat:something, lng:somethingElse}”
:zoom=”7”
map-type-id=”terrain”
style=”width: 500px; height: 300px”
\>
<GmapMarker
@click=”center={lat:latitude, lng: longitude}”
/>
</GmapMap>

[Vue.js] There are performance issues combining VueJS and Django? Subscribe to RSS

there is decided to use VueJS with Django. Will there any performance issue happen with this? if any, should I use webpack loader?

Solution :

The short answer is NO. There are no performance issues using Django and VueJS.

The bottleneck in most of web applications is the database access. Django uses its own ORM which is really easy to work with and very well documented but not famous by its performance.

Given that VueJS is a frontend library, it has no impact in the database access and/or backend stuff, so the combination of Django+vue.js will be pretty similar to a 100% Django application.

Having said that, notice that you will probably have to implement a Django backend using a toolkit like Django Rest Framework and many Django features like Forms and Jinja templates will be useless. Implementing all that functionality with a frontend library like Vue, can reduce the requests and data exchange between clients and server, so thus, the performance can improve significantly in applications with small DB access.

[Vue.js] VueJS accessing a method from another method Subscribe to RSS

I’m using VueJS to make a simple enough resource management game/interface. At the minute I’m looking to activate the roll function every 12.5 seconds and use the result in another function.
At the moment though I keep getting the following error:

Uncaught TypeError: Cannot read property ‘roll’ of undefined(…)

there is tried:

app.methods.roll(6);
app.methods.roll.roll(6);
roll.roll()
roll()

but can’t seem to access the function. Anyone any ideas how I might achieve this?

methods: {

// Push responses to inbox.
say: function say(responseText) {
console.log(responseText);
var pushText = responseText;
this.inbox.push({ text: pushText });
},

// Roll for events
roll: function roll(upper) {
var randomNumber = Math.floor(Math.random() * 6 * upper) + 1;
console.log(randomNumber);
return randomNumber;
},

// Initiates passage of time and rolls counters every 5 time units.
count: function count() {
function counting() {
app.town.date += 1;
app.gameState.roll += 0.2;

if (app.gameState.roll === 1) {
var result = app.methods.roll(6);
app.gameState.roll === 0;
return result;
}
}

setInterval(counting, 2500);

// Activates the roll at times.
}
}

Solution :

You can access these methods directly on the VM instance, or use them in directive expressions. All methods will have their this context automatically bound to the vue.js instance.

vue.js API Guide on methods

Within a method on a vue.js instance you can access other methods on the instance using this.

var vm = new Vue({

methods: {
methodA() {
// Method A
},
methodB() {
// Method B

// Call `methodA` from inside `methodB`
this.methodA()
},
},

});

To access a method outside of a vue.js instance you can assign the instance to a variable (such as vm in the example above) and call the method:

vm.methodA();

Solution 2:

You can use vm.methodName();

Example:

let vm = new Vue({
el: ‘#app’,
data: {},
methods: {
methodA: function () {
console.log(‘hello’);
},
methodB: function () {
// calling methodA
vm.methodA();
}
},
})

Solution 3:

let vm = new Vue({
el: ‘#testfunc’,
data:{
sp1: “Hi I’m textbox1”,
sp2: “Hi I’m textbox2”
},
methods:{
chsp1:function(){
this.sp1 = “I’m swapped from textbox2”
},
chsp2:function(){
this.sp2 = “I’m swapped from textbox1”;
this.chsp1();
},
swapit:function(){
this.chsp2();
}
}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”testfunc”>
<input type=”text” :value=”sp1”></span>
<input type=”text” :value=”sp2”></span>
<button @click=”swapit()”>Swap</button>
</div>

[Vue.js] Understanding undocumented Vue.js attributes ( Vue + Pug ) Subscribe to RSS

So i was just browsing through certain vue.js code HERE. and came across the following code below:

menu-dropdown.task-dropdown(
v-if=”!isRunningYesterdailies”,
:right=”task.type === ‘reward’”,
ref=”taskDropdown”,
v-b-tooltip.hover.top=”$t(‘options’)”
)

I don’t quite understand this attribute :right that is inserted in the code ? What is it doing and what is its purpose , when new to Vue.js , but by looking around a bit i was able to find documentation for the rest of the attributes except this attribute called :right ? Can anybody shed some light on this ?

Solution :

The : in front of html attributes is a shorthand for the v-bind directive. what v-bind allows you to do is have a variable value to the specified html attribute.
ex: v-bind:alt=”kittenPhotoDescription” is the same as doing alt:”kittenPhotoDescription”.

Here is where it’s found in the docs.

Solution 2:

I don’t know Pug well, but it seems to me that the pasted Pug code creates a menu-dropdown element with those given attributes. right attribute is bound to a dynamic value from the vue.js model using the v-bind: directive’s shorthand :.

I searched for menu-dropdown component’s definition in the repository you linked, and find this file:
https://github.com/HabitRPG/habitica/blob/develop/website/client/components/ui/customMenuDropdown.vue

This is where the right attribute is defined as a vue.js prop:

<script>
export default {
props: {
right: Boolean,

You can read more about props in the vue.js documentation.

[Vue.js] VUE add a component with JS Subscribe to RSS

Can I create/mount a vue.js component calling a JS function in a fullyloaded page?

As a async call? Something like:

function getComponent(obj){
return <component parameters=”obj”></component >;
}

Solution :

I think what you are looking for is vue.js dynamic components. What that allows you is to choose which component to load after the original component has loaded. You can do that whenever and however you want to, aka in an async way. You can read more in the vue.js guides. All the code you need is there so won’t repost it here again.

Solution 2:

Can I create/mount a vue.js component calling a JS function in a fullyloaded page?

I think you want to load/mount the component in a certain condition and not on page initialization.

If that the case then you can take advantage of lazy-loading and dynamic components:

<template>
//…
<button @click=”activateComponent”>Activate component</button>
<component :is=”dynamicComponent” />
//…
</template>

<script>
export default {
components: {
MyCmp: () => import(‘./MyCmp.vue’) //lazy loading
},

data: () => ({
dynamicComponent: null
}),

methods: {
activateComponent () {
this.dynamicComponent = ‘MyCmp’
}
}
}
</script>