Home > Software engineering >  Vue computed value as data property value
Vue computed value as data property value

Time:02-25

Simplified example component code:

<template>
  <section>
    <div>{{ z }}</div>
    <div>{{ compZ }}</div>
    <div>{{ x }}</div>
  </section>
</template>

<script>
export default {
  name: "example",
  data: () => ({
    z: false,
    x: [{ visible: null }]
  }),
  mounted() {
    this.x[0].visible = this.compZ;
    setTimeout(() => (this.z = true), 1e3);
  },
  computed: {
    compZ() {
      return this.z;
    }
  }
};
</script>

After a second results are:

true
true
[ { "visible": false } ]

I need x[n].visible to change when compZ changes. Any ideas on how to cleanly keep reactivity? This is required, because i have 22 potential steps, that are visible depending on certain flags that can change after initialization.

CodePudding user response:

Found a workaround, but i think it's ugly:

<template>
  <section>
    <div>{{ refFlag1 }}</div>
    <div>{{ compRefFlag1 }}</div>
    <div>{{ x }}</div>
  </section>
</template>

<script>
export default {
  name: "example",
  data: () => ({
    refFlag1: false,
    refFlag2: false,
    x: [{ visible: null, visibleFunc: "that.compRefFlag1" }]
  }),
  watch: {
    allRelevatFlags: function () {
      setTimeout(() => this.updateVisible());
    }
  },
  mounted() {
    this.x[0].visible = this.compRefFlag1;
    setTimeout(() => (this.refFlag1 = true), 1e3);
  },
  methods: {
    updateVisible() {
      // eslint-disable-next-line no-unused-vars
      let that = this; // eval doesn't see 'this' scope
      this.x.forEach(step => (step.visible = eval(step.visibleFunc)));
    }
  },
  computed: {
    allRelevatFlags() {
      return `${this.compRefFlag1}${this.compRefFlag2}`;
    },
    compRefFlag1() {
      return this.refFlag1;
    },
    compRefFlag2() {
      return this.refFlag2;
    }
  }
};
</script>

Watch for changes in any relevant flag and then using JS eval() set the visible flag anew.

There's got to be a better way...

CodePudding user response:

You can add watcher for your z.

  watch: {
    z: function (newValue, oldValue) {
       // here you can change x.y
    }
  },
  • Related