我需要捕获哪个事件才能在使用 Vue 鼠标按下时捕获鼠标移动

Which event do I need to capture to catching a mouse move while mousedown with Vue

我正在使用 Vue3 构建一个带有自上而下地图的 2D 游戏。我创建了一个简单的地图编辑器,您可以在其中将每个图块从一个集合拖到地图上。对于大地图来说,这会变得非常麻烦,因此我想尝试另一种方式。我的想法就像一个绘图工具,你select把“画笔”拖到“canvas”上。唯一的问题是,地图是由 div 排列成矩阵的图块构建的。我尝试了以下方法,但由于某种原因绘图被延迟并且它在其他图块上生成“工件”(我开始拖动图块 20:4 但图块 15:2 也更新了。

<div class="tiles">
    <div v-for="(row, y) in tiles" class="row"
        :key="'row_' + y"
        :style="{width: mapSize.x + 'px'}">
        <div v-for="(tile, x) in row" class="tile"
            :class="tile.background"
            :key="'tile_' + x + '_' + y"
            @dragover.prevent
            @dragenter="onDragEnter(x, y)">
        </div>
    </div>
</div>

我没有可拖动的元素,也许这就是问题所在,但我还可以使用什么其他事件来进行点击移动?

我建议您使用 mousedownmousemovemouseup 以及它们的触摸 semi-equivalents(如果使用触摸设备)。

这是一个示例,代码中有注释。

const colors = ["powderblue","gold","orangered","deeppink", "deepskyblue","palegreen"];

const generateTiles = (wx, wy) => {
  const ret = [];
  for (let y = 0; y < wy; y++) {
    const row = [];
    ret.push(row)
    for (let x = 0; x < wx; x++) {
      row.push({x,y,background: colors[0]})
    }
  }
  return ret;
}

Vue.createApp({
  el: '#app',
  setup() {
    const tiles = Vue.reactive(generateTiles(10,10)); // setup tiles and make reactive
    const color = Vue.ref(1); // helper for managing color(s)
    let mouseDown = false; // no need to make reactive
    
    // do some stuff to the tile here
    const setTileBg = (tile) => {
        tile.background=colors[color.value];
    }
    
    const handlers = {
        // reuse handler, used both for parent and 
      onMouseDown: (tile) => {
        mouseDown = true;
        if(tile) setTileBg(tile);
      },
      onMouseUp: (e) => {
        mouseDown = false;
      },
      onMouseOver: (tile) => {
        if(mouseDown) setTileBg(tile);
      }
    }
    
    // adding it to window (instead of an element) allows
    // capturing mouseup event even when mouse is not within
    // the dom element
    window.addEventListener('mouseup', handlers.onMouseUp)
    

    return {
        tiles, color, colors, ...handlers
    }
  }
}).mount('#app')
.tiles,select{width:200px;margin:0 auto;display:block}.tile{display:inline-block;width:20px;height:20px;border:1px solid #000;box-sizing:border-box;font-size:10px;font-family:monospace;cursor:pointer;color:rgba(0,0,0,.4);text-align:center;padding:3px}.row{display:block;height:20px;width:200px;box-sizing:content-box;user-select:none}
<script src="https://unpkg.com/vue@3.0.2/dist/vue.global.prod.js"></script>
<div id="app">
  <div>
    <select v-model="color">
      <option :value="i" v-for="(c,i) in colors" :style="{'background-color':c}">{{c}}</option>
    </select>
  </div>
  
  <div class="tiles">
      <div v-for="(row, y) in tiles" class="row"
          :key="'row_' + y"
          >
          <div v-for="(tile, x) in row" class="tile"
              :style="{'background-color':tile.background}"
              :key="'tile_' + x + '_' + y"
              @mouseDown="onMouseDown(tile)"
              @mouseOver="onMouseOver(tile)">
              {{ y * row.length + x}}
          </div>
      </div>
  </div>
</div>