使用Vue从头搭建前后端分离的应用
简介:前后端分离一直是前端、后端同学所期望的方式,当然如果你所在的团队中分工比较明确的话,毕竟解耦不仅是我们程序上的一种追求,工作方式同样如此。那么首先从整体上了解下项目整体情况吧:
后端项目:springboot(2.0+)
前端项目:vue-cli脚手架搭建的前端工程 + Node.js(8.9+)
IDE:前后端都采用IDEA(安装vue.js插件,设置ES语法级别为6以上即可进行前端项目的编码,谁让我们是后端来写前端项目呢,苦笑~),当然前端也可以采用Visual Studio Code
一、搭建基础环境
1.1 安装node.js环境
- Node简介: 简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js 的包管理器 npm,是全球最大的开源库生态系统。
这些不免有些官方,从后端的视角来看的话,Node之于前端项目就像Tomcat之于后端项目,是用来发布前端项目并提供服务的,这样做个类比也许更好理解。 - 下载: 从官网下载对应版本的node安装包,我的系统是Ubuntu16,选择linux 64位的tar.xz包:
- 解压: 解压到指定目录下(我的是在/opt/node目录),因为我没有使用root账号,所以命令前都需要带上
sudo
来保证有权限执行相应命令,命令如下:
sudo tar -xvf node-v10.15.3-linux-64.tar.xz
解压完成后,就可以看到bin
目录里有node
和npm
的文件了,其中npm
即node package manager
(node的包管理器),就是对Node.js
依赖的包进行管理,从后端的视角来看,就是Maven
一样的存在了
- 建立软连接: 这样就可以在全局执行相应的命令了,软连接类似于一个指针,这样不管在什么路径下执行
npm
或node
相关操作,都会由指向node
安装目录的npm
或node
来执行,命令如下:
sudo ln -s /opt/node/node-v10.15.3-linux-x64/bin/node /usr/local/bin
sudo ln -s /opt/node/node-v10.15.3-linux-x64/bin/npm /usr/local/bin
- 验证: 执行如下命令查看是否安装成功。
查看node版本:node -v
查看npm版本:npm -v
- 安装
cnpm
: 因为使用npm install
安装包时速度很慢,所以建议安装cnpm后使用cnpm install来安装包。cnpm
是淘宝做的国内的一个镜像,类似于Maven
在国内做的私服地址一样,这样下载依赖的时候就会比访问国外的资源要快了。步骤也跟上面的一样,下载cnpm
,配置软连接,验证,命令如下:
sudo npm install -g cnpm --registry=https://registry.npm.taobao.org
sudo ln -s /opt/node/node-v10.15.3-linux-x64/bin/cnpm /usr/local/bin
cnpm -v
1.2 初始化vue前端项目
- 安装vue脚手架
@vue/cli
,用来快速搭建vue前端工程。只需要执行如下命令即可:
sudo npm install -g @vue/cli
- 验证是否安装成功,如果有如下提示,则需要建立软连接:
- 建立软连接:
sudo ln -s /opt/node/node-v10.15.3-linux-x64/bin/vue /usr/local/bin
这时,@vue/cli
脚手架就安装完了,我们看到版本是3.0+,接下来就可以创建前端工程了 - 创建前端工程: 默认模式,创建一个工程名为my-vue-project的项目
sudo vue create my-vue-project
接下来会让选择创建模式,default
为默认模式,都采用默认配置,当然如果是实际的项目的话,需要选择第2个来手工指定相关配置。这里为了演示,先采用默认default
等待几分钟后就会自动创建完成,并提示接下来需要进入到项目的目录内,启用服务,如下:
按照提示进入目录:cd my-vue-project
,启用服务:npm run serve
,启用后显示访问地址,两种访问方式,浏览器输入后即可访问。
打开后如下,默认项目创建成功。
当然如果不想用默认模式创建,可以采用第二种模式来手工指定相关配置,接下来看下如何处理:
- 创建前端工程: 手动选择模式,同样通过
sudo vue create my-new-vue
命令创建工程,并进入模式选择页面,并选择第二个选项,手工选择功能特性,如下:
- vue-cli 内置支持了8个功能特性,可以多选:使用方向键在特性选项之间切换,使用空格键选中当前特性,使用 a 键切换选择所有,使用 i 键翻转选项。
对于每一项的功能,此处做个简单描述:- TypeScript: 支持使用 TypeScript 书写源码。
- Progressive Web App (PWA) Support: PWA 支持。
- Router: 支持 vue-router ,类比后端controller的
RequestMapping
。 - Vuex: 支持 vuex 。
- CSS Pre-processors: 支持 CSS 预处理器。
- Linter / Formatter: 支持代码风格检查和格式化。
- Unit Testing: 支持单元测试,同样可以和后端的单元测试做类比。
- E2E Testing: 支持 E2E 测试。
- 按如上选择完后,接下来的默认yes即可,接下来需要选择,在项目里面需要支持何种动态样式语言,此处提供了三个选项:
- SCSS/SASS
- LESS
- Stylus
此处选择 LESS ,进入下一步:
- 格式化的配置,选择最后一项
- 单元测试,选择目前最火的Jest
- 配置是否单独保存,还是统一保存在package.json文件中,建议分开保存,便于管理
- 是否将如上配置进行保存,以便下次创建时能用到
至此,创建完成~
二、vue项目基本配置介绍
2.1 项目的基本结构
- package.json项目中所有的依赖,类似后端maven中的pom文件,
node_modules
即下载的依赖,类似maven中的jar
包 - jest.config.js单元测试的配置,单元测试的具体代码在
tests
包下 - public包我们都知道vue是单页面应用(SPA),而public中的index.html即这个单页面,通过
<div id="app"></div>
中的app
来挂载它所依赖的其他页面
- src包是我们写页面最重要的包,类似于我们后端项目中的
src
包,我们看下里边具体都有什么东东: - src–>assets 一些静态资源,比如logo.png等;
- scr–>components 基础组件,比如我们会写一些通用的上传组件、页面布局组件、分页组件,放在这里,以免重复造轮子;
- scr–>views 具体的页面;
- scr–>App.vue vue的入口页面,可以看下具体的内容,一般情况下
*.vue
文件包含3个部分template
:页面模板,script
:逻辑,style
:样式,我们可以看到这里只有页面模板
及样式
,页面模板
也很简单,只有一个div
和router-view
,而router-view
是个很神奇的存在,router.js
路由对应到什么页面,router-view
就对应成什么页面。接下来看下路由
- scr–>router.js 页面的路由,类似于后端项目的
controller
,不过它是针对页面的路由,不同的url
对应到不同的*.vue
页面上,如下图:/
根路径对应为./views/Home.vue
页面,/about
路径对应为./view/About.vue
页面。
- src–>main.js入口文件,类比后端的
main
函数,作用就是进行初始化,比如new Vue进行实例化;引入app.vue作为根组件(父组件),import 来引入子组件
- src–>views–>Home.vue我们从路由中得知,访问
/
根路径时加载Home.vue
页面,那么看下这个页面,可以看到该页面引用了HelloWorld
子组件,这类似于后端项目中的bean
依赖,很少有bean
是独立存在的,总得通过@AutoWare或者@Resource
依赖个其他bean
吧,那就像页面这样,先import HelloWorld from "@/components/HelloWold.vue"
引入,再声明components:{ HelloWorld}
,最后使用<HelloWorld msg="Welcome to your vue.js app">
,其中msg
就相当于在使用时给该组件的属性赋值,那么接下来看下HelloWorld
组件
- src–>views–>HelloWorld.vue该组件存在属性
msg
,声明的方式如下props:{msg: String}
,这样父组件在调用该子组件时就可以对子组件赋值了
以上我们了解了vue前端项目的基本结构~
三、跨域问题解决方案
笔者目前的项目中,采用的是开发环境下前后端分离,生产环境中前后端不分离的模式。采用这种方式,主要是为了充分利用服务器资源,因为对于管理端的页面,因为并没有太大的访问量,所以前后端在一起打包部署并无不妥,前端负责页面的跳转,并通过Ajax向后端发起请求,后端为前端提供数据。
而在开发环境中,为了提高前后端开发的效率,前端同学只需要关注前端工程,后端同学关注后端工程即可。
不过在开发环境联调的过程中,常会遇到跨域的问题,那么接下来介绍下3种解决方案:
3.1 方案一:后端设置为允许跨域
后端项目为springboot 2.0,只需在启动类中增加如下配置即可:
@SpringBootApplication
public class WebLauncher extends SpringBootServletInitializer implements WebMvcConfigurer{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(WebLauncher.class);
}
public static void main(String args[]){
SpringApplication.run(WebLauncher.class, args);
}
/**
* 允许跨域访问
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders("*")
.allowCredentials(true)
.allowedOrigins("*")
.allowedMethods("*")
//跨域允许时间
.maxAge(3600);
}
}
3.2 方案二:前端设置的域名和后端保持一致
前端项目访问地址默认为localhost:8080,后端一般为hppt://www.xxx.com,这样的话前端发起Ajax请求肯定会遇到跨域问题,如果我们把前端配置成后端域名,这样就不存在跨域问题了嘛(一种奇淫技巧的赶脚……)
由于vue-cli 3.0+版本节省了很多配置,就像springboot一样配置直接默认化了,需要我们增加vue.config.js
配置文件。如下:
配置内容如下:
module.exports = {
devServer: {
open: true,
host: 'www.xxx.com', //配置为后端域名即可,默认为0.0.0.0,即localhost
port: 83, //如果跟后端项目在同一台电脑上启动服务,端口改成不一样即可
https: false,
disableHostCheck: true
},
}
3.2 方案二:前端设置代理来访问后端
同样在vue.config.js
配置中配置代理,来访问后端
module.exports = {
devServer: {
open: true,
host: '0.0.0.0',
port: 83,
https: false,
// 代理相关配置,开发联调打开,
proxy: {
'/apis': {
target: 'http://www.xxx.com', //后端域名
secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //允许跨域
pathRewrite: {
'^/apis': '/'
}
},
},
disableHostCheck: true
},
}
我们的Ajax请求的URL就要以/apis
开头了,如下:
export function add(params) {
return fetch({
url: '/apis/add/user', //注意此处一定要以/apis开头
method: 'post',
params
})
}
这样的话,我们在vue的axios
组件中发起Ajax
请求的地址改为/apis/add/user
,就被代理成了http://www.example.com/add/user
,解决了跨域问题。
四、其他问题
打包、部署待完善