Мне удалось найти причину этой проблемы, и, поскольку она технически работает, я опубликую ее как ответ.Я знаю, что вы не должны смешивать 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: ""
}
});
}
Кажется, это работает.Я сомневаюсь, что это отличное решение, но я полагаю, если оно будет функциональным, я могу также включить его сюда.Если есть лучший способ сделать это, я хотел бы услышать это.