Как я могу инициализировать страницу Vue в мобильном приложении jQuery? - PullRequest
0 голосов
/ 17 октября 2018

Я работаю над заявкой, оставленной консультантом.Сайт в настоящее время основан на jQuery, но некоторая логика на этих страницах становится действительно сложной, и соответствующий javascript немного выходит из-под контроля.Я хочу избавиться от некоторых слесарных операций, которые я должен выполнить вручную с помощью jQuery Mobile, переписав страницы в Vue.

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

Когда я перехожу на сайт, написанный на Vue, при первой загрузке всеинициализируется правильно, и код работает просто отлично.Тем не менее, после перехода и возврата на эту страницу, кажется, ничего не работает.Похоже, что Vue вообще не инициализирован.

Я бы опубликовал пример, но я просто не знаю, как опубликовать пример, который требует навигации, чтобы показать проблему, поэтому лучшее, что я могу сделать, этоопишите шаги воспроизведения:

  1. Начните с любого приложения с jQuery Mobile и переписайте одну страницу в Vue.
  2. Перейдите на страницу Vue.Страница работает должным образом.
  3. Перейдите со страницы обратно в основное приложение jQM.
  4. Перейдите обратно на страницу Vue.На этот раз Vue не инициализирован правильно.Все элементы HTML все еще там, но Vue не будет взаимодействовать ни с чем.

1 Ответ

0 голосов
/ 17 октября 2018

Мне удалось найти причину этой проблемы, и, поскольку она технически работает, я опубликую ее как ответ.Я знаю, что вы не должны смешивать jQuery Mobile и Vue, и все проблемы совместимости являются основной причиной, но я просто не могу позволить себе роскошь начинать с нуля, и я все еще хочу получить преимущества, которые я получаю как разработчикиз фреймворка.

Проблема здесь заключается в архитектуре кэширования / SPA jQM.У меня есть приложение JSP, в котором я переписываю одну страницу в Vue.Корневой экземпляр приложения vue записывается прямо на страницу JSP, поэтому, когда пользователь загружает страницу, он выбирает HTML-код с шаблоном.Предположим, например, что это шаблон:

<html>
  <head>
    <!-- links and scripts -->
    <script src="app.js"></script>
  </head>
  <body>
    <div data-role="page">
      <div data-role="content" class="ui-container">
        <div id="vue-application">
          <input v-model="test_input">
          <p>{{ test_input }}</p>
        </div>
      </div>
    </div>
  </body>
</html>

Затем в app.js

$(document).bind("pageinit", function() {
  new Vue({
    el: "#vue-application",
    data: {
      test_input: ""
    }
  });
});

Учитывая приведенную выше страницу, загрузка в первый раз работает, потому что шаблон загружен без изменений изсервер в DOM, а затем, когда Vue инициализируется на div#vue-application, он извлекает шаблон из DOM, анализирует его и инициализирует, а затем монтирует компонент Vue обратно в DOM без всего синтаксиса шаблона.

Теперь, когда вы уходите со страницы, jQM возьмет все, что находится в DOM внутри этого элемента div[data-role=page], и кеширует его.Последующая навигация по этой странице не приведет к извлечению неизмененного шаблона из сервера, но вместо этого повторно вставит его в DOM из памяти, но проблема в том, что Vue уже заменил весь код шаблона на обычные элементы DOM, и все хуки теперь исчезли.,Все события, такие как pageinit, по-прежнему запускаются, и Vue по-прежнему инициализируется, но теперь нет шаблона для инициализации, это просто обычный DOM, поэтому Vue практически ничего не цепляет и просто инициализирует статическую HTML-страницу.

Чтобы противодействовать этому кешированию, я закончил тем, что загружал содержимое div#vue-application через Ajax и впоследствии инициализировал приложение.Главная страница была разделена на два файла:

main_page.jsp

<html>
  <head>
    <!-- links and scripts -->
    <script src="app.js"></script>
  </head>
  <body>
    <div data-role="page">
      <div data-role="content" class="ui-container">
        <div id="vue-application"></div>
      </div>
    </div>
  </body>
</html>

template.jsp

<input v-model="test_input">
<p>{{ test_input }}</p>

, и для кода JavaScript также требовалось немногореконструкция:

app.js

$(document).bind("pageshow", function() {
  $.mobile.loading("show");
  $.ajax({
    url: "template.jsp",
    method: "Get",
    data: {
      // My JSPs are parameterized, so the template may
      // need some of the parameters from this page to 
      // be passed down into the template for initialization.
    }
  }).done(function(template) {
    initialize_vue_from_template("#vue-application", template);
  }).always(function() {
    $.mobile.loading("hide");
  });
});

function initialize_vue_from_template(element, template) {
  $(element)
      .html(template)
      // Don't forget to initialize jQuery
      .enhanceWithin(); 

  new Vue({
    el: element,
    data: {
      test_input: ""
    }
  });
}

Кажется, это работает.Я сомневаюсь, что это отличное решение, но я полагаю, если оно будет функциональным, я могу также включить его сюда.Если есть лучший способ сделать это, я хотел бы услышать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...