Call Vue method on button click - vue.js

I am new to Vue and I've been toying around with a basic component and trying to get some interactivity to work. However, when attempting to implement some methods, I find that nothing actually happens. My code looks like this:
var testComponent = Vue.component('testComponent', {
data: function () {},
props: [ 'maps' ],
methods: {
filt: function() {
alert("Useful alert");
}
},
template: "<div><button class='btn-primary' #click='filt'>Filter</button></div>"
});
var vm = new Vue({
el: '#app',
data: {},
methods: {},
computed: {},
components: {
TestComponent: testComponent
},
ready: function () {}
});
And my HTML essentially contains only this:
<test-component></test-component>
I would like to call the testComponent's filt method (which will later hopefully become a working filter method for the maps prop), but the button gives no alert on pressing it.
I've tried a few variations like v-on:click, but to no avail.
Any help would be greatly appreciated!

Related

Use API call in component

I am playing around with VueJS and trying to make an api call from within a component:
var postView = {
props: ['post'],
template: '<li>{{ post.title }}</li>',
url: 'https://jsonplaceholder.typicode.com/posts',
data: function () {
return {
results: []
}
},
mounted() {
axios.get(url).then(response => {
this.results = response.data
})
},
ready: function () { },
methods: {}
}
Vue.component('postitem', postView);
var app = new Vue({
el: '#app',
data: {},
ready: function () { },
methods: {}
})
I get the following error:
[Vue warn]: Property or method "results" is not defined on the
instance but referenced during render.
I am wondering what the best approach is to make api calls from within a component and display it on a HTML page. I learned that a component’s data option must be a function, but I'm not sure what the error related to 'results' means.
First of all you should consider using vue single file components. They are great for splitting your functionality.
Vue requests guide
You can watch the whole playlist for complete vue guide. The link is to the video that explains api calls in vue.
i think that error for (this)
you can do like that:
var vm = this;
axios.get(url).then(response => {
vm.results = response.data
})

Why is this the window object in a Vue method even with an Arrow function

I have a simple Vue app that looks like this...
new Vue({
el: "#app",
data: {
value:""
},
mounted: function(){
this.test(10);
},
methods: {
test: (max) =>{
console.log(this)
}
}
})
Console outputs window I would expect it to be the Vue Application. How do I structure it so that this is Vue?
this is window especially in your arrow function.
Use a normal function declaration, or the equivalent ES2015 method declaration shorthand:
new Vue({
el: "#app",
data: {
value: "test"
},
mounted: function() {
this.test(10);
this.test2(42);
this.test3(42);
},
methods: {
// Arrow function: `this` is the context when declaring.
test: (max) => {
console.log(this === window)
},
// Function expression: `this` is the context when calling.
// Bound to the Vue instance by Vue.
test2: function(max) {
console.log(this.value);
},
// ES6 method shorthand, same as above.
test3(max) {
console.log(this.value);
}
}
});
<script src="https://unpkg.com/vue#2"></script>
<div id="app"></div>

In Vue, how do I set a data property from a method on load?

I'd like to have a data prop populated by data received from an axios http request. Here's a simplified version of the issue.
I would like the 'hello' prop to populate when the app loads. And when the user clicks the button, the 'hello' prop should update. The click-and-update part is working as expected, but how do I get the data to populate the 'hello' prop initially? I've also tried it with computed properties, but that also doesn't populate the 'hello' prop on the initial load. Thanks!
<div id="app">
<h1>{{ hello }}</h1>
<button #click="updateText()">Update text!</button>
</div>
var app = new Vue({
el:'#app',
created() {
updateText() // Calling this here does not work
},
data: {
hello: ''
},
methods: {
updateText: function() {
this.hello = 'hello'
}
}
});
You don't have this. before the method name inside created so it's not calling the method:
var app = new Vue({
el: '#app',
data: function() {
return {
hello: ''
}
},
created () {
this.updateText()
},
methods: {
updateText: function() {
this.hello = 'hello'
}
}
})

Delegate event in vue

Im trying to delegate an avent from one instance to another.
I have a toolbar on the top of the page with a button like this
<div id="toolbar">
<button v-on:click="add" class="btn btn-default" type="submit"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Ny</button>
</div>
This add event working in this vue instance
var toolbarApp = new Vue({
el: '#toolbar',
data: {
},
methods: {
add: function (event) {
alert('lol');
}
}
});
But now i want to attach this add event to another instance like this
var contactApp = new Vue({
mixins: [toolbarApp],
el: '#contact',
data: {
showGrid: true,
showForm: false,
editMode: false
},
created: function () {
this.getContacts();
},
methods: {
getContacts: function () {
$.getJSON(this.apiGrid, function (data) {
this.contacts = data;
}.bind(this));
},
add: function (event) {
alert('hej');
}
}
});
But i cant attach this because of diffrent instance. Is it any way to do this?
Have also tried with mixedin with no luck.
Thanks in advice
what you are trying to do is not unique, there's even a title for it "Event bus"
EventBus = new Vue();
var toolbarApp = new Vue({
el: '#toolbar',
data: {
},
methods: {
add: function (event) {
EventBus.$emit('add-something', this.somevar);
}
}
});
then in your other instance:
var contactApp = new Vue({
mixins: [toolbarApp],
el: '#contact',
data: {
showGrid: true,
showForm: false,
editMode: false
},
created: function () {
this.getContacts();
EventBus.$on('add-something', function(somevar) {
// do cool stuff, like this.getContacts...
});
},
methods: {
getContacts: function () {
$.getJSON(this.apiGrid, function (data) {
this.contacts = data;
}.bind(this));
},
add: function (event) {
alert('hej');
}
}
});
Definition:
Sometimes you need a quick and easy solution to pass data between Vue.js components.
For an application with simple architecture it’s enough to communicate between components using events. For this we can create a quick solution and implement EventBus. EventBus allows us to emit an event in one component and listen for that event in another.
https://medium.com/#andrejsabrickis/https-medium-com-andrejsabrickis-create-simple-eventbus-to-communicate-between-vue-js-components-cdc11cd59860

Reference component in another one

In a VueJS file i have two component :
var firstComponent = Vue.extend({
template: '#component1',
[...]
methods:
comp1function: function() {
[...]
comp2function()
}
[...]
}),
var secondComponent = Vue.extend({
template: '#component2',
[...]
methods:
comp2function: function(){
do things here
}
[...]
})
so what i want to do is to say : do comp2function when you finished to do comp1function. So is there any way i can reference a function from my template component2 in my template component1 ?
You should use Vue Events. I assume you are using VueJS 1.x?
So let's imagine you have those two components as you stated in your question:
var firstComponent = Vue.extend({
template: '#component1',
methods: {
doSomething () {
// Do things here
console.log('I do things')
// Fire an event when you want:
this.$dispatch('some-event')
}
}
})
var secondComponent = Vue.extend({
template: '#component2',
methods: {
doSomethingElse () {
console.log('I do something else')
}
},
events: {
trigger () {
this.doSomethingElse()
}
}
})
You need to trigger an event from your first component using the $dispatch method. Then, in your Vue Instance, you need to get that event, and use $broadcast to broadcast a new event to the other Vue children:
new Vue({
el: '#app',
components: {
firstComponent,
secondComponent
},
events: {
'some-event' () {
this.$broadcast('trigger')
}
}
})
You will then be able to get the event in your secondComponent and trigger whatever method you want
You can learn more about custom events on this page: http://v1.vuejs.org/guide/components.html#Parent-Child-Communication