set variable from component in instance - javascript

I want to set data variable of Vue instance from component. Is that even possible.
Vue.component('graph', {
template: '',
props: {},
data: function () {
methods: {
setBtn: function () {
//here i want to set ShowBtn variable for example to false
},
}, this.getUserRecordStatistic();
});
new Vue({
el: '#app',
data: {
showBtn: null
},
methods: {},
});

This should do the trick:
Vue.component('graph', {
template: '',
props: {},
data: {},
methods: {
setBtn: function () {
app.showBtn = false;
},
},
});
var app = new Vue({
el: '#app',
data: {
showBtn: null
},
methods: {},
});

You can access data on the root vue instance through vm.$root.
setBtn: function () {
this.$root.showBtn = false;
},

As a best practice you should avoid directly setting params on other components. Vue is intended to decouple its components therefore directly editing a param, although possible, runs in the face of this. Check out the components guide for more info, specifically: https://v2.vuejs.org/v2/guide/components.html#Composing-Components
Therefore rather than directly editing this param you should emit an event from the component which you can listen for on the root - or any other component that sets the graph component, i.e.
graph component emit an event
Vue.component('graph', {
methods: {
activateBtn () {
this.$emit('set-button', true)
},
...
root or any component that sets graph in its template
# template
<graph #set-button="setBtn"></graph>
# script
new Vue({
el: '#app',
data: {
showBtn: false
},
methods: {
setBtn (state) {
this.showBtn = state
},
},
})

Related

How can i use my component method in my vue?

I have a method "aggiornaQuantity" in this component that i would use in my vue. How can i do?
Obviously I did various tests without any success
Vue.component('todo-item', {
props: ['todo'],
template: '...',
methods:
{
aggiornaQuantity: function()
{
return this.todo.quantity = this.value ;
}
}
var app7 = new Vue
(
{
el: '#app-7',
data:
{
message: '${Message}',
risultato: true,
groceryList: [],
product: '',
selected: '',
},
methods:
{
.....
}
Edit: I'm not sure if you want to know how to use the function or why your function doesn't work (as commented above). If it's the former, here's the answer:
You have to call it in one of the lifecycle instances. Most of the time, we call it in mounted().
...
methods: {
foo () {
// do something
},
},
mounted() {
this.foo();
},
...

How to use data from one hook to other hook in Vue.js?

In my vue.js application I send request by axios package in created() hook. I add response to array called coordinates. I want to use that array outside of created() hook. For example in mounted() hook or in functions which we can set in methods.
Right now when I tried to use self.coordinates outside created() hook it return undefined. When I use this.coordinates it return just [__ob__: Observer].
Whats wrong I did?
export default {
name: "Map",
data() {
return {
coordinates: [],
}
},
created() {
let self = this;
axios.get('URL').then(function (response) {
let coordinates = [];
for (let i = 0; i < response.data.length; i++) {
coordinates.push([response.data[i]["LATITUDE"], response.data[i]["LONGITUDE"]]);
}
self.coordinates = coordinates;
});
},
mounted() {
console.log(self.coordinates); // undefined
consol.log(this.coordinates); // [__ob__: Observer]
},
}
I would prefer "mounted" and move the logic into methods for reusability. The method can be kicked from anywhere afterwards. In the example below, I prefered kicking the method direcly. Watchers is another option.
Here is the fiddle https://jsfiddle.net/dj79ux5t/2/
new Vue({
el: '#app',
data() {
return {
coordinates: []
}
},
mounted() {
let self = this;
axios.get('https://api.weather.gov/').then(function (response) {
self.coordinates = response.data;
self.greet();
});
},
methods: {
greet: function () {
console.warn(this.coordinates.status);
}
}
})
I think instead of mounted , you should use watch . You call some link so it will take time to load that data , watch method will trigger when your data is updated ...
watch: {
coordinates: {
handler: function (updateVal, oldVal) {
console.log(updateVal)
},
deep: true
}
},

Vue plugin, adding global component which takes data

I am using Vue plugins so that user can access a global component once registering the global component and configuring it inside Vue.use. For this I need to pass some data from Vue.use() to Component.vue.
Take a look at the following code:
Vue.use(MyPlugin, { data: true });
the code of MyPlugin is
import Plugin from './plugin';
const IconPlugin = {
install(Vue, options) {
console.log(options); // Here I can see {data: true}
Vue.component('GlobalComponent', Icon);
},
};
Now I need to pass this options variable to the component. So that a user whenever use
<GlobalComponent />
{data: true} should always be there.
Basically, that is a configuration which user is passing and the further component computation will be dependent on this.
You can use Vue.extend to extend components
var Icon = Vue.extend({
data: function() {
return {
foo: 'fooooo',
bar: 'barr'
}
},
template: '<div><button #click="doFooStuff">{{foo}}</button><button #click="doBarStuff">{{bar}}</button></div>',
methods: {
doBarStuff: function() {
console.log(this.foo, this.bar)
},
doFooStuff: function() {
console.log(this.foo)
}
}
})
const IconPlugin = {
install(Vue, options) {
// console.log(options);
// normalize data (select only props you want)
var data = Object.assign({}, options);
var NewIcon = Icon.extend({
data: function() {
return data;
}
})
Vue.component('GlobalComponent', NewIcon);
},
};
Vue.use(IconPlugin, {
foo: 'FOOO'
});
new Vue({
el: '#app',
components: {
Icon
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<icon></icon>
<global-component></global-component>
</div>
it sounds like you want to take a look at the component guide. It would seem that you want to merge the data with where you are passing Icon.

Vue: Accessing data from an unmounted component

I have an issue where I want to retreive data from a child component, but the parent needs to use that data, before the child is mounted.
My parent looks like this
<template>
<component :is="childComp" #mounted="setData"/>
</template>
<script>
data : {
childComp : null,
importantData : null
},
methods : {
addComponent : function() {
this.prepareToAdd(this.importantData);
this.childComp = "componentA"; //sometimes will be other component
},
setData : function(value) {
this.importantData = value;
},
prepareToAdd : function(importantData){
//something that has to be run before childComp can be mounted.
}
}
</script>
My child (or rather, all the potential children) would contain something like this:
<script>
data : {
importantData : 'ABC',
},
created: function() {
this.$emit('mounted', this.importantData);
},
</script>
This clearly doesn't work - importantData is set when the childComponent is mounted, but prepareToAdd needs that data first.
Is there another way of reaching in to the child component and accessing its data, before it is mounted?
You can use $options to store your important data and have it available in beforeCreate. You can also use it to initialize a data item, and you can emit data items in created (you don't have to initialize from $options to emit in created, I'm just pointing out two things that can be done). The $options value is, itself, reactive (to my surprise) and can be used like any data item, with the added benefit that it is available before other data items.
new Vue({
el: '#app',
methods: {
doStuff(val) {
console.log("Got", val);
}
},
components: {
theChild: {
template: '<div>Values are {{$options.importantData}} and {{otherData}}</div>',
importantData: 'abc',
data() {
return {
otherData: this.$options.importantData
};
},
beforeCreate() {
this.$emit('before-create', this.$options.importantData);
},
created() {
this.$emit('on-created', this.otherData + ' again');
// It's reactive?!?!?
this.$options.importantData = 'changed';
}
}
}
});
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
<the-child #before-create="doStuff" #on-created="doStuff"></the-child>
</div>
My bad :(
We cannot get the data inside beforeCreated() hook.
Use the beforeCreate() hook instead of created() hook:
beforeCreate: function() {
this.$emit('mounted', this.importantData);
},
We can use a watcher or computed option, so now your parent component would look:
data: {
childComp: null,
importantData: null,
isDataSet: false
},
methods: {
addComponent: function() {
this.prepareToAdd(this.importantData);
this.childComp = "componentA"; //sometimes will be other component
},
setData: function(value) {
this.importantData = value;
this.isDataSet = true;
},
prepareToAdd: function(importantData) {
//something that has to be run before childComp can be mounted.
}
},
watch: {
isDataSet: function(newValue, oldValue) {
if (newValue) {
this.addComponent();
}
}
}
I would suggest to use computed method as it caches the results. Use watcher when you have to perform asynchronous code.

VueJS2 property not defined

I wrote the following code and Vue complains:
[Vue warn]: Property or method "incidents" is not defined on the
instance but referenced during render. Make sure to declare reactive
data properties in the data option.
I don't see why incidents cannot be accessed?
var app = new Vue({
el: '#app',
data: {
responders: [],
incidents: []
},
mounted: function () {
this.getIncidents();
},
methods: {
getIncidents: function() {
console.log('getIncidents');
var app = this;
this.$http.get('/api/v1/incidents').then(function(response) {
// set data
var incidentsReceived = response.data.map(function (incident) {
return incident;
});
Vue.set(app, 'incidents', incidentsReceived);
})
},
getResponders: function() {
console.log('fetchResponders');
var app = this;
this.$http.get('/api/v1/responders').then(function(response) {
// set data on vm
var respondersReceived = response.data.map(function (responder) {
return responder
});
Vue.set(app, 'responders', respondersReceived);
});
}
}
})
EDIT: Didn't read the code very well for the first time. Verify that you have data inside the response and if not don't set it the incidents array.
data is meant for internal component data modeling, while props, which can be assigned externally, are defined using the props key for your component.
In other words, try:
var app = new Vue({
...,
props: {
incidents: {
type: Array,
required: false //change this as you see fit.
}
},
...
});
For full documentation on component properties, please refer to the official guide.

Categories

Resources