Vue 实现前后端分离项目

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。

Vue实现前后端分离项目的初体验

经过之前学习的Vue的知识:

  • vue基本指令
  • vue组件
  • vue-resource
  • vue路由

其实我们已经可以开始实战运用到实际的Web项目中了,由于本人是Java后端开发的,所以后端是基于SpringMVC的。

以下我们将演示如何使用Vue组件实现一个用户登录系统。

<!--more-->

介绍

后端

后端基于spring、springMVC、mybatis框架

对后端SSM框架搭建不熟悉的可以参考我的博文: SSM项目整合

前端

前端使用了wepack打包工具,利用了vue.cli脚手架快速搭建的项目。由于本人对一些技术也不是很熟悉,所以给大家提供些官方文档, 想要深入学习还是要仔细分析官方文档。传送门如下(也是本项目要用到的):

  • node.js
  • vue.js
  • vue-cli
  • vue-resource
  • vue-router
  • webpack
  • element-ui

以上技术都是比较常用的,webpack类似一个打包工具,它会将你项目中的Vue组件打包为一个庞大的js文件(当然我们是看不懂的),而我们的前端项目是部署在node.js提供的web容器中的。

即前后端分离的实际效果是这样的: 

有没有感觉很神奇,哈哈,反正我第一次见到的时候就是觉得很神奇,因为html中完全看不到任何js、css代码,但是却能渲染出来这么好看的页面。下面我们就讲一下,怎么实现这个过程吧!!

<br/>

环境

上面我们提到的技术,在本案例中都会遇到,后端的SSM框架请参考我的博客文档,介绍一下前端环境的搭建:

1、安装node.js

具体安装流程还是要去看node.js官网。如果安装完成,请在终端输入npm -v查看是否安装成功。一般会出现类似如下版本号:

v8.11.3

2、安装VueCLI脚手架

VueCLI能够帮助我们快速搭建一个webpack的项目。

在已经安装好node.js的前提上,在终端输入:npm install vue-cli -g开始安装VueCLI。如果安装完成,请在终端输入:vue -V,会出现如下版本信息:

2.9.6

具体安装流程可以参看:博文

由于VueCLI脚手架已经帮我们安装好了webpack、以及相关的node依赖包,所以我们不需要再手动安装了。

范例

如果安装完成,我们可以看到出现如下目录结构: 

启动项目

在终端项目路径下输入npm run dev命令;正常情况下,会出现如下信息:

在浏览器中输入指定的URL,会出现如下页面:

我们继续观察,打开项目中的index.html

我们看到,这个HTML中没有任何代码,甚至没有引入js、css,但是页面中的视图是怎样渲染出来的呢?

仔细看项目结构,我们能看到在src/components/下有一个HelloWorld.vue程序,我们页面中的程序就是通过这些.vue组件来渲染出来的。

打包项目

如果我们想将项目部署到服务器上,你放一堆.vue程序,浏览器是无法解析出来的,所以我们需要了解一下webpack的打包命令:

npm run build

正常情况下,会显示上图中的信息,表示打包成功了,会在项目根目录中生成一个叫dist的文件夹,里面是生成的静态项目:

我们双击dist/index.html,会看到和之前一样的页面,但是其中引入了一个XX.js文件

开始

经过上面的步骤我们应该了解到了所谓前端分离的简易概念,其实在之前的博文: Vue组件 我们已经了解到了Vue的模块化开发流程。配合.vue组件,其实思路还是相同的。

搭建前端

开始之前,我们首先要安装vue-resourceelement-ui),执行:

npm install vue-resource npm install element-ui

第一步:修改main.js

main.js文件是webpack的核心入口,我们需要在其中引入Vue-resource以及router

import VueResource from 'vue-resource'import router from './router/index.js'

在Vue实例中注册router

new Vue({router,
});

完整代码:

第二步:修改router/index.js

这是有关Vue路由的配置,前面我们也已经讲过了vue的路由,这里不再多说,代码如下:

