变更阵列后,Vue不会从阵列中呈现v-for输入字段

时间:2019-02-04 16:18:12

标签: javascript vue.js

Vue组件在外部设置其值后将不会重新呈现数组项。声明状态,但v-for元素未显示更改。

我有一个从数组渲染项目的组件。我还具有用于更改数组长度的按钮,它可以很好地工作:“ +”添加一行,“-”删除最后一行。当我从获取方法设置数组数据时,问题就开始了。数据已显示,但“ +”和“-”按钮不起作用。

这是codesanbox https://codesandbox.io/s/q9jv524kvw

的链接

/App.vue

<template>
  <div id="app">
    <button @click="downloadTemplate">Load data</button>
    <HelloWorld :formData="formData" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  components: {
    HelloWorld
  },
  data() {
    return {
      fakeData: {
        unloadingContactPersons: [
          {
            id: this.idGen("unloadingContactPersons"),
            value: "123"
          },
          {
            id: this.idGen("unloadingContactPersons"),
            value: "1234"
          },
          {
            id: this.idGen("unloadingContactPersons"),
            value: "12345"
          }
        ]
      },
      lengthDependentLoadings: [
        "loadingDates",
        "loadingAddresses",
        "loadingContactPersons"
      ],
      lengthDependentUnloadings: [
        "unloadingDates",
        "unloadingAddresses",
        "unloadingContactPersons"
      ],
      formData: {
        unloadingContactPersons: [
          {
            id: this.idGen("unloadingContactPersons"),
            value: ""
          }
        ]
      }
    };
  },
  methods: {
    idGen(string = "") {
      // Math.random should be unique because of its seeding algorithm.
      // Convert it to base 36 (numbers + letters), and grab the first 9 characters
      // after the decimal.
      return (
        string +
        "_" +
        Math.random()
          .toString(36)
          .substr(2, 9)
      );
    },
    addLine(id) {
      console.log("id", id);
      const parentName = id.split("_")[0];

      const dependentArray = this.lengthDependentLoadings.includes(parentName)
        ? this.lengthDependentLoadings
        : this.lengthDependentUnloadings;

      dependentArray.forEach(objName => {
        this.formData[objName]
          ? this.formData[objName].push({
              id: this.idGen(objName),
              value: ""
            })
          : null;
      });

      console.log("--length", this.formData.unloadingContactPersons.length);
    },
    removeLine(id) {
      const parentName = id.split("_")[0];

      const dependentArray = this.lengthDependentLoadings.includes(parentName)
        ? this.lengthDependentLoadings
        : this.lengthDependentUnloadings;

      dependentArray.forEach(objName => {
        this.formData[objName] ? this.formData[objName].pop() : null;
      });

      console.log("--length", this.formData.unloadingContactPersons.length);
    },

    downloadTemplate(link) {
      // fake fetch request
      const getFunctionDummy = data =>
        new Promise(resolve => setTimeout(resolve.bind(null, data), 1500));

      // data setter

      getFunctionDummy(this.fakeData).then(result => {
        // set our data according to the template data
        const templateKeys = Object.keys(result);
        const templateData = result;
        this.formData = {};

        templateKeys.forEach((key, index) => {
          let value = templateData[key];
          console.log(value);

          if (Array.isArray(value)) {
            console.log("array", value);
            this.formData[key] = value.map((item, id) => {
              console.log("---from-template", item);
              return {
                id: this.idGen(key),
                value: item.value
              };
            });
          } else {
            this.formData[key] = {
              id: this.idGen(key),
              value
            };
          }
        });
      });
    }
  },
  mounted() {
    // takes id number of item to be added
    this.$root.$on("addLine", ({ value }) => {
      console.log("---from-mounted", value);
      this.addLine(value);
    });

    // takes id number of item to be removed
    this.$root.$on("removeLine", ({ value }) => {
      this.removeLine(value);
    });
  },

  beforeDestroy() {
    this.$root.$off("addLine");
    this.$root.$off("removeLine");
  }
};
</script>

/HelloWorld.vue

<template>
  <div class="hello">
    <div class="form-item">
      <div class="form-item__label">
        <label :for="formData.unloadingContactPersons"
          >Contact person on unload:</label
        >
      </div>
      <div class="form-item__input multiline__wrapper">
        <div
          class="multiline__container"
          @mouseover="handleMouseOver(unloadingContactPerson.id);"
          v-for="unloadingContactPerson in formData.unloadingContactPersons"
          :key="unloadingContactPerson.id"
        >
          <span
            class="hover-button hover-button__remove"
            @click="removeLine(unloadingContactPerson.id);"
            ><i class="fas fa-minus-circle fa-lg"></i>-</span
          >
          <input
            class="multiline__input"
            :id="unloadingContactPerson.id"
            type="text"
            v-model="unloadingContactPerson.value"
            @input="emitFormData"
          />
          <span
            class="hover-button hover-button__add"
            @click="addLine(unloadingContactPerson.id);"
            ><i class="fas fa-plus-circle fa-lg"></i>+</span
          >
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Datepicker from "vuejs-datepicker";
import { uk } from "vuejs-datepicker/dist/locale";

export default {
  name: "SubmitForm",
  components: {
    Datepicker
  },
  props: {
    formData: Object
  },
  data: () => {
    return {
      uk,
      hoveredItemId: null
    };
  },
  methods: {
    emitFormData() {
      this.$root.$emit("submitFormData", { value: this.formData });
    },
    handleMouseOver(id) {
      this.hoveredItemId = id;
    },
    addLine(id) {
      // console.log("---add", id);
      this.$root.$emit("addLine", {
        value: id
      });
    },
    removeLine(id) {
      // console.log("---remove", id);
      this.$root.$emit("removeLine", {
        value: id
      });
    }
  }
};
</script>

1 个答案:

答案 0 :(得分:1)

只需评论npm install npm ERR! Error while executing: npm ERR! /usr/bin/git ls-remote -h -t https://myprivategit.com/my/repo npm ERR! npm ERR! remote: HTTP Basic: Access denied npm ERR! fatal: Authentication failed for 'https://myprivategit.com/my/repo.git/' npm ERR! npm ERR! exited with error code: 128 中的line no 111,它就会起作用。

App.vue

问题是您直接突变了Vue.js无法检测到的// this.formData = {} 对象。进一步了解Array Change detection [List Rendering - Vue.js]