как слушать vue событий при обратном вызове с $ refs - PullRequest
2 голосов
/ 23 января 2020

строит игру ножницами из каменной бумаги и хочет, чтобы компьютер выбрал случайную руку. Все идет нормально. я хочу, чтобы компьютер запускался слушателем событий, таким как v-on:humanChoosedHand="startGame()", чтобы выбрать руку, КОГДА игрок / человек также выбрал руку. я могу проверить и увидеть, что событие humanChoosedHand запускается, когда я выбираю руку для человека, но родитель GameField.vue не слушает код выглядит так:

родитель GameField.vue

<template>
  <div id="game-field">
    <button class="btn btn-primary" @click="startGame()">Start</button>

    <div class="row">
      <div class="col-md-6 pt-5">
        <Human></Human>
      </div>
      <div class="col-md-6 pt-5">
        <Computer ref="computer" v-on:humanChoosedHand="startGame()"></Computer>
      </div>
    </div>
  </div>
</template>

<script>
import Human from './Human.vue'
import Computer from './Computer.vue'
export default {
  data: () => {
    return {
      score: [
        {
          human: 0
        },
        {
          computer: 0
        }
      ]
    }
  },
  components: {
    Human,
    Computer
  },
  props: {
    difficulty: String
  },
  methods: {
    startGame () {
      console.log('Game Started')
      // this.$refs.computer.shuffleAnimation()
      this.$refs.computer.setRandomHand() //<-----
      // listen to emit here, not in html template
    },
    testFunction () {
      console.log('test')
    }
  }
}
</script>

<style lang="scss">
#game-field {
  .far {
    cursor: pointer;
    font-size: 300px;
    width: 350px;
    height: 350px;
  }

  .row {
    margin: 0 0 0 0;

    .select-hand {
      position: relative;
      left: 60px;
      .far {
        font-size: 80px;
        height: 0;
        width: 0;
      }
      .far:hover {
        color: $orange;
      }
    }
  }

  .btn-primary {
    background-color: $orange;
    border-color: $orange;
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, 30%);
  }
  .btn-primary:focus {
    background-color: $orange;
    border-color: $black !important;
    box-shadow: 0 0 0 0.2rem rgba(255, 51, 0, 0.644);
  }
}
</style>

затем дочерний элемент Computer.vue:

<template>
  <div id="computer">
    <div class="text-center">
      <div class="h2 mb-5">Computer</div>
      <i class="far" :class="playIcon"></i>
      <div class="hand h3 mt-4">{{ activeHand }}</div>
    </div>
  </div>
</template>

<script>
export default {
  data: () => {
    return {
      winCounter: 0,
      activeHand: 'I am ready',
      playIcon: '',
      hands: [
        {
          name: 'Rock',
          strength: 'scissor',
          weakness: 'paper',
          icon: 'fa-hand-rock'
        },
        {
          name: 'Paper',
          strength: 'rock',
          weakness: 'scissor',
          icon: 'fa-hand-paper'
        },
        {
          name: 'Scissor',
          strength: 'paper',
          weakness: 'rock',
          icon: 'fa-hand-scissors'
        }
      ]
    };
  },
  methods: {
    setRandomHand() {
      // THIS SHOULD LISTEN TO THE 'humanChoosedHand' 
      // and should gets triggered by a 'ref.computer.setRandomHand' then
      console.log('computer listens');

      let choosedHand = Math.round(Math.random() * 2);
      this.activeHand = this.hands[choosedHand].name;
      this.playIcon = this.hands[choosedHand].icon;
      this.$emit('computerChoosedHand', this.activeHand.toLowerCase());
    }
    // shuffleAnimation () {
    //   setInterval(() => {
    //     let shuffle = Math.round(Math.random() * 2)
    //     this.activeHand = this.hands[shuffle].name
    //     this.playIcon = this.hands[shuffle].icon
    //   }, 100)
    // }
  }
};
</script>

<style lang="scss">
#computer .far {
  transform: rotate(-90deg);
}
</style>

другой дочерний элемент GameField - Human.vue

<template>
  <div id="human">
    <div class="text-center">
      <div class="h2 mb-5">Human</div>
      <i class="far" :class="playIcon"></i>
      <div class="h3 mt-4">{{ activeHand }}</div>
      <div class="row select-hand mt-4">
        <div class="col-md-4">
          <i class="far fa-hand-rock" @click="setHand(hands[0])"></i>
        </div>
        <div class="col-md-4">
          <i class="far fa-hand-paper" @click="setHand(hands[1])"></i>
        </div>
        <div class="col-md-4">
          <i class="far fa-hand-scissors" @click="setHand(hands[2])"></i>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data: () => {
    return {
      winCounter: 0,
      activeHand: 'Choose a Hand',
      playIcon: '',
      hands: [
        {
          name: 'Rock',
          strength: 'scissor',
          weakness: 'paper',
          icon: 'fa-hand-rock'
        },
        {
          name: 'Paper',
          strength: 'rock',
          weakness: 'scissor',
          icon: 'fa-hand-paper'
        },
        {
          name: 'Scissor',
          strength: 'paper',
          weakness: 'rock',
          icon: 'fa-hand-scissors'
        }
      ]
    }
  },
  methods: {
    setHand (hand) {
      this.activeHand = hand.name
      this.playIcon = hand.icon
      this.$emit('humanChoosedHand', this.activeHand.toLowerCase())
    }
  }
}
</script>

<style lang="scss">
#human .far {
  transform: rotate(90deg);
}
</style>

Возможно, невозможно прослушать событие, а затем $ref.component.callFunction()

1 Ответ

1 голос
/ 23 января 2020

Gamefield не прослушивает должным образом, так как в вашем теге отсутствует код. Вам нужно добавить @humanChoosedHand в ваш тег:

<Human @humanChoosedHand="triggerComputer"></Human>

, который теперь корректно прослушивает изменения humanChoosedHand

Теперь triggerComputer может запускать компьютерную функцию с Gamefield:

triggerComputer() {
  this.$refs.computer.setRandomHand();
}

, поэтому удалите v-on:humanChoosedHand="startGame()" из тега Computer.

Вот вам SANDBOX для игры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...