Результаты не попадают на страницы для разбиения на страницы в vueJS

Я использую Bootstrap Vue, чтобы заставить работать разбиение на страницы на стороне клиента, при этом данные поступают из API отдыха. Пока страницы вычисляются, но результаты не отображаются на страницах, результаты отображаются снаружи и не разбиваются на страницы. Таким образом, страницы вычисляются, но результаты не на страницах. Пока что код компонента:

<template>
  <div class="container search">
    <div class="row">
      <div class="col-md-8">

 <div class="jumbotron mt-5" style="clear:both">
      <h1 class="display-4">{{title}}</h1>
      <p class="lead">{{intro}}</p>
      <hr class="my-4">
      <p v-if="validated" :class="errorTextClass">Enter a valid search term</p>

      <button
        type="button"
        class="btn btn-primary btn-lg mb-3"
        v-on:click="refreshPage"
        v-if="result.length > 1"
      >
        <font-awesome-icon icon="redo"/> Start again
      </button>
      <input
        class="form-control form-control-lg mb-3"
        type="search"
        placeholder="Search"
        aria-label="Search"
        v-model="search"
        required
        autocomplete="off"
        id="search"
      >
  <div class="overflow-auto">
    <b-pagination
      v-model="currentPage"
      :total-rows="rows"
      :per-page="perPage"
      aria-controls="my-table"
    ></b-pagination>

    <p class="mt-3">Current Page: {{ currentPage }}</p>

    <!-- <b-table
      id="my-table"
      :result="result"
      :per-page="perPage"
      :current-page="currentPage"
      small
    ></b-table> -->

     <div v-for="(result, index) in result" :key="index" :result="result"
      :perPage="0"
      :current-page="currentPage"
      small >
        <div class="media mb-4">
          <img
            :src="resizeArtworkUrl(result)"
            alt="Album Cover"
            class="album-cover align-self-start mr-3"
          >
          <div class="media-body">
            <h4 class="mt-0">
              <!-- <button
                type="button"
                class="btn btn-primary btn-lg mb-3 float-right"
                v-on:click="addItem(result)"
              >
                <font-awesome-icon icon="plus"/>
              </button>-->

              <button
                type="button"
                class="btn btn-primary btn-lg mb-3 float-right"
                v-on:click="addItem(result)"
                :disabled="result.disableButton"
              >

                <font-awesome-icon icon="plus"/>
              </button>

              <b>{{result.collectionName}}</b>
            </h4>
            <h6 class="mt-0">{{result.artistName}}</h6>
            <p class="mt-0">{{result.primaryGenreName}}</p>
          </div>
        </div>
      </div>

  </div>


      <div :class="loadingClass" v-if="loading"></div>

      <button
        class="btn btn-success btn-lg btn-block mb-3"
        type="submit"
        v-on:click="getData"
        v-if="result.length < 1"
      >
        <font-awesome-icon icon="search"/>Search
      </button>
    </div>



      </div>

      <div class="col-md-4">


    <List :itemList="List"/>


      </div>


    </div>
    <!-- <div class='div' v-bind:class="[isActive ? 'red' : 'blue']" @click="toggleClass()"></div> -->


  </div>
</template>

<script>
import List from "../components/myList.vue";

export default {
  name: "Hero",
  components: {
    List
  },
  data: function() {
    return {
      title: "Simple Search",
      isActive: true,
      intro: "This is a simple hero unit, a simple jumbotron-style.",
      subintro:
        "It uses utility classes for typography and spacing to space content out.",
      result: [],
      errors: [],
      List: [],
      search: "",
      loading: "",
      message: false,
      isValidationAllowed: false,
      loadingClass: "loading",
      errorTextClass: "error-text",
      disableButton: false,
      perPage: 3,
      currentPage: 1
    };
  },

  watch: {
    search: function(val) {
      if (!val) {
        this.result = [];
      }
    }
  },

  computed: {
    validated() {
      return this.isValidationAllowed && !this.search;
    },
    isDisabled: function() {
      return !this.terms;
    },
    rows() {
        return this.result.length
      }
  },

  methods: {
    getData: function() {
      this.isValidationAllowed = true;
      this.loading = true;
      fetch(`https://itunes.apple.com/search?term=${this.search}&entity=album`)
        .then(response => response.json())
        .then(data => {
          this.result = data.results;
          this.loading = false;
          /* eslint-disable no-console */
          console.log(data);
          /* eslint-disable no-console */
        });
    },

    toggleClass: function() {
      // Check value
      if (this.isActive) {
        this.isActive = false;
      } else {
        this.isActive = true;
      }
    },

    refreshPage: function() {
      this.search = "";
    },
    addItem: function(result) {
      result.disableButton = true; // Or result['disableButton'] = true;
      this.List.push(result);
      /* eslint-disable no-console */
      console.log(result);
      /* eslint-disable no-console */
    },

    resizeArtworkUrl(result) {
      return result.artworkUrl100.replace("100x100", "160x160");
    },

  },
  mounted() {
    if (localStorage.getItem("List")) {
      try {
        this.List = JSON.parse(localStorage.getItem("List"));
      } catch (err) {
        console.err(err);
      }
    }
  },
};


</script>

<style>
.loading {
  background-image: url("../assets/Rolling-1s-42px.gif");
  background-repeat: no-repeat;
  height: 50px;
  width: 50px;
  margin: 15px;
  margin-left: auto;
  margin-right: auto;
}

.error-text {
  color: red;
}

.media {
  text-align: left;
}

.album-cover {
  width: 80px;
  height: auto;
}

.red {
  background: red;
}

.blue {
  background: blue;
}

.div {
  width: 100px;
  height: 100px;
  display: inline-block;
  border: 1px solid black;
}
</style>

Любая идея или понимание было бы здорово.


person Sole    schedule 28.06.2019    source источник


Ответы (2)


Я не думаю, что нумерация страниц vue bootstrap предназначена для управления HTML-элементами div по умолчанию. Если вы хотите отобразить результат в таблице, которую вы закомментировали, попробуйте изменить ее на это:

<b-table
      id="my-table"
      v-model="result"
      :per-page="perPage"
      :current-page="currentPage"
      small
    ></b-table>

В вашей предыдущей реализации у b-table не было возможности прикрепить массив «результат». То, к чему вы прикрепили свой массив, было свойством с именем «результат».

надеюсь это поможет.

person Pete    schedule 28.06.2019

Я не знаю, является ли это той же проблемой, но у меня есть компонент сетки, который перерисовывается только в том случае, если я его заставляю, потому что сетка отверстий монтируется в «созданном» жизненном цикле, поэтому вы можете попробовать nextTick(), было бы что-то как это:

  <b-pagination v-if="renderPagination"
    v-model="currentPage"
    :total-rows="rows"
    :per-page="perPage"
    aria-controls="my-table"
  ></b-pagination>

Поместите директиву v-if, наблюдающую за логической переменной, вы можете запустить ее с истинным значением в ваших данных;

data() {
    return {
         renderPagination: true,
         // the rest of your data
    }
}

Затем, после того, как вы проконсультируетесь с API отдыха для новых данных, вызовите логику с помощью:

   this.renderPagination = false;
   this.$nextTick(() => {
        this.renderPagination = true;
    });

Это заставит компонент начальной загрузки перерисовывать себя с самого начала.

person Julliano Osorio    schedule 28.06.2019