Как я могу создать вычисляемый массив в Vue, а затем отобразить его, используя v-if all при использовании v-модели в вычисляемом массиве? - PullRequest
0 голосов
/ 14 февраля 2020

Я пытался создать вычисляемый массив, который затем рендерил с использованием v-if. Но это также должно работать с v-моделью. Причина, по которой ей нужна v-модель, заключается в том, что она является частью перетаскиваемого списка, использующего vuedraggable.

В настоящее время я получаю следующую ошибку Computed property "list" was assigned to but it has no setter.

Следующий код - это мой компонент перетаскивания. vue :

<template>
  <div>
    <draggable
      v-model="list"
      v-bind="dragOptions"
      class="bigger-area"
      @start="isDragging=true"
      @end="isDragging=false"
    >
      <transition-group name="flip-list" type="transition">
        <li
          v-for="text in list"
          :key="text"
          id="list1"
          class="drag-item flex flex-justify-betweeen"
        >{{ text }}</li>
      </transition-group>
    </draggable>
  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  name: "Drag",
  data() {
    return {
      test: [],
      lists: [
        {
          title: "0-6 months",
          correctlyOrderedList: [
            "Lifting Head",
            "Rolling",
            "Sitting (with support)"
          ]
        },
        {
          title: "6-12 months",
          correctlyOrderedList: [
            "Crawling on stomach",
            "Sitting (without support)",
            "Stands with support and walks holding on",
            "Rolls a ball"
          ]
        },
        {
          title: "12-18 months",
          correctlyOrderedList: ["Crawling", "Walks alone"]
        },
        {
          title: "18 months – 2 years",
          correctlyOrderedList: [
            "Walks smoothly and turns corners",
            "Walks upstairs with support",
            "Begins running"
          ]
        },
        {
          title: "2-3 years",
          correctlyOrderedList: [
            "Walks upstairs without support",
            "Runs safely",
            "Catches using body and arms"
          ]
        },
        {
          title: "3-4 years",
          correctlyOrderedList: ["Kicks a ball forwards", "Can hop on one foot"]
        },
        {
          title: "4-5 years",
          correctlyOrderedList: [
            "Catches using only their hands",
            "Can skip following a demonstration"
          ]
        }
      ]
    };
  },
  components: {
    draggable
  },
  methods: {
    fullArrayMethod() {
      //Puts all statements into single array
      let i;
      let v;
      let fullArrayInOrder = [];
      for (i = 0; i < this.lists.length; i++) {
        for (v = 0; v < this.lists[i].correctlyOrderedList.length; v++) {
          fullArrayInOrder.push(this.lists[i].correctlyOrderedList[v]);
        }
      }
      return fullArrayInOrder;
    },
    disorderedArrayMethod() {
      //Randomizes array
      let fullArrayInOrder = this.fullArrayMethod();
      var copy = [],
        n = fullArrayInOrder.length,
        i;
      // While there remain elements to shuffle…
      while (n) {
        // Pick a remaining element…
        i = Math.floor(Math.random() * fullArrayInOrder.length);

        // If not already shuffled, move it to the new array.
        if (i in fullArrayInOrder) {
          copy.push(fullArrayInOrder[i]);
          delete fullArrayInOrder[i];
          n--;
        }
      }
      return copy;
    },
    chunk(array, size) {
      const chunked_arr = [];
      let index = 0;
      while (index < array.length) {
        chunked_arr.push(array.slice(index, size + index));
        index += size;
      }
      return chunked_arr;
    },
    splitArrayFinalProduct() {
      let disorderedArray = this.disorderedArrayMethod();
      let finalArray = this.chunk(disorderedArray, 3);
      return finalArray;
    }
  },
  computed: {
    dragOptions() {
      return {
        animation: 0,
        group: "shared",
        disabled: false,
        ghostClass: "ghost"
      };
    },
    list() {
      return this.disorderedArrayMethod();
    }
  }
};
</script>

Контекст : я пытаюсь создать приложение, объединяющее несколько массивов в один. Рандомизирует массив. Затем пользователь может привести его в порядок и посмотреть, правильно ли он понял.

1 Ответ

0 голосов
/ 17 февраля 2020

Для тех, кто может найти это полезным, это то, что работает для меня. Я не могу объяснить, почему все работает, поэтому надеюсь, что кто-нибудь умнее меня сможет это разработать.

Чтобы заставить переменную вычисляемого массива работать с v-моделью и v-for, я использовал map() как показано ниже:

let completeListOfStatements = this.lists.map(
d => d.correctlyOrderedList
);

Насколько я понимаю, map() возвращает массив.

Затем в v-модели я установил его в массив, который находится внутри объекта. Это тот самый, на котором я использовал map(). Это можно увидеть ниже.

