I have two Vue.js components Lobby and Game. I want to use Game as a model that contains all logic to create a game and trigger it via the Lobby component.
if I run the app and click on the button I get the following error
Uncaught TypeError: game.createGame is not a function
at click (eval at createFunction (vue.js:9923), <anonymous>:2:76)
at HTMLButtonElement.invoker (vue.js:1827)
How can I access the game method from the Lobby component? Thanks!
let Game = {
methods: {
createGame: function () {
console.log('createGame clicked')
}
}
}
let Lobby = {
template: `
<div>
<button v-on:click="game.createGame()">Create</button>
</div>
`,
data() {
return {
'game': Game
}
},
}
If you want to call a method from another component you can use Event bus from Vue.js
The main idea is that you have to emit a global call in A component and receive it in B component using bus.$on
var bus = new Vue();
Vue.component('Increment', {
template: "#inc",
data: function() {
return ({count: 0})
},
methods: {
increment: function(){
var increment = ++this.count
bus.$emit('inc', increment)
}
}
})
Vue.component('Display', {
template: "#display",
data: function(){
return {count: 0}
},
created: function(){
bus.$on('inc', function(num){
this.count = num
}.bind(this));
}
})
vm = new Vue({
el: "#example",
})
https://jsfiddle.net/emwcoy36/
Related
Let's suppose that I have the following situation, using a Global Mixin to create a global helper method with Vue:
import Vue from "vue";
Vue.mixin({
methods: {
replaceString: function (word) {
return word.toLowerCase().replace(/\W/g, '');
}
}
});
let vm = new Vue({
methods: {
doSomething: function() {
console.log(this.replaceString('Hello World'); //helloword
}
}
});
I know that I can invoke the method inside the other methods, inside of the component and their childs. But how can I invoke the mixin method "replaceString" from the Vue instance "vm"?
I tried to use "vm.replaceString", but keeps returning "undefined".
Few changes to your code and it works:
You should change the definition of your mixin (var mixin instead of Vue.mixin)
Import the mixin to your new vue component (mixins = [mixin])
import Vue from "vue";
var mixin = {
methods: {
replaceString: function (word) {
return word.toLowerCase().replace(/\W/g, '');
}
}
};
let vm = new Vue({
mixins: [mixin]
methods: {
doSomething: function() {
console.log(this.replaceString('Hello World'); //helloword
}
}
});
I think this chunk o code is what you are looking for:
var mixin = {
methods: {
foo: function () {
console.log('foo')
},
conflicting: function () {
console.log('from mixin')
}
}
}
var vm = new Vue({
mixins: [mixin],
methods: {
bar: function () {
console.log('bar')
},
conflicting: function () {
console.log('from self')
}
}
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
From the docs
I want to display the updated data in the modal. There is a click function which trigger the testing(data) function below.
The data comes out right in the function. However, the template doesn't seem to update, it still displays the previous data. How can I fix this?
Script:
function testing(data) {
const testingLink = new Vue ({
el: '#test',
data: { selected: data },
methods: {
showDialog: function() { $("#test).modal() }
}
})
testingLink.showDialog()
}
You shouldn't create a Vue Instance in a repeatable function
Try it in following way:
const testingLink = new Vue ({
el: '#test',
data: { selected: null },
methods: {
showDialog: function(data) {
this.selected = data
$("#test").modal()
}
}
})
testingLink.showDialog(YOUR_DATA_YOU_WANT_TO_PASS)
I am trying to build a simple quiz app. it has some questions which are in the database. I am fetching those using AXIOS request.
I am doing something like this :
var app = new Vue({
el:"#app",
data:{
currentQuestion:0,
question:{}
},
methods:{
next:function(){
this.currentQuestion+=1;
this.loadQuest();
} ,
loadQuest:function(){
axios.get('/questions').then((response)=>{
//console.log(response.data[this.currentQuestion]);
this.question = response.data[this.currentQuestion];
})
}
},
mounted(){
this.loadQuest();
},
});
Here you can see whenever I click next question button loadQuest() is called and a request is sent to the server. Is there any way not to send request on every next button click instead just increment the currentQuestion variable and load next question?
Make 'questions' an Array (not an Object)
Get all the questions at the start
The computed value 'question' will watch on a change on 'currentQuestion' automatically and update the value accordingly
const app = new Vue({
el: '#app',
data: {
currentQuestion: 0,
questions: [],
},
mounted() {
axios.get('/questions').then((response) => {
// console.log(response.data[this.currentQuestion]);
this.questions = response.data
})
},
methods: {
next () {
this.currentQuestion += 1
}
},
computed: {
question () {
return this.questions.length ? this.questions[this.currentQuestion] : {}
}
}
})
Depends on how many questions you have, but you could just fetch all question with a request on load, and store them in a questions: {} object declared in your data. And on click just fetch the question directly from the object. Code example below:
var app = new Vue({
el:"#app",
data:{
currentQuestion:0,
questions:{},
question:{}
},
methods:{
next:function(){
this.loadNextQuest();
this.currentQuestion+=1;
} ,
loadQuest:function(){
axios.get('/questions').then((response)=>{
//console.log(response.data[this.currentQuestion]);
this.questions = response.data;
})
},
loadNextQuest:function(){
this.question = this.questions[this.currentQuestion];
}
},
mounted(){
this.loadQuest();
},
});
I am trying to fetch data from the server using Vue + Vuex + Vue resource.On button click I want to hit Http request and show in list format .I tried like that.Here is my code
https://plnkr.co/edit/EAaEekLtoiGPvxkmAtrt?p=preview
// Code goes here
var store = new Vuex.Store({
state: {
Item: []
},
mutations: {
getItems: function (state) {
}
},
actions: {
fetchData:function (context) {
this.$http.get('/data.json', function(v1users)
{
// this.$set('v1_user',v1users);
});
}
}
})
var httprequest = Vue.extend({
"template": '#http_template',
data: function () {
return {
items: store.state.Item
}
},
methods: {
fetchData: function () {
store.dispatch('fetchData')
},
}
})
Vue.component('httprequest', httprequest);
var app = new Vue({
el: '#App',
data: {},
})
;
any udpdate?
Try using Vue.http.get instead of this.$http.get.
Vuex doesn't have access to $http directly from instance.
How can I call the test vue in javascript? Here is my code, I want to call test when I do something in javascript function.
function clickit() {
this.test.fetchTestData();
}
var test = new Vue({
el: '#viewport',
data: {
test_data: []
},
mounted: function () {
this.fetchTestData();
},
methods: {
fetchTestData: function () {
$.get(test.json, function (data) {
this.test_data = data;
alert(this.test_data.isActive);
});
}
}
});
You are attempting to use this inside clickit() where this refers to window, so you just need to remove this and it should call the method inside the view model:
function clickit() {
test.fetchTestData();
}
If you compile this code with 'vue-cli-service build' the variable 'test' will not be defined, but you can make it visible to javascript in the mounted function:
new Vue({
el: '#viewport',
data: {
test_data: []
},
mounted: function () {
window.test=this;
},
methods: {
fetchTestData: function () {
$.get(test.json, function (data) {
this.test_data = data;
alert(this.test_data.isActive);
});
}
}
});
Then you can call it from javascript:
function clickit() {
window.test.fetchTestData();
}
Another way to call VueJs method using external java-script.
Firstly we should create a file. name event.js
import Vue from 'vue';
export default new Vue({
data: {
}
});
After that we should import that event.js to our component
import Event from "../event.js";
Then we can emit an event on our javascript function like below
function yourJavascriptFunction(){
Event.$emit("fetchdata");
}
In your component, mounted property should be like below:
mounted() {
Event.$on("fetchdata", group => {
this.fetchData();
});
},
methods() {
async fetchData() {
console.log('hoooray :)');
}
},