在Java Web Project中实现Vue异步组件加载
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Java Web Project中实现Vue异步组件加载相关的知识,希望对你有一定的参考价值。
背景
最近看上了ElementUI(Vue实现)用来实现一个管理系统Demo,其中一个最常见的需求就是左侧导航不动,右侧主页块在点击导航菜单时动态更新,如下图所示:
之前的实现方案是右边嵌入一个iframe,动态更改iframe的url即可,现在既然用了Vue咱也试试单页,是不是显得更优雅。接着就接触到了vue-router、组件、异步组件这些关键字,本以为把页面定义为xxx.vue放到webapp下,然后告诉vue-router去加载就好了,最后发现自己想简单了,思维模式还停留在Java Web开发上,感觉Vue这类框架更多适用于纯前端开发者或Node环境?按照官方文档的说法“结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。”在 Webpack 的加持下貌似可以达到要求,但是这又是一个什么鬼?暂时粗浅的认为它是一个工具,可以解析.vue生成.js。难道说我要把前端部分单独出来,然后每次写完先 Webpack 一下,再把生成的文件拷贝到webapp下?这对于目前的模式来说肯定是不可行的,且不说前后端分离带来的部署调试的麻烦,首先分离后就丧失了Spring+Thymeleaf的优势,其次目前的情况分不分都是一个人玩,从前写到后,切来切去多累,我只想在一个Eclipse 的 Project 中解决问题,怎么办?
实现思路
后来研究了Vue的异步组件,发现它要的无非就是一段定义组件的JS代码,那么完全可以定义一个接口来输出JS代码。把一个Vue组件拆分成两个同名文件如:user_list.js user_list.html(user_list就是组件名称,本来一个js就足够了,但是为了避免在js中写HTML字符串还是分开好,js中的template属性用一个占位符便于替换如:template: ‘$template‘)放在WEB-INF/vue-component下,然后实现接口,这个接口收到请求自动把两个文件拼合为一段JS代码,响应给前端,代码如下:
@GetMapping("/vcp")
public void parse(@RequestParam("p") String path, HttpServletRequest req, HttpServletResponse resp) throws IOException {
if(StringUtils.isEmpty(path)) return;
String res = "null";
String vcpDir = req.getServletContext().getRealPath("/WEB-INF/vue-component/");
File jsFile = new File(vcpDir + path + ".js");
File htmlFile = new File(vcpDir + path + ".html");
if(jsFile.exists() && htmlFile.exists()) {
String jsCode = BaseUtils.readCodeFileAsText(jsFile);
String htmlCode = BaseUtils.readCodeFileAsText(htmlFile);
res = "window.vcpRes[‘"+path+"‘] = "+jsCode.replace("$template", htmlCode);
}
// response
resp.setContentType("application/x-javascript;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println(res);
out.close();
}
接口定义好了再来看Vue部分(下面给出关键性代码,关键是思路,版本信息:vue2.5 vue-router3.0)
// 定义全局变量,用于接收接口输出的JS组件对象
window.vcpRes = {};
// 添加路由
routes.push({path: ‘/user/list‘, component: Vue.component(‘user-list‘, syncComponent(‘user_list‘)) });
/**
* 该函数通过JQuery异步获取组件,path参数就是组件名如:user_list
*/
function syncComponent(path){
return function(resolve, reject){
$.getScript(‘vcp?p=‘+path, function(){
var component = window.vcpRes[path];
if(component){
resolve(component);
}else{
reject(‘组件加载失败:‘+path);
}
});
};
}
结语
如果有时间,也可以在接口中实现一个.vue的解析器,这样组件就不用分两个文件写了。这只是我个人能想到的一种解决方案,能力有限。如果你是一名Java Web开发者也在使用Vue,有更好的解决方案请留言。
以上是关于在Java Web Project中实现Vue异步组件加载的主要内容,如果未能解决你的问题,请参考以下文章