<draggable
   v-model="lists.correctlyOrderedList"
   v-bind="dragOptions"
   class="list-group"
   @start="isDragging=true"
   @end="isDragging=false"
>

Для сравнения с кодом в моем вопросе вот весь код компонента:

<template>
  <div class="draggable-list-container">
    <div
      class="draggable-list-inner-container"
      v-for="(statement, index) in splitCompleteListOfStatements"
      :key="index"
    >
      <h1>{{ lists[index].title }}</h1>
      <draggable
        v-model="lists.correctlyOrderedList"
        v-bind="dragOptions"
        class="list-group"
        @start="isDragging=true"
        @end="isDragging=false"
      >
        <transition-group name="flip-list" type="transition">
          <li
            v-for="(statement, index) in statement"
            :key="index + 'index'"
            class="drag-item flex flex-justify-betweeen"
          >{{ statement }}</li>
        </transition-group>
      </draggable>
    </div>
    <div class="submit-button-container">
      <button class="btn" @click="revealAnswers">Reveal answers</button>
    </div>
  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  name: "Drag",
  data() {
    return {
      lists: [
        {
          title: "0-6 months",
          correctlyOrderedList: [
            "Lifting Head",
            "Rolling",
            "Sitting (with support)"
          ]
        },
        {
          title: "6-12 months",
          correctlyOrderedList: [
            "Crawling on stomach",
            "Sitting (without support)",
            "Stands with support and walks holding on",
            "Rolls a ball"
          ]
        },
        {
          title: "12-18 months",
          correctlyOrderedList: ["Crawling", "Walks alone"]
        },
        {
          title: "18 months – 2 years",
          correctlyOrderedList: [
            "Walks smoothly and turns corners",
            "Walks upstairs with support",
            "Begins running"
          ]
        },
        {
          title: "2-3 years",
          correctlyOrderedList: [
            "Walks upstairs without support",
            "Runs safely",
            "Catches using body and arms"
          ]
        },
        {
          title: "3-4 years",
          correctlyOrderedList: ["Kicks a ball forwards", "Can hop on one foot"]
        },
        {
          title: "4-5 years",
          correctlyOrderedList: [
            "Catches using only their hands",
            "Can skip following a demonstration"
          ]
        }
      ]
    };
  },
  components: {
    draggable
  },
  methods: {
    disorderedArrayMethod(value) {
      //Randomizes array
      let fullArrayInOrder = value;
      var copy = [],
        n = fullArrayInOrder.length,
        i;
      // While there remain elements to shuffle…
      while (n) {
        // Pick a remaining element…
        i = Math.floor(Math.random() * fullArrayInOrder.length);

        // If not already shuffled, move it to the new array.
        if (i in fullArrayInOrder) {
          copy.push(fullArrayInOrder[i]);
          delete fullArrayInOrder[i];
          n--;
        }
      }
      return copy;
    },
    revealAnswers() {this.splitCompleteListOfStatements[0].push("Hello")}
  },
  computed: {
    dragOptions() {
      return {
        animation: 0,
        group: "shared",
        disabled: false,
        ghostClass: "ghost"
      };
    },
    splitCompleteListOfStatements() {
      let completeListOfStatements = this.lists.map(
        //Maps out full array (Basically loops through gathers the arrays and creates an array from them)
        d => d.correctlyOrderedList
      );
      completeListOfStatements = completeListOfStatements.reduce(function(
        //The map returns an array as the following [[a,b], [], []] etc. So this turns it into [a,b,c,d]
        a,
        b
      ) {
        return a.concat(b);
      }, []);
      completeListOfStatements = this.disorderedArrayMethod(
        completeListOfStatements
      ); //This sends it to a method that jumbles the array

      var temp = [];
      var preVal = 0;
      var nextVal = 3;
      for (var i = 0; i < 7; i++) {
        temp.push(completeListOfStatements.slice(preVal, nextVal));
        preVal = nextVal;
        nextVal = nextVal + 3;
      }
      return temp;
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.title {
  margin-bottom: 0.5em;
}
.submit-button-container {
  margin-top: 5px;
}
.btn {
  width: 10em;
  height: 5em;
}
.draggable-list-container {
  display: inline-block;
  justify-content: center;
  min-height: 200px;
}
.list-group {
  min-height: 80px;
}
.drag-item {
  justify-content: center;
  padding: 15px 10px;
  background-color: whitesmoke;
  border: 1px solid black;
  width: 20em;
  margin: 2px;
  cursor: move;
}
.list-group-item {
  position: relative;
  display: block;
  padding: 0.75rem 1.25rem;
  margin-bottom: -1px;
  background-color: #fff;
  border: 1px solid rgba(0, 0, 0, 0.125);
}
.flip-list-move {
  transition: transform 0.5s;
}
.no-move {
  transition: transform 0s;
}
.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}
.list-group-item {
  cursor: move;
}
</style>
...