Скрытие шаблона vue.js перед его отображением

Я пытаюсь скрыть содержимое шаблона vue.js до его полной визуализации. Рассмотрим следующий шаблон:

<div class="loader"> 
  <table class="hidden">
    <tr v-for="log in logs">
      <td>{{log.timestamp}}</td>
      <td>{{log.event}}</td>
    </tr>
  </table>
</div>

Когда я отрисовываю этот шаблон на сервере, пользователь видит содержимое элемента <tr> до его отрисовки. По этой причине я использую класс hidden чтобы скрыть его, прежде чем он будет полностью отрендерен.

Также перед тем, как он будет отрендерен, я показываю элемент загрузчика с анимированным индикатором выполнения.

Как только он рендерится, я просто вызову element.show() в jQuery и также element.show() выполнения. Мой вопрос: можно ли смешивать jQuery и vue.js для достижения этой цели?

var vueLogs = new Vue({
  el: "#checkInLogsHolder",
  data: {logs: []}
});
var holder = $("#checkInLogsHolder");

function response(payload) {
  // hiding the loader animation
  holder.find(".loader").remove();
  // showing the rendered table
  holder.find("table").show();
  vueLogs.logs.unshift(payload);
}

Есть ли лучший способ сделать это?

Ответ 1

Vue уже имеет встроенную директиву v-cloak, вам просто нужно добавить соответствующий класс css:

[v-cloak] {
  display: none;
}

А затем примените его к вашему элементу так:

<div v-cloak>
  {{message}}
</div>

Вот JSFiddle: https://jsfiddle.net/2jbe82hq/

Если вы v-cloak в этой скрипке v-cloak, вы увидите усатый {{message}} до монтирования экземпляра.

Если вы хотите отображать loader во время извлечения данных с вашего сервера, тогда вы комбинируете логический флаг с v-if чтобы показать и скрыть загрузчик:

var vm = new Vue({
  el: "#app",
  created(){
    this.$http.get('url').then(response => {
      // set loader to false
      this.loading = false;
    });
  },
  data: {
    message: 'Hello Vue!',
    loading: true
  }
});

Затем вы можете сделать:

<div v-if="loading">
   Loading...
</div>
<div v-else>
    {{message}}
</div>

Вот JSFiddle для этого: https://jsfiddle.net/fa70phLz/

Также можно использовать класс loading а затем использовать v-bind:class для применения и удаления класса на основе флага, что полезно, если вы хотите наложить всю страницу на loader.

<div :class="{'loading': loading}"></div>

Ответ 2

Я просто добавляю полезные вещи из v-cloak , чтобы добавить spinner перед рендерингом полного HTML файла и благодаря Адаму для его Gist - https://gist.github.com/adamwathan/3584d1904e4f4c36096f

Если вы хотите добавить счетчик перед загрузкой своей страницы, вы можете прочитать это -

  • Добавить v-cloak внутри #app.
  • Сделайте один div v-cloak--inline, который мы хотим показать перед обработкой HTML-страницы.
  • Другое Div, которое будет содержать полную страницу с v-cloak--hidden.
  • Необходимо добавить здесь css.

Пусть код - На главной странице,

 <div id="app">

  <div v-cloak>

   <div class="v-cloak--inline"> <!-- Parts that will be visible before compiled your HTML -->
      <i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
      <span class="sr-only">Loading...</span>
   </div>

   <div class="v-cloak--hidden"> <!-- Parts that will be visible After compiled your HTML -->
      <!-- Rest of the contents -->
      @yield('content')
   </div>

  </div>

</div>

С добавлением этих дополнительных CSS для v-cloak.

[v-cloak] .v-cloak--block {
  display: block;
}
[v-cloak] .v-cloak--inline {
  display: inline;
}
[v-cloak] .v-cloak--inlineBlock {
  display: inline-block;
}
[v-cloak] .v-cloak--hidden {
  display: none;
}
[v-cloak] .v-cloak--invisible {
  visibility: hidden;
}
.v-cloak--block,
.v-cloak--inline,
.v-cloak--inlineBlock {
  display: none;
}

Затем перед компиляцией HTML файла будет отображен счетчик. После компиляции прядильщик скроется. Вы можете использовать это на своей главной странице. Таким образом, каждый раз, когда вы загружаете новую страницу, это будет видеть эффекты.

См. Gist - https://gist.github.com/adamwathan/3584d1904e4f4c36096f

Ответ 3

Я бы не стал смешивать jQuery в коде Vue.js по той причине, что Vue.js предоставляет набор инструментов, которые обычно устраняют необходимость в jQuery.

Так как вы загружаете страницу и показываете индикатор выполнения, вы можете использовать перехваты жизненного цикла Vue.js: [созданный, смонтированный, beforeUpdate, обновленный и т.д. и т.д.].

Что бы я сделал, это создать небольшой div, содержащий индикатор выполнения, а затем соседний элемент с фактическим содержимым, отображаемым после загрузки. Задайте данные экземпляра компонента, а затем используйте переключатели жизненного цикла для переключения дисплея.

<div v-if='loading'>
  <div class='progress-bar'>
  <!-- Loading bar markup here -->
  </div>
</div>

<div v-else class='content'>
  <table>
  <!-- Content -->
    <tr v-for="log in logs">
      <td>{{log.timestamp}}</td>
      <td>{{log.event}}</td>
    </tr>

  </table>
</div>

Затем в script части шаблона:

export default {
  data() {
    return: {
      loading: true,
      logs: [],
      message: ''
    };
  },
  methods: {
    fetchLogs() {
      // using vue-resource / ajax library like axios
      this.$http.get('/api/logs').then((logs) => {
        if (logs) {
          this.logs = logs;
          setTimeout(() => {
            this.loading = false;
          }, 1000);
        } else {
          this.message = 'No logs to display';
          this.loading = false;
        }
      });
    }
  },
  mounted() {
    this.fetchLogs();
  }
};

Используя этот метод, вы также можете привязать классы к элементам для создания плавных переходов CSS.

Ответ 4

Кроме v-cloak. Вы также можете использовать атрибут v-text. Таким образом, вам не нужно иметь дело с этим в CSS.