java web vue_在Java Web Project中实现Vue异步组件加载

背景

最近看上了ElementUI(Vue实现)用来实现一个管理系统Demo,其中一个最常见的需求就是左侧导航不动,右侧主页块在点击导航菜单时动态更新,如下图所示:

c29c648e6219a9dd10b7f64cf9577fdc.png

之前的实现方案是右边嵌入一个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,有更好的解决方案请留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值