计算属性为$ children

时间:2018-01-16 01:26:56

标签: javascript arrays webpack vue.js

我觉得我好像疯了。我已经在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内以某种方式放置,而不是片刻之前。这很合理,但是等等!还有更多!

WTF WTF

在所有情况下,我们都可以观察到孩子们在哪里!对象内部的长度为2。然而,除了最后一个孩子或长度之外,试图在所有情况下做任何事情都会导致精神错乱。

调用this.$children.splice(0)返回一个空数组。 JSON.stringify(this.$children)导致一个空数组,但是作为一个字符串。

我从未见过像这样的问题。请停下来。

1 个答案:

答案 0 :(得分:0)

我想到了,部分原因。在计算组件之前计算计算值。

预期.length与实际.length之间不一致的原因是console.log是异步并按引用记录。

换句话说,我实际输出的内容看起来像这样

当孩子们空着时,

console.log(children*, int<0>)(指向children数组的指针和数字0)。反过来,在接下来的1ms内,孩子们只获得它的两个元素,之后浏览器获取子元素的值并发现它是一个包含两个元素的数组。