Vue,Springboot前后端分离项目初体验

6,233 阅读5分钟
最近在撸一个小项目,原来做过几个系统,主要用的是Extjs和SpringMVC。Vue了解过一点,看了一下官方文档感觉蛮好的(相比Extjs,“蛮好”两字其实无法表达...)。原来的SpringMVC的架构因为是别人搭建好的,只是照葫芦画瓢的开发,也没有足够的精力去深入学习了解。然后我决定了这个项目的方案,Vue加Springboot,几乎零基础边做边学,虽然因为时间要求的比较紧把自己搞得压力山大,不过最后还是如期开发完成~

架构方案

前端:Vux  做移动网页版(朋友推荐,也确实比较溜。文档还算比较齐全的,不过我到现在还是没搞出来 InlineCalendar的marks是怎么用的)

后端:Springboot 参考 @Mr_初晨 的专栏,一步步搭的框架。感谢!

数据库:MySQL

路由校验

1.定义路由:通过设置meta来判断是否需要进行校验,我是全部都写了

const routes = [
    {  
        path: '/',  component: Login},
    {  
        path: '/home',  
        meta:{auth:true}, // 设置当前路由需要校验  不需要校验的路由就不用写了  
        component: Home
    },{  
        path: '/Reserve',  
        meta:{auth:true},   
        component: Reserve
    },{  
        path: '/Cancel',  
        meta:{auth:true},   
        component: Cancel
    },{  
        path: '/WorkInfo',  
        meta:{auth:true},  
        component: WorkInfo
    },{   
        path: '/Detail/:type/:date',   
        meta:{auth:true},   
        component: Detail
    }]
    const router = new VueRouter({  routes})

2.通过路由钩子对每次请求进行拦截,判断是否已经登录。

这里有个小坑,我本来是把用户信息存到Vuex里面的,然后去验证,兴致勃勃的刷了个新,就GG了。后来查了下资料,Vuex的里的数据刷新就会清空的,采用了sessionStorage来存储用户信息进行校验。当浏览器关闭时才会清除。(区别localStorage,算是基础知识了,不过我是第一次用~)

//路由拦截router.beforeEach((to,from,next) => {   
  if(to.matched.some( m => m.meta.auth)){           
    var userInfo = JSON.parse(sessionStorage.getItem('userInfo'));  // 对路由进行验证           
        if(userInfo) { // 已经登陆               
            next()   // 正常跳转到你设置好的页面           
        }      
        else{               // 未登录则跳转到登陆界面,query:{ Rurl: to.fullPath}表示把当前路由信息传递过去方便登录后跳转回来;      
            next({path:'/',query:{ Rurl: to.fullPath} })      
        }  
     } 
     else{
     next()
     } })

跨域请求

前后端分离就会碰到跨域的问题,我的解决方案很粗暴。

1.Springboot Controller增加跨域资源的注解 

 @CrossOrigin(origins = "*", maxAge = 3600)

不要问我为什么,我不知道,反正就这样成功了,允许所有的跨域请求。阮神有篇文章有详细介绍 跨域资源共享 CORS 详解,我没有仔细看。

2.统一BaseUrl

vux用的是axios,了解过,没有认真了解。不知道BaseUrl怎么配置,于是用了一个笨方法:全局变量。我知道Webpack可以区分量产和测试环境分别配Url,但是没有时间和精力研究了,项目结束后再认真学习吧~

前端config里创建 global.js 文件(其实随便啦~)

const BASE_URL ="localhost:8080/"export default{    BASE_URL}

在main.js中import进来,添加到Vue全局变量里:

import global_ from "./../config/global"

Vue.prototype.GLOBAL = global_;

然后在组件中就可以这样引用:

this.$http
        .post(this.GLOBAL.BASE_URL+"user/login?id="+this.id+"&password="+this.password)
        .then(function(response) {
          console.log(response.data);
        })        
        .catch(function(error) {
          console.log('error'+error);
        });

But,这样搞在build的时候会报错,报错内容我忘记了,搜了一下好像是说global的这种写法是ES6的没有正确解析,需要用babel解析。解决方案是修改Webpack.base.conf.js文件

原配置:

 module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      。。。

增加 resolve('config/global.js')

module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test'),resolve('config/global.js')]
      },
      。。。

打包部署

后端我是打成了jar包,Springboot本来就自带Tomcat服务器,感觉没有必要打成war包再放到容器里。

1.首先,我尝试了把前端build的出来的dist文件夹下面的文件(static目录,index.html文件)塞到springboot的resources/static下面:

根据Spring Boot 对静态资源映射提供的默认配置,按道理 /index.html 是能够找到这个目录下面的index.html文件的。但是显示未定义接口,被拦截掉了。查了一下资料,应该是WebConfigurer里用了SpringMvc的拦截方法。于是添加了

 registry.addResourceHandler("/static/**").addResourceLocations( "classpath:/static/");

奢望能够通过 /staitic/index.html来访问,这样index是可以访问了,但是js文件被拦截了~也没有查到解决方案,遂放弃~应该是写法不对,望大神们指教。后来需要一个apk的发布网址,我就把index修改成apk下载网页了~哦,apk下载也被拦截了,更改配置解决:

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("swagger-ui.html")
            .addResourceLocations("classpath:/META-INF/resources/");
    registry.addResourceHandler("doc.html")
            .addResourceLocations("classpath:/META-INF/resources/");
    registry.addResourceHandler("/static/**").addResourceLocations( "classpath:/static/");
    registry.addResourceHandler("/app-release.apk").addResourceLocations( "classpath:/static/");
    registry.addResourceHandler("/webjars/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/");
    super.addResourceHandlers(registry);
}

2.采用Nginx部署

前端的ajax请求不要用localhost,直接用IP地址,下载Nginx,修改配置文件:

server {
    listen 8079;   、、端口号
    ...
    root   /front/dist;   //dist文件夹路径
    index  index.html index.htm;
    add_header Access-Control-Allow-Origin "*";
    ...
}

注意不要直接双击nginx.exe,这样会导致修改配置后重启、停止nginx无效,需要手动关闭任务管理器内的所有nginx进程

在nginx.exe目录,打开命令行工具,用命令 启动/关闭/重启nginx

start nginx : 启动nginx

nginx -s reload :修改配置后重新加载生效

nginx -s reopen :重新打开日志文件

nginx -t -c /path/to/nginx.conf 测试nginx配置文件是否正确

关闭nginx:

nginx -s stop :快速停止nginx

nginx -s quit :完整有序的停止nginx

结语

至此,Vue和Springboot前后端分离的实践算是基本完成,当然还有很多问题和知识点需要自己再去学习和了解。因为本职工作无论内容还是技术其实和这些不相干,投入的精力有限,也只能靠抽点时间自学。架构的问题点,不足之处也请多多指教。看了蛮久的掘金,第一次写文章,发现技术领域的文章我完全没有文笔,哈哈