Что инициирует пересчет вычисляемого свойства в асинхронном c контексте? - PullRequest
1 голос
/ 21 января 2020

I fetch некоторые данные из файла JSON для обработки. Эта асинхронная операция (fetch), по-видимому, нарушает функциональность свойств computed().

Приведенный ниже код работает должным образом - данные не извлекаются, а жестко кодируются в mounted(). Когда вы запускаете код и смотрите на консоль, вы видите первое вычисление для filteredTags (пусто), затем allTags модифицируются, что вызывает вычисление filteredTags.

→ все как положено

new Vue({
  el: "#app",
  data: {
    posts: [],
    tags: {},
    allTags: {},
  },
  computed: {
    // provides an Array of tags which are selected
    filteredTags: function() {
      let t = Object.keys(this.allTags).filter(x => this.allTags[x])
      console.log("computed filteredtags: " + JSON.stringify(t))
      return t
    }
  },
  watch: {
  },
  mounted() {
    const r = '{"tag1":["/posts/premier/"],"post":["/posts/premier/","/posts/second/"]}'
    this.tags = JSON.parse(r)
    // bootstrap a tags reference where all the tags are selected
    Object.keys(this.tags).forEach(t => {
      this.$set(this.allTags, t, true)
      // this.allTags[t] = true
    });
    console.log("allTags in mounted: " + JSON.stringify(this.allTags))
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="tag in filteredTags">{{tag}}</div>
</div>

Теперь тот же код, но в случае, когда {"tag1":["/posts/premier/"],"post":["/posts/premier/","/posts/second/"]} извлекается через HTTP-вызов:

<div id="app">
    <div :click="allTags[tag]=!allTags[tag]" v-for="tag in filteredTags">{{tag}}</div>
</div>

<script>
new Vue({
    el: "#app",
    data: {
        posts: [],
        tags: {},
        allTags: {},
    },
    computed: {
        // provides an Array of tags which are selected
        filteredTags: function () {
            let t = Object.keys(this.allTags).filter(x => this.allTags[x])
            console.log("computed filteredtags: " + JSON.stringify(t))
            return t
        }
    },
    watch: {
    },
    mounted() {
        // get source tags
        fetch("tags.json")
        .then(r => r.json())
        .then(r => {
            this.tags = r
            // bootstrap a tags reference where all the tags are selected
            Object.keys(this.tags).forEach(t => {
                this.$set(this.allTags, t, true)
                // this.allTags[t] = true
            });
            console.log("allTags in mounted: "+ JSON.stringify(this.allTags))
        })
    }
})
</script>

Вывод Консоль:

computed filteredtags: []
allTags in mounted: {"tag1":true,"post":true}
computed filteredtags: ["tag1","post"]
computed filteredtags: []

Первые три строки в порядке. Почему в конце проводится дополнительный пересчет filteredtags? И что еще важнее - почему результат пуст?

...