简体   繁体   中英

VueJs not rerendering after new element is added to an array

I have set a watcher to check if the dropdown value is equals to "select", if the value is equal then a new array "option" is created with one element in it. I have a button that will add a value to the array that the watcher created when the dropdown value is equal to select. The button function is working but the input field that should loop the array doesn't re-render after the button click. I am sorry I am terrible at explaining things. here is my code

<template lang="pug">
.formHolder
  .quest
    input(type="text" placeholder="Question" v-model="tempForm.tempQuestions[0].question")
    input(type="text" placeholder="Description" v-model="tempForm.tempQuestions[0].description")
    select(name="category" v-model="tempForm.tempQuestions[0].type")
      option(value="text") text
      option(value="select") Dropdown
      option(value="number") Number

this is the input field that will loop the array

    .option(v-for="(option, index) in tempForm.tempQuestions[0].options")
        input(type="text" placeholder="Option" v-model="tempForm.tempQuestions[0].options[index]")

this button adds a value to the array

    button(v-if="tempForm.tempQuestions[0].type === 'select'"  @click="addItems") Add Options   
</template>

<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";

export default {
  name: "HomeView",
  components: {
    HelloWorld,
  },
  data() {
    return {
      questions: 0,
      tempForm: {
        tempQuestions: [
          {
            question: null,
            description: null,
            type: null,
          },
        ],
      },
      form: {
        questions: [],
      },
    };
  },

  methods: {
    addQuestion() {
      this.tempForm.tempQuestions.push({
        question: null,
        description: null,
        type: null,
      });
      this.questions++;
      this.readerNos++;
    },
    addOptionArray() {
      this.tempForm.tempQuestions[0].options.push("");
    },
//////// this is the function
    addItems() {
      console.log(this.tempForm.tempQuestions[0].options);
      let length = this.tempForm.tempQuestions[0].options.length;
      console.log(length);
      this.$set(this.tempForm.tempQuestions[0].options, length, "");
    },
  },
  watch: {
    tempForm: {
      handler: function () {
        this.tempForm.tempQuestions.forEach((question) => {
          if (question.type === "select") {
            question.options = [];
            question.options.push("");
          } else if (question.type === "text") {
            if (question.options) {
              delete question.options;
            }
          } else if (question.type === "number") {
            if (question.options) {
              delete question.options;
            }
          }
        });
      },
      deep: true,
    },
  },
};
</script>

You should use Vue.$set() when adding an empty options array - otherwise it won't be reactive and there will be no rerendering of the options in the template:

watch: 
{
    tempForm: 
    {
      handler() 
      {
        this.tempForm.tempQuestions.forEach((question) => 
        {
          if (question.type === "select") 
          {
            this.$set(question, 'options', []);
            question.options.push("");
          } 
          else if (question.type === "text") 
          {
            if (question.options) 
            {
              question.options.splice();
            }
          } 
          else if (question.type === "number") 
          {
            if (question.options) 
            {
              question.options.splice();
            }
          }
        });
      },
      deep: true,
    },
  },

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM