我觉得我好像疯了。我已经在Firefox和Chrome中对它进行了测试,但都有这个问题,所以我不认为这是一个特定于浏览器的错误。
我有以下组件:
<template lang="pug">
#app
img(src="./assets/logo.png")
.titleArea(v-html="marked(question.title)")
#answer
answer-btn(v-for="(answer, index) in question.answers" :key="index" v-model="answer.selected" v-html="marked(answer.text)")
h3 {{ correct }}
</template>
<script>
import AnswerBtn from "./components/AnswerBtn.vue";
import marked from "marked";
export default {
data() {
return {
question: {
title: "# Question Title",
type: 2,
answers: [
{
text: "Option 0",
code: 0,
selected: false
},
{
text: "Option 1",
code: 1,
selected: false
}
]
}
};
},
computed: {
correct() {
window.abc = this.$children
let ok = false;
console.log("!!!!From Computed!!!!", this.$children, this.$children.length)
this.validate();
setTimeout(this.validate, 1)
return ok;
}
},
components: { AnswerBtn: {
template: "<button>Hi</button>"
} },
methods: {
marked,
validate() {
console.log("!!!!From Methods!!!!", this.$children, this.$children.length)
}
}
};
</script>
这将在app中生成两个AnswerBtn
,然后可以将其称为$this.children
,它被认为是一个正常的数组,可正确报告自己的长度。可悲的是,事实并非如此。
console.log
的调用顺序如下:
1:将调用console.log
内的correct()
2:console.log
内的validate()
将被调用(来自correct()
)
3:console.log
内的validate()
将在1小时后通过setTimeout
理论上,我认为在所有3种情况下输出都是相同的。但事实并非如此。这就是console.log输出的内容:
!!!!From Computed!!!! Array [] 0
!!!!From Methods!!!! Array [] 0
!!!!From Methods!!!! Array [ {…}, {…} ] 2
所以现在你可能会认为孩子们在计算出的函数执行后1ms内以某种方式放置,而不是片刻之前。这很合理,但是等等!还有更多!
在所有情况下,我们都可以观察到孩子们在哪里!对象内部的长度为2
。然而,除了最后一个孩子或长度之外,试图在所有情况下做任何事情都会导致精神错乱。
调用this.$children.splice(0)
返回一个空数组。 JSON.stringify(this.$children)
导致一个空数组,但是作为一个字符串。
我从未见过像这样的问题。请停下来。
答案 0 :(得分:0)
我想到了,部分原因。在计算组件之前计算计算值。
预期.length
与实际.length
之间不一致的原因是console.log是异步并按引用记录。
换句话说,我实际输出的内容看起来像这样
当孩子们空着时, console.log(children*, int<0>)
(指向children数组的指针和数字0)。反过来,在接下来的1ms内,孩子们只获得它的两个元素,之后浏览器获取子元素的值并发现它是一个包含两个元素的数组。