如上就配置了,如果你访问localhost:8081/,那么就会自动路由跳转到login.vue组件中,提示我们登录;其中的/home表示,如果登录成功,就跳转到home.vue组件中,相当于登录成功后跳转到后台页面。

第三步:创建login.vue

src/components/下创建login.vue组件。

login组件中表单样式就不再讲了,我们主要看一下怎样利用v-model绑定表单数据,并请求后端

表单原型

<!-- 登录表单 -->
<el-form :model="login" status-icon :rules="rule" ref="login"><el-form-item prop="username"><el-input prefix-icon="el-icon-ump-yonghu" v-model="login.username"auto-complete="off"/></el-form-item><el-form-item prop="password"><el-input prefix-icon="el-icon-ump-mima" type="password" v-model="login.password"auto-complete="off"/></el-form-item><el-form-item><el-checkbox class="check" v-model="checked">记住我</el-checkbox></el-form-item><el-form-item><el-button class="btn" type="primary" @click="submitForm('login')">登录</el-button></el-form-item>
</el-form>
<div><p><a href="#" class="tips">还没有账号?点我去注册</a></p>
</div>

在上面的表单中,我们只需要关注三个点:

  • v-model="login.username"
  • v-model="login.password"
  • @click="submitForm('login')"

为什么不关注其他的? 注意,这个案例由于我使用了element-ui,从标签中就能看出来,其中涉及到了一些element-ui提供的js校验,我们只需要关注Vue的逻辑即可。

提交表单

关于上面提到的element-ui的校验部分 

表单提交方法部分

