前后端分离已成为互联网项目开发的业界标准使用方式,通过nginx+tomcat的方式有效的进行解耦,并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户端,例如:浏览器,车载终端、安卓、IOS等等)打下坚实的基础。
这个步骤是系统架构从猿进化成人的必经之路。
核心思想是前端html页面通过ajax调用后端的restuful api接口并使用json数据进行交互。
前后分离的优势
1.可以实现真正的前后端解耦,前端服务器使用nginx/tomcat。前端/WEB服务器放的是css、js、图片等等一系列静态资源,前端服务器负责控制页面引用、跳转、路由。
2.发现bug,可以快速定位是谁的问题,不会出现相互踢皮球的现象。页面逻辑,跳转错误,浏览器兼容性问题,脚本错误,页面样式等问题,全部由前端工程师来负责。接口数据出错,数据没有提交成功,应答超时等问题,全部由后端工程师来解决。
3.减少后端服务器的负载压力。除了接口以外的其他所有http请求全部转移到前端服务器上。
4.即使后端服务暂时超时或者宕机了,前端页面也会正常访问,只不过数据刷不出来而已。
5.也许你也需要有微信相关的轻应用,那样你的接口完全可以共用,如果也有app相关的服务,那么只需要通过一些代码重构,也可以大量复用接口,提升效率。(多端应用)
6.页面显示的东西再多也不怕,因为是异步加载。
7.nginx支持页面热部署,不用重启服务器,前端升级更无缝。
8.增加代码的维护性和易读性(前后端混在一起的代码读起来相当费劲)。
9.提升开发效率,因为可以前后端并行开发,而不是像以前的强依赖。
10.在nginx中部署证书,外网使用https访问,并且只开放443和80端口,其他端口一律关闭(防止黑客端口扫描),内网使用http,性能和安全都有保障。
11.前端大量的组件代码得以复用,组件化,提升开发效率。
MVVM是Model-View-ViewModel的简写。MVVM就是将其中的View的状态和行为抽象化,让我们将视图UI和业务逻辑分开。当然这些事ViewModel已经帮我们做了,它可以取出Model的数据同时帮忙处理View中由于需要展示内容而涉及的业务逻辑。
Vue是一套用于构建用户界面的渐进式框架。与其他大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
Vue.js是前端的主流框架之一,和Angular.js、React.js一起,并成为前端三大主流框架。
1.体积小 压缩后33k
2.更高的运行效率
用JQuery或者原生的JavaScript DOM操作函数对DOM进行频繁操作的时候,浏览器要不停的渲染新的DOM树,导致页面看起来非常卡顿。
基于虚拟dom,一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化的技术,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM,最后在计算完毕才真正将DOM操作提交,将DOM操作变化反映到DOM树上。
3.双向数据绑定,简化DOM操作
通过MVVM思想实现数据的双向绑定,让开发者不再操作DOM对象,把更多的精力投入到业务逻辑上。
4.生态丰富,学习成本低
市场上拥有大量成熟、稳定的基于vue.js的UI框架、常用组件,来实现快速开发,对初学者友好,入门容易,学习资料多。
1.导入开发版本的Vue.js
2.创建Vue实例对象,设置el属性和data属性
3.使用简洁的模板语法把数据渲染到页面上
Vue.js的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进DOM的系统:
代码解析:
{{变量}}模板语法,插值表达式获取数据
new Vue();创建Vue对象(VM对象)
el:数据挂载的dom对象
Vue会管理el选项命中的元素及其内部的后代元素
可以使用其他的选择器,但是建议使用ID选择器
可以使用其他的闭合标签,不能使用html和body
data:{message:‘hello world’}model数据
Vue中用到的数据定义在data中
data中可以写复杂类型的数据,如对象,数组
渲染复杂类型数据时,遵守js的语法即可
Vue.js使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。所有Vue.js的模板都是合法的HTML,所以能被遵循规范的浏览器和HTML解析器解析。
在底层的实现上,Vue将模板编译成虚拟DOM渲染函数。结合响应系统,Vue能够智能地计算出最少需要重新渲染多少组件,并把DOM操作次数减到最小。
插值文本
数据绑定最常见的形式就是使用“Mustache”语法(双大括号)的文本插值:< span>Message:{{msg}}< /span>,Mustache标签将会被替代为对应数据对象上msg property的值。无论何时,绑定的数据对象上msg property发生了改变,插值处的内容都会更新。
使用JavaScript
迄今为止,在我们的模板中,我们一直都只绑定简单的property键值。但实际上,对于所有的数据绑定,Vue.js都提供了完全的JavaScript表达式支持。
{{number+1}}
{{ok?‘YES’:‘NO’}}
{{message.split(’’).reverse().join(’’)}}
< div v-bind:id="‘list-’+id">< /div>
这些表达式会在所属Vue实例的数据作用域下作为JavaScript被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
< !-- 这是语句,不是表达式 -->
{{var a=1}}
< !-- 流程控制也不会生效,请使用三元表达式 -->
{{if(ok){return message} }}
指令带有前缀v-开头,以表示它们是Vue提供的特殊属性。
v-text
作用是设置标签的文本内容
默认写法会替换全部内容,使用插值表达式可以替换指定内容
内部支持写表达式
<span v-text="message">aaaspan>
<span v-text="message+1">span>
< b>hello Vue!< /b> < b>hello Vue!< /b>1
v-html
作用是设置元素的innerHTML
内容中有html结构会被解析为标签
内容支持写表达式
<span v-html="message+1">指令绑定的内容会覆盖标签内的内容span>
hello Vue!1
v-on
作用是为元素绑定事件
事件名不需要写on指令可以简写为@
绑定的方法定义在methods属性中,可以传入自定义参数
<input type="button" value="操作1" v-on:click="oper()"/>
<input type="button" value="操作2" @click="test(1,2)" />
methods:{
oper(){
this.message = "aaaaaaaaaaaaaa"
},
test(a,b){
console.log(a,b)
}
}
v-model
作用是便捷的设置和获取表单元素的值
绑定的数据会和表单元素值相关联
绑定的数据< ---->表单元素的值,双向数据绑定
<input type="text" v-model="name">
<p>{{name}}p>
data:{
message:"hello Vue!",
name:""
},
v-show
作用是根据真假切换元素的显示状态
原理是修改元素的display,实现显示隐藏
指令后面的内容,最终都会被解析为布尔值
值为true元素显示,值为false元素隐藏
数据改变之后,对应元素的显示状态会同步更新
<img src="img/1.1.jpg" v-show="isShow" />
data:{
isShow:false
},
v-if
作用是根据表达式的真假切换元素的显示状态
本质是通过操纵dom元素来切换
显示状态表达式的值为true,元素存在dom中,为false,从dom中移除
频繁的切换v-show,反之使用v-if,前者的切换消耗小
v-bind
作用是为元素绑定属性
完整的写法是v-bind:属性名
简写的话可以直接省略v-bind,只保留:属性名
需要动态的增删class属性可以使用三元运算符,也可以使用对象的方式
<input type="button" value="切换" v-on:click="oper()" />
<img v-bind:src="imgsrc" />
<img :src="imgsrc" :title="title"/>
<img v-bind:src="imgsrc" :title="title" :class="isimg?'imgcss1':'imgcss2'" />
<img v-bind:src="imgsrc" :title="title" :class="{'imgcss1':isimg}"/>
data:{
imgsrc:"img/1.1.jpg",
i:1,
title:"这是图片",
isimg:false
},
methods:{
oper(isshow){
this.i++
this.imgsrc="img/1."+this.i+".jpg"
this.title = "这是图片"+this.i
}
}
v-for
作用是根据数据生成列表结构
数组经常和v-for结合
使用语法是(item,index)in数据
item和index可以结合其他指令一起使用
数组长度的更新会同步到页面上是响应式的
为循环绑定一个key值:key="值"尽可能唯一
<select>
<option v-for="(c,index) in city">
{{c}}{{index}}
option>
select>
<select v-model="cityid">
<option v-for="c in cityobj" :value="c.id">
{{c.name}}
option>
select>
data:{
cityid:0,
city:["北京","上海","西安"],
cityobj:[{id:1,name:"北京"},{id:2,name:"上海"},{id:3,name:"西安"}]
},
当一个Vue实例被创建时,它将data对象中的所有的property加入到Vue的响应式系统中,当这些property的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
<div id="app">
{{a}}
div>
var data = {a:1};
var vm = new Vue({ el:"#app", data: data })
vm.a == data.a // => true
data.a=2; vm.a-->2;
vm.a=3; date.a-->3;
一方的值发生修改时都会对原始数据发生改变,当这些数据改变时,视图会进行重渲染。
每个Vue实例在被创建时都要经过一系列的初始化过程——例如:需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM等。同时这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
beforeCreate:function(){//创建之前
console.log("beforeCreate")
},
created:function() {//创建以后
console.log("created")
},
beforeMount:function() {//挂载标签以前
console.log("beforeMount")
},
mounted:function() {//挂载标签以后
console.log("mounted")
}
组件是可复用的vue实例,说白了就是一组可以重复使用的模板,且带有一个名字。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
为了能在模板中使用,这些组件必须先注册以便Vue能够识别。这里有两种组件的注册类型:全局注册和局部注册。至此,我们的组件都只是通过Vue.component全局注册的:
<template id="mycomId"><h1>这是自定义的一个组件{{name}}h1>template>
Vue.component("mycom",{
//template:"<h1>这是自定义的一个组件h1>" 模板
template:"#mycomId" ,//为组件挂载标签内容
data:function(){//定义组件内自己的数据
return{
name:"jim"
}
}
})
定义组件:
button-counter 的新组件
Vue.component(‘组件名’,{template:‘模板内容’});
Vue.component(‘组件名’,{template:’#id名’});
组件中的数据
export default {
data: function () {
return {
count:0,
msg:"组件数据"
}
}
}
一个组件的data选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。
组件中的函数
methods:{
add:function(){
this.count++;
}
}
vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板;预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,我们的开发更加的快速。
1.主要的功能
2.需要的环境
(1)Node.js
简单的说Node.js就是运行在服务器端的JavaScript。如果你熟悉JavaScript,那么你将会很容易的学会Node.js.
Node.js是一个基于Chrome JavaScript运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行JavaScript的速度非常快,性能非常好。
(2)npm
npm是Node.js的包管理工具,用来安装各种Node.js的扩展。npm是JavaScript的包管理工具,也是世界上最大的软件注册表。nmpm让JavaScript开发人员可以轻松地使用其他开发人员共享的代码。
npm由三个不同的部分组成:
网站、注册表、命令行界面(CLI)
安装Node.js淘宝镜像加速器(cnpm)-g就是全局安装
npm install cnpm -g
安装的位置:c:\Users\Administrator\AppData\Roaming\npm
安装vue-cli
npm install vue-cli -g
测试是否安装成功
vue list
3.创建第一个vue-cli项目
(1)创建一个Vue项目,在电脑上硬盘中建立一个空的文件夹,用来存储项目文件
(2)创建一个基于webpack模板的vue应用程序
vue init webpack vuedemo(项目名)
(3)初始化项目
进入项目目录内
npm install
注意:修改项目内的版本号,安装完成后,如果有报错,根据提示修复即可。
(4)启动项目
npm run dev
(5)访问项目
http://127.0.0.1:8080/
ctrl+c 停止服务
4.项目结构
Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,让构建单页面应用变得易如反掌。
安装
vue-router是一个插件包,所以我们还是需要用npm来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令:
npm install vue-router --save-dev
使用步骤:
1.创建router目录
创建index.js文件,在其中配置路由
import Vue from 'vue';
import router from 'vue-router'; /* 导入路由 */
import success from '../success'
import login from '../login'; /* 导入其他页面 */
import userList from '../view/user/list.vue'
import roleList from '../view/role/list.vue'
Vue.use(router)
/* 定义组件路由 */
const rout = new router({
routes: [{
path: '/login',//映射地址
name: 'login',
component: login//绑定组件
},
{
path: '/succ',
component: success,
children:[
{path:"/userList",component:userList},
{path:"/roleList",component:roleList}
]
}
]
})
/* 导出路由组件 */
export default rout;
2.使用路由
<!-- 跳转到登录页面-->
<router-link to="/login">登录</router-link>
<router-link to="/succ">成功</router-link>
<!-- 显示路由对应的组件内容-->
<router-view></router-view>
3.在main.js中配置路由
import router from './router'
Vue.use(router);
new Vue({
el: '#app',
components: {
index
},
router,
render: h => h(index),
template: ' '
})
路由导航守卫
为路由对象,添加beforeEach导航守卫
to-将要访问的页面,from-从哪个页面访问的,next-放行函数
/* 导出路由组件 */
export default rout;
//路由导航守卫
rout.beforeEach((to, from, next) => {
//如果用户访问的登录页, 直接放行
if (to.path == '/login') {
return next();// to要去的页面路由 next()向下走
} else {
const account = window.sessionStorage.getItem("account");
if (account == null) {
return next("/login");
} else {
next();
}
}
})
axios是一个HTTP的网络请求库
安装npm install axios
在main.js中配置axios
导入axios
import axios from ‘axios’;
设置访问后台的服务器地址
axios.defaults.baseURL = “http://127.0.0.1:9999/api/”
将axios挂载到vue全局对象中,使用this可以直接访问
Vue.prototype.$http = axios
使用get或post方法即可发送对应的请求
then方法中的回调函数会在请求成功或失败时触发
通过回调函数的形参可以获取响应内容,或错误信息
基本语法
this.$http.get(地址?key-value&key2=values).then(function(response){},function(err){})
this.$http.post("login",{key:"value",key2:"value2"}).then(function(response){},function(err){})
axios的常用API
get:查询数据
post:添加数据
put:修改数据
delete:删除数据
axios的响应结果
响应结果的主要属性
data:实际响应回来的数据
headers:响应头信息
status:响应状态码
statusText:响应状态信息
//axios 请求拦截 网络请求拦截器
axios.interceptors.request.use(
config =>{//为请求头对象,添加 Token 验证的 token 字段
config.headers.token = window.sessionStorage.getItem('token');
return config;
})
// 添加响应拦截器
axios.interceptors.response.use((res) =>{
if(res.data.code==202){
router.replace("/login");
}
if(res.data.code==500){
this.$message({ message: res.data.msg, type: 'error' });
}
return res;
});
本质上,webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。
Webpack是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源,还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。