I try to append a couple of buttons with click event when the ponent is mounted:
data() {
return {
show_word: true,
game: {
//type: "memory, working memory",
type: 1,
name: "Symbols",
start:false,
total_bo:0,
total_correct:0,
total_incorrect:0,
total_correct_in_a_row:0,
max_correct_in_a_row:0,
correct_percent:0,
avg_time_for_ans:0,
button: '<button @click="checkNumbers">click</button>',
score_plus:0,
score_multi:0,
d_timer:600,
finish:false,
positive: null,
negative: null,
numbers_array:[],
abuse: {
clicks:5,
seconds:1,
max:3,
flag: false
}
},
}
},
methods:{
playGame(){
let tilesize = 50, tilecount = 6;
$( '#numbersContainer' ).empty()
let gRows = Math.floor($("#numbersContainer").innerWidth()/tilesize);
let gCols = Math.floor($('#numbersContainer').innerHeight()/tilesize);
let vals = _.shuffle(_.range(tilecount));
let xpos = _.shuffle(_.range(gRows));
let ypos = _.shuffle(_.range(gCols));
console.log(vals);
console.log(xpos);
console.log(ypos);
let $this = this;
_.each(vals, function(d,i){
var $newdiv = $('<button @click="checkNumbers('+(d+1)+')"/>').addClass("tile btn btn-info");
$this.game.numbers_array.push(d+1)
$newdiv.css({
'position':'absolute',
'left':(xpos[i] * tilesize)+'px',
'top':(ypos[i] * tilesize)+'px'
}).appendTo( '#numbersContainer' ).html(d+1);
});
},
checkNumbers($val){
console.log($val)
},
}
This is the html that i getting:
<div id="numbersContainer" class="col-ms-3">
<button @click="checkNumbers(6)" class="tile btn btn-info" style="position: absolute; left: 250px; top: 250px;">6</button>
<button @click="checkNumbers(5)" class="tile btn btn-info" style="position: absolute; left: 150px; top: 150px;">5</button>
<button @click="checkNumbers(1)" class="tile btn btn-info" style="position: absolute; left: 100px; top: 0px;">1</button>
<button @click="checkNumbers(3)" class="tile btn btn-info" style="position: absolute; left: 50px; top: 100px;">3</button>
<button @click="checkNumbers(2)" class="tile btn btn-info" style="position: absolute; left: 200px; top: 200px;">2</button>
<button @click="checkNumbers(4)" class="tile btn btn-info" style="position: absolute; left: 0px; top: 50px;">4</button>
</div>
The problems is that the "click" event is not working. Seems like the "checkNumbers" function is not register, although it registered in my methods.
What is the right way to append html element with register events?
Thank !
I try to append a couple of buttons with click event when the ponent is mounted:
data() {
return {
show_word: true,
game: {
//type: "memory, working memory",
type: 1,
name: "Symbols",
start:false,
total_bo:0,
total_correct:0,
total_incorrect:0,
total_correct_in_a_row:0,
max_correct_in_a_row:0,
correct_percent:0,
avg_time_for_ans:0,
button: '<button @click="checkNumbers">click</button>',
score_plus:0,
score_multi:0,
d_timer:600,
finish:false,
positive: null,
negative: null,
numbers_array:[],
abuse: {
clicks:5,
seconds:1,
max:3,
flag: false
}
},
}
},
methods:{
playGame(){
let tilesize = 50, tilecount = 6;
$( '#numbersContainer' ).empty()
let gRows = Math.floor($("#numbersContainer").innerWidth()/tilesize);
let gCols = Math.floor($('#numbersContainer').innerHeight()/tilesize);
let vals = _.shuffle(_.range(tilecount));
let xpos = _.shuffle(_.range(gRows));
let ypos = _.shuffle(_.range(gCols));
console.log(vals);
console.log(xpos);
console.log(ypos);
let $this = this;
_.each(vals, function(d,i){
var $newdiv = $('<button @click="checkNumbers('+(d+1)+')"/>').addClass("tile btn btn-info");
$this.game.numbers_array.push(d+1)
$newdiv.css({
'position':'absolute',
'left':(xpos[i] * tilesize)+'px',
'top':(ypos[i] * tilesize)+'px'
}).appendTo( '#numbersContainer' ).html(d+1);
});
},
checkNumbers($val){
console.log($val)
},
}
This is the html that i getting:
<div id="numbersContainer" class="col-ms-3">
<button @click="checkNumbers(6)" class="tile btn btn-info" style="position: absolute; left: 250px; top: 250px;">6</button>
<button @click="checkNumbers(5)" class="tile btn btn-info" style="position: absolute; left: 150px; top: 150px;">5</button>
<button @click="checkNumbers(1)" class="tile btn btn-info" style="position: absolute; left: 100px; top: 0px;">1</button>
<button @click="checkNumbers(3)" class="tile btn btn-info" style="position: absolute; left: 50px; top: 100px;">3</button>
<button @click="checkNumbers(2)" class="tile btn btn-info" style="position: absolute; left: 200px; top: 200px;">2</button>
<button @click="checkNumbers(4)" class="tile btn btn-info" style="position: absolute; left: 0px; top: 50px;">4</button>
</div>
The problems is that the "click" event is not working. Seems like the "checkNumbers" function is not register, although it registered in my methods.
What is the right way to append html element with register events?
Thank !
Share Improve this question edited Apr 18, 2018 at 15:16 Dani Banai asked Apr 18, 2018 at 15:06 Dani BanaiDani Banai 1,1404 gold badges15 silver badges34 bronze badges 2-
3
You really don't want to be manipulating the DOM directly. You should change the data and let Vue update the DOM for you. Can you show your
data
declaration? – acdcjunior Commented Apr 18, 2018 at 15:11 - @acdcjunior - i added the data declaration – Dani Banai Commented Apr 18, 2018 at 15:16
1 Answer
Reset to default 4Don't manipulate the DOM directly, that's why you're using Vue in the first place. Use a bination of v-for
and data()
to manipulate state and have Vue populate the DOM.
Adding the @click=""
within the direct DOM manipulation is going to cause the element to not be managed by Vue, in other words it won't have the Vue context.
const Game = {
props: ["tilecount"],
data() {
return {
tiles: []
};
},
mounted() {
this.tiles = _.shuffle(_.range(this.tilecount));
},
methods: {
checkNumbers(val) {
console.log(val);
}
}
};
const app = new Vue({
el: "#app",
ponents: {
game: Game
},
data() {
return {
tilecount: 50
};
}
});
.game .number-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
.game .number-container button {
flex-basis: 20%;
height: 50px
}
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<div id="app">
<game :tilecount="tilecount" inline-template>
<div class="game">
<div ref="numberContainer" class="number-container">
<button v-for="tile in tiles" @click="checkNumbers(tile)"> {{tile}}</button>
</div>
</div>
</game>
</div>