vuejs - 如何使用点击事件追加html

时间:2018-04-18 15:06:33

标签: javascript jquery vue.js vuejs2

我尝试在安装组件时附加一些带有click事件的按钮:

      data() {
          return {
            show_word: true, 
            game: {
              //type: "memory, working memory",
              type: 1,
              name: "Symbols",
              start:false,
              total_combo: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)

        },
}

这是我得到的HTML:

<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>

问题在于&#34;点击&#34;事件不起作用。好像是&#34; checkNumbers&#34;函数不是注册,虽然它在我的方法中注册。

使用注册事件追加html元素的正确方法是什么?

谢谢!

1 个答案:

答案 0 :(得分:4)

不要直接操纵DOM,这就是你首先使用Vue的原因。使用v-fordata()的组合来操纵状态并让Vue填充DOM。

在直接DOM操作中添加@click=""将导致元素不被Vue管理,换句话说它将不具有Vue上下文。

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",
  components: {
    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.net/npm/vue@2.5.16/dist/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/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>