Vue 3:附加到子组件道具

Vue 3: Append to child component prop

我正在创建一个小益智游戏来学习 Vue 3,但在尝试将值附加到子组件中的数组时卡住了。

这是父级:

<template>
  <div class="home">
    <Puzzle :guess="puzzleGuess" />
  </div>
</template>

这是子组件'Puzzle':

<template>
    <div>
        <div class="row">
            <img :src="require(`@/assets/${imgPath}`)" alt="Puzzle image" class="puzzleImage" >
        </div>
        <div class="row puzzleIcon" :key="i" v-for="(char, i) in word">
            <span v-if="hasGuessedChar(char)">{{char}}</span>
            <span v-else>
                <i class="large material-icons">remove</i>
            </span>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'Puzzle',
        props: {
            word: Array,
            imgPath: String,
            guess: Array,
        },
        methods: {
            hasGuessedChar(char) {
                if(char == '') return false;

                if(this.guess.indexOf(char) > -1) return true;
           
                return false;
            }
        }
    }    
</script>

基本上,每当在父组件中更新 prop puzzleGuess 时,我想将一个字符推送到子组件的 guess 数组 属性。使用当前发布的代码,我只是继续覆盖 guess 变量而不是附加到它。

首先,你必须知道guesspuzzleGuess是一样的。 所以在子组件中push或者watch它在大多数情况下会导致死循环错误。

如果您希望仅在父组件中发生事件时添加 char,解决方案是在子组件中创建本地数据:loaclGuess。 在加载时用 guess 填充它并为 guess.

设置观察者

但在子组件中试试这个

data() {
   return {
      loaclGuess: this.guess
   }
}

然后

pushCharToGuess(char) {

    if(char == '') return false;

    // Important has to stop it to avoid empty loop 
    if(!this. loaclGuess.includes(char)) return true;

    // Push char
    this.loaclGuess.push(char);
}

受到@MohKoma 建议答案的启发,我得出了这个解决方案(不确定它是否与@Mohkoma 建议的相同):

父组件:

<template>
  <div class="home">
    <Puzzle :guess="puzzleGuess" />
    <hr />
    <div class="letters-container">
        <Letters @clickLetter="clickLetter" />
    </div>
  </div>
</template>

<script>      
export default {
  name: 'Home',
  components: {
    Letters,
    Puzzle
  },
  data() {
    return{          
      puzzleGuess: []
    }
  },
  methods: {
    clickLetter(letter) {
      this.puzzleGuess.push(letter.val.toLowerCase());
    }
  }
}
</script>

...子组件保持不变:

<template>
    <div>
        <div class="row puzzleIcon" :key="i" v-for="(char, i) in word">
            <span v-if="hasGuessedChar(char)">{{char}}</span>
            <span v-else>
                <i class="large material-icons">remove</i>
            </span>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'Puzzle',
        props: {
            word: Array,
            guess: Array,
        },
        methods: {
            hasGuessedChar(char) {
                if(char == '') return false;

                if(this.guess.indexOf(char) > -1) return true;
                
                return false;
            }
        }
    }    
</script>

所以基本上,我没有尝试将值推送到子组件中的数组,而是将该值推送到本地数组,然后将该数组向下传递给子组件