在Vue.js中,我有一个像这样的组件(答案组件):
<template>
<a class="quiz-input-choice" :class="{'quiz-input-choice--selected': answer.selected}"
@click="toggleSelect()" :selected="answer.selected">
<img :src="answer.image_path"/>
<p class="quiz-input-choice__description">{{answer.title}}</p>
</a>
</template>
<script>
export default {
props: ['answer'],
methods: {
toggleSelect() {
this.$parent.$emit('answer-selected', this.answer.id);
}
}
}
</script>
如果在父母(问题组件)中,我更新&#34;选择&#34;该元素的属性,不会重新呈现此组件。
export default {
props: ['question'],
components: {QuizAnswer},
created: function () {
let _self = this;
this.$on('answer-selected', id => {
let i = _self.question.answers.map(item => item.id).indexOf(id);
let answer = _self.question.answers[i];
answer.selected = !answer.selected;
});
}
}
在Vue Developer Console中,我检查了答案组件数据是否已更新,因此答案被标记为已选中。无论如何,不会使用&#34; quiz-input-choice - selected&#34;类。
奇怪的是,如果我从道具的父级其他属性更新(例如(answer.title)),那么子组件也会正确呈现,并且类别为#34; quiz-input-choice - selected&# 34 ;. 所以我想这是一个检测孩子变化的问题。
答案 0 :(得分:1)
谢谢大家的答案。
我发现了这个问题。答案的“selected”属性不存在于初始对象中,因此Vue无法使该属性具有反应性。 https://vuejs.org/v2/guide/reactivity.html
我解决了在父组件中反应该属性的问题。
created() {
let self = this;
this.question.answers.forEach(function (answer) {
self.$set(answer, 'selected', false);
});
},
答案 1 :(得分:0)
我认为你在这里有结构性问题。您不应该向父母提交活动,因为该组件应该是自包含的。
然而,您可以做的是在子组件中发出一个事件(答案),该事件将在父组件中被捕获(问题)。
Answer.vue
<template>
<a class="quiz-input-choice" :class="{'quiz-input-choice--selected': answer.selected}"
@click="toggleSelect()" :selected="answer.selected">
<img :src="answer.image_path"/>
<p class="quiz-input-choice__description">{{answer.title}}</p>
</a>
</template>
<script>
export default {
props: ['answer'],
methods: {
toggleSelect() {
this.$emit('answer-selected');
}
}
}
</script>
Question.vue
你的模板会像这样捕捉到这样的事件(我不知道你的答案在哪里,所以我假设你有一个answers
数组):
<answer
v-for="(answer, index) in answers"
:answer="answer"
@answer-selected="answerSelected(index)"
></answer>
您的脚本将如下所示:
export default {
props: ['question'],
components: {QuizAnswer},
data() {
return {
answers: [],
selectedAnswer: -1,
};
},
watch: {
selectedAnswer(newIndex, oldIndex) {
if (oldIndex > -1 && this.answers.length > oldIndex) {
// Reset old value
this.answers[oldIndex].selected = false;
}
if (newIndex > -1 && this.answers.length > newIndex) {
// Set new value
this.answers[newIndex].selected = true;
}
},
},
methods: {
answerSelected(index) {
this.selectedAnswer = index;
},
},
};