methods: {submitForm(login) {this.$refs[login].validate((valid) => {if (valid) {//提交表单this.$http.post('http://127.0.0.1:8080/login.do', {username: this.login.username,password: this.login.password}).then(result => {console.log(result);if (result.bodyText === 'index') {this.$router.push({ path: 'home' }); //跳转到home组件中} else {console.log("登录失败");return false;}});} else {console.log('error submit!!');return false;}});},
}

上面就是我们要讲到的核心部分:请求后端的接口

解释:

  • 首先需要注意的this.$refs[login].validate((valid)){}是element-ui提供的表单验证的逻辑,但是是结合vue.js的。因为我们若在不验证表单直接提交的时候,会在表单提交按钮中直接传@click="submitForm(login)",因为此时的login是一个data中已经声明的对象,其中包含两个参数:username,password。而element-ui提供的方式则会根据.validate()获取到login所包含的参数从而实现校验。

  • 经过上面的校验,如果校验成功,那么将调用this.$http.post()进行提交post表单,这是vue-resource提供的方式,博文 中我们也讲过。其中包含了两个参数,username,password。

  • 请求成功,调用.then()回获取到成功的请求结果。判断请求的结果:我这里是从后端返回的参数(return "index")中判断是否登录成功,如果能录成功,就应该跳转到home组件中。

  • 调用vue-router中提供的$router.push方法,我们可以理解为向Router对象中添加了一条路由地址,其URL是:path: 'home',那么就表明了会跳转带名字叫/home的路径下,整好对应的是我们配置好的home.vue组件。

注意:

  • 最重要的就是跨域请求问题,本例中node.js提供的web服务器地址是:127.0.0.1:8081,但是我们后端Tomcat服务器的地址是:127.0.0.1:8080,而默认是不能在一个域中访问另一个域中的资源的,所以也就出现了跨域请求的概念。

  • 其次重要的就是$http.post()的第一个参数:URL地址,不要写locahost:,不要写.... 具体原因不是很清楚,不然请求还会报错为跨域请求。

  • 解决跨域请求的方式也有很多,这里我提供一个比较简单的方式,只需要在后端的web.xml中提供一个允许跨域访问的过滤器就行了,后面会介绍。

  • 还有就是之前我们就说过Vue中默认提交的post请求时不包含表单格式的,所以需要配置,我已经在main.js中写了Vue.http.options.emulateJSON = true;设置全局表单提交格式,所以在post()方法中就没有设置。

第四部:创建home.vue

src/components/下创建home.vue组件

<br/> <br/>

搭建后端

经过上面介绍了前端搭建步骤后,搭建后端我们就相对熟悉了,我们的目标就是在controller中提供一个接口login.do让前端访问。

解决跨域请求

之前已经说了跨域请求很重要,不然我们写的所有请求都无法顺利访问后端接口。解决的方式如下:

配置

我们只需要在项目中的web.xml中配置如下代码即可。因为这个过滤器是tomcat提供的,所以我们并不需要导入任何jar包。

<!--配置允许跨域访问-->
<filter><filter-name>CorsFilter</filter-name><filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping><filter-name>CorsFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

Controller

讲了那么多,终于到了Controller层,这里就比较简单了,就是根据获取到的参数判断数据库中有没有对应的用户,有就登录成功,否者亏登录失败。

由于我这里使用了shiro,需要将密码加密处理,所以没有直接传入到service层,当然思路是相同的。

注意:

  • 我这个login.do接口返回的是JSON字符串,前面使用了@RestController注解,不要误认为是返回的页面,那么就会404的。
  • 接受的参数要用@RequestParam注解标记,不然会接受不到前端传递的数据

请求成功

跳转到home组件中:

转自:https://my.oschina.net/u/3955926/blog/1940500

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++对C的一些加强和变化

实用性加强&#xff1a; int main() {// C语言中的变量都必须在作用域开始的位置定义&#xff01;&#xff01;// C中更强调语言的“实用性”&#xff0c;所有的变量都可以在需要使用时再定义。for (int i 0; i < 10; i){std::cout << i << std::endl;}return…

优秀Unix管理员的七个习惯

摘要&#xff1a;Unix系统管理员可能会很懒或喜欢优雅的解决方法&#xff0c;这就是他们的存在之美。一位优秀的Unix系统管理员有着自己的习惯&#xff1a;不会等到问题来找你、精通所使用的工具和系统、确定事情优先次序和喜欢优雅的解决方案但不迷失等。 优秀的Unix系统管理员…

Vue.js 极简小例:读值、样式调用、if判断、a 标签、点击事件、管道

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 写法&#xff1a; <template><div id"app"><!-- 三目运算符使用 ‘ok’ 的值定义在 data 中-->{{ ok …

【快写】基本思路及模板

快读也可以了解一下 先从C自带的输出开始吧 cout<<n<<endl;这是最基本的输出&#xff0c;适合初学者 &#xff08;虽然我到现在都还在用&#xff09; 然后稍微快一点的输出 printf("%d",n);这个就比较快速了&#xff0c;但是对于那种毒瘤题目 故意卡你的…

C++与C中const的比较以及const和define的比较

C与C中const的比较&#xff1a; C语言中 const修饰的变量是一个 常变量&#xff0c;本质还是变量&#xff0c;有自己的地址空间C编译器对const常量的处理 当碰见常量声明时&#xff0c;在符号表中放入常量 > 问题&#xff1a;那又如何解释取地址编译过程中若发现对const使…

中国古典十大悲剧

一.《窦娥冤》  《窦娥冤》——元关汉卿 山阴书生窦天章因无力偿还蔡婆的高利贷&#xff0c;把七岁的女儿窦娥送给蔡婆当童养媳来抵债。窦娥长大后与蔡婆儿子成婚&#xff0c;婚后两年蔡子病死。后来蔡婆向赛卢医索债&#xff0c;被赛卢医骗至郊外谋害&#xff0c;为流氓张驴…

解决: Elements in iteration expect to have ‘v-bind:key‘ directives

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 报错&#xff1a; Elements in iteration expect to have v-bind:key directives 原本写法&#xff1a; <li v-for"site in s…

回来太多事需要处理

出差回来&#xff0c;发现太多事需要处理现在每个项目都在Delay。且没有一个人是主动汇报项目的。这是非常不正常的现象。感觉有点累转载于:https://www.cnblogs.com/boriscao/archive/2005/09/03/229368.html

不该失去的,一块钱也不放弃

很多人都觉得&#xff0c;有钱人既然财力雄厚&#xff0c;花钱时必定毫不手软。然而&#xff0c;观察成功的CEO&#xff0c;你会发现&#xff0c;他们多数人花钱也花得小心&#xff0c;对于什么该花、值得花&#xff0c;算得十分精细。 华人首富、香港长江实业与和记黄埔董事局…

C++之引用

普通引用和常引用 1. 变量名的回顾 变量名实质上是一段连续存储空间的别名&#xff0c;是一个标号(门牌号) 程序中通过变量来申请并命名内存空间 通过变量的名字可以使用存储空间 问题&#xff1a;一段连续的内存空间是否只能有一个别名吗&#xff1f; 2. C引用的概念 引…

Vue.js 极简小例:数值计算、千米换算为米、九九乘法表、循环

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 代码&#xff1a; <template><div id"app"><!-- 千米和米换算 --><div id "computed_props&quo…

shiro框架的学习

权限控制是shiro最核心的东西 Shiro权限声明通常是使用以冒号分隔的表达式。一个权限表达式可以清晰的指定资源类型&#xff0c;允许的操作&#xff0c;可访问的数据。同时&#xff0c;Shiro权限表达式支持简单的通配符&#xff0c;可以更加灵活的进行权限设置。 下面以实例来说…

C++之内联函数

内联函数是一种特殊的函数&#xff0c;具有普通函数的特征&#xff08;参数检查&#xff0c;返回类型等&#xff09; 内联函数是对编译器的一种请求&#xff0c;因此编译器可能拒绝这种请求 内联函数由 编译器处理&#xff0c;直接将编译后的函数体插入调用的地方 宏代码片段…

妈妈培养天才的13绝招

作父母的&#xff0c;都希望自己的宝宝可以变得聪明、懂事&#xff0c;所以想尽办法去让宝宝上早教班、做早期智力开发……当然&#xff0c;这些做法对于开发宝宝智力能够起到一定的帮助。但是&#xff0c;千万别忽视您所能给予宝宝的家庭教育。    近日&#xff0c;日本一位…

Vue.js 极简小例: 4 种方式样式绑定、style 的多种方式实现

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 代码&#xff1a; <template><div id"app"><!-- JSON方式使用样式 --><div v-bind:style"{ colo…

C++之默认参数

一、什么是默认参数 C中可以在函数声明时为参数提供一个默认值&#xff0c; 当函数调用时没有指定这个参数的值&#xff0c;编译器会自动用默认值代替 二、默认参数规则 只有参数列表后面部分的参数才可以提供默认参数值 一旦在一个函数调用中开始使用默认参数值&#xff…

50 Python - 装饰器 类定义装饰器

04 类定义装饰器 上节通过函数定义装饰器&#xff0c;本节通过类定义装饰器 001 定义类装饰器 定义一个类&#xff0c;类里面两个函数&#xff0c;一个构造函数init()&#xff0c;一个调用函数call() 构造函数init时候&#xff0c;传递一个函数func()进来 调用函数call()&#…

C++之过载函数

过载函数的定义&#xff1a; 用同一个函数名定义不同的函数 当函数名和不同的参数搭配时函数的含义不同 过载函数的判断标准&#xff1a; 函数重载至少满足下面的一个条件&#xff1a; 参数个数不同 参数类型不同 参数顺序不同 函数返回值不是函数重载的判断标准 调用…

人民币贬值会让八类人损失惨重!有你吗?

截至20日&#xff0c;人民币本周对美元累计贬值1.24%&#xff0c;年初以来不到三个月时间累计贬值2.79%。分析人士表示&#xff0c;人民币短期内仍有较强下跌压力。本轮人民币急贬预计将对几类人群收入造成严重冲击。 本周以来&#xff0c;人民币对美元即期汇价持续单边下跌。数…

Vue.js 极简小例: 点击事件

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 代码&#xff1a; <template><div> <!-- jy_mothed 是在 js 中自定义的方法 --><button v-on:click"jy_mot…