我正在处理顾问遗留的应用程序。该站点当前基于jQuery,但是这些页面上的某些逻辑确实变得非常复杂,并且相应的javascript有点失控。我想通过重写Vue中的页面来摆脱一些我必须使用jQuery Mobile手动完成的工作。
我不想重写整个网站,只有几页可以帮助我驯服复杂的逻辑并划分代码。我已经处理了各种组件的所有jQuery增强冲突,但是现在我面临jQuery的页面加载机制的问题。
当我导航到用Vue编写的网站时,第一次加载时,一切都会正确初始化并且代码可以正常工作。但是,导航离开并返回该页面后,似乎没有任何效果。看起来Vue根本没有初始化。
我会发布一个示例,但是我只是不知道如何发布一个需要导航以显示问题的示例,所以我能做的最好的事情就是描述复制步骤:
答案 0 :(得分:0)
我设法找到了这个问题的原因,并且由于它在技术上是可行的,因此我将其发布为答案。我知道您不应该将jQuery Mobile和Vue混合使用,并且所有兼容性问题都是主要原因,但是我只是没有从头开始的奢望,我仍然希望获得作为开发人员的好处从框架开始。
这里的问题是jQM的缓存/ SPA架构。我有一个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中的,然后在div#vue-application
初始化Vue时,它将模板从DOM中拉出,对其进行解析,然后初始化它,然后在不使用所有模板语法的情况下将Vue组件重新安装到DOM中。
现在,当您离开页面导航时,jQM将获取div[data-role=page]
元素内DOM中的所有内容并将其缓存。此页面的后续导航不会将未更改的模板从服务器中拉出,而是会将其从内存中重新插入到DOM中,但是问题在于Vue已经用正常的DOM元素替换了所有模板代码,并且所有钩子现在都消失了。像pageinit
这样的所有事件仍然会触发,并且Vue仍会初始化,但是现在没有要初始化的模板,它只是一个普通的DOM,因此Vue基本上不会挂接到任何东西,而只是初始化了静态HTML页面。 / p>
为了抵消这种缓存,我最终通过Ajax加载div#vue-application
的内容,然后初始化应用程序。主页已分为两个文件:
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: ""
}
});
}
这似乎有效。我怀疑这是否是一个很好的解决方案,但是我认为它是否可以正常工作,我不妨将其包含在此处。如果有更好的方法可以做到这一点,我很想听听。