pythonNovice
pythonNovice

Reputation: 1431

Vue child component not re-rendering on data change

Trying to update a child component on parent state change. When I change the date state in Day.vue I can see that the computed function is working but the <EntryList> component is not updating with the new date I pass in.

Day.vue

<template>
  <div id="daily">
    <div id="nav">
      <div class="nav">
        <button @click="changeDay(-1)" class="arrow">←</button>
        <h5 class="dayTitle" style="background-color: initial">
          {{ dayTitle }}
        </h5>
        <button @click="changeDay(1)" class="arrow">→</button>
      </div>
    </div>
    <div class="dayDiv">
      <div class="details">
        <!-- We use v-bind to attach state item to component--->
        <EntryList v-bind:listDate="date" />
      </div>
    </div>
  </div>
</template>

<script>
import EntryList from "./EntryList";

export default {
  components: {
    EntryList,
  },
  data() {
    return {
      date: "",
    };
  },
  created() {
    this.date = new Date();
  },
  methods: {
    // Change Date here
    changeDay(amount) {
      let changeDate = new Date(this.date); // had to do this because computed couldn't see that it was updating
      changeDate.setDate(this.date.getDate() + amount);
      this.date = changeDate;
      console.log("Date Changed");
    },
  },

  computed: {
    dayTitle() {
      let options = { weekday: "short" };
      return `${this.date.toLocaleString(
        undefined,
        options
      )} ${this.date.toLocaleDateString()}`;
    },
  },
};
</script>

EntryList.vue

<template>
  <div>
    <ul>
      <Entry v-for="entry in entries" v-bind:entry="entry" :key="entry.id" />
    </ul>
    <button :value="dateStamp" class="add">+</button>
  </div>
</template>

<style lang="scss">
</style>

<script>
import Entry from "./Entry";
export default {
  components: {
    Entry,
  },
  // Eventually pass in props for styling component
  props: {
    listDate: {
      type: Date,
      required: true,
    },
  },
  data() {
    return {
      entries: [],
    };
  },
  created() {
    // We do this to get the entries for the date
    console.log("Render List");
    let dateStamp = this.listDate.toLocaleDateString();
    chrome.storage.sync.get([dateStamp], (result) => {
      this.entries = Object.values(result[dateStamp]);
    });
  },
  computed: {
    dateStamp() {
      return this.listDate.toLocaleDateString();
    },
  },
};
</script>

Upvotes: 0

Views: 1382

Answers (1)

Alan Millirud
Alan Millirud

Reputation: 1192

your entries array fills once on created event. You should move logic from created function, to computed property or use watcher

like this

watch: {
  listDate (newValue) {
    console.log("Render List");
    let dateStamp = this.listDate.toLocaleDateString();
    chrome.storage.sync.get([dateStamp], (result) => {
      this.entries = Object.values(result[dateStamp]);
    });
  }
}

Upvotes: 1

Related Questions