• ElementUI之登录与注册


    目录

    一.前言

    二.ElementUI的简介

    三.登录注册前端界面的开发

    三.vue axios前后端交互--- Get请求

    四.vue axios前后端交互--- Post请求

    五.跨域问题


    一.前言

            这一篇的知识点在前面两篇的博客中就已经详细详解啦,包括如何环境搭建和如何建一个spa项目等等知识点,非常详细,大家如果有看不懂的地方可以看我前面两篇的博客,或者也可以私信问我哦~~上两篇的博客链接放下面啦!!
    http://t.csdn.cn/uQqQ0icon-default.png?t=N7T8http://t.csdn.cn/uQqQ0        http://t.csdn.cn/PNTPEicon-default.png?t=N7T8http://t.csdn.cn/PNTPE

    二.ElementUI的简介

            Element的官网:

    Element - 网站快速成型工具icon-default.png?t=N7T8https://element.eleme.cn/#/zh-CN        ElementUI 是一套基于 Vue.js 的桌面端 UI 组件库,它提供了丰富的组件和工具,可以帮助开发者快速构建出美观、灵活和易于维护的网页应用程序。

            ElementUI 提供了众多常用的 UI 组件,例如按钮、输入框、表格、弹窗等,这些组件都经过精心设计和实现,具备良好的可定制性,可以满足各种不同场景的需求。

            ElementUI 还提供了一些实用的功能组件,如表单验证、数据展示、数据交互等,能够帮助开发者简化开发流程,提高开发效率。

    三.登录注册前端界面的开发

            我们先来创建一个spa项目,在cmd窗口输入:

            vue init webpack 项目名

    ·        接着下载Element依赖,在cmd窗口输入:

    npm install element-ui -S

            建立两个登录和注册的页面,并且使用ElementUI里的组件搭建页面以及样式

    登录:

    1. <template>
    2. <div class="login-wrap">
    3. <el-form class="login-container">
    4. <h1 class="title">用户登录</h1>
    5. <el-form-item label="">
    6. <el-input type="text" v-model="username" placeholder="登录账号" autocomplete="off"></el-input>
    7. </el-form-item>
    8. <el-form-item label="">
    9. <el-input type="password" v-model="password" placeholder="登录密码" autocomplete="off"></el-input>
    10. </el-form-item>
    11. <el-form-item>
    12. <el-button type="primary" style="width:100%;" @click="doSubmit()">提交</el-button>
    13. </el-form-item>
    14. <el-row style="text-align: center;margin-top:-10px">
    15. <el-link type="primary">忘记密码</el-link>
    16. <el-link type="primary" @click="gotoRegister()">用户注册</el-link>
    17. </el-row>
    18. </el-form>
    19. </div>
    20. </template>
    21. <script>
    22. export default {
    23. name: 'Login',
    24. data () {
    25. return {
    26. username:"",
    27. password:""
    28. }
    29. },
    30. methods:{
    31. gotoRegister(){
    32. this.$router.push("/Register")
    33. }
    34. }
    35. }
    36. </script>
    37. <style scoped>
    38. .login-wrap {
    39. box-sizing: border-box;
    40. width: 100%;
    41. height: 100%;
    42. padding-top: 10%;
    43. background-image:
    44. /* background-color: #112346; */
    45. background-repeat: no-repeat;
    46. background-position: center right;
    47. background-size: 100%;
    48. }
    49. .login-container {
    50. border-radius: 10px;
    51. margin: 0px auto;
    52. width: 350px;
    53. padding: 30px 35px 15px 35px;
    54. background: #fff;
    55. border: 1px solid #eaeaea;
    56. text-align: left;
    57. box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
    58. }
    59. .title {
    60. margin: 0px auto 40px auto;
    61. text-align: center;
    62. color: #505458;
    63. }
    64. </style>

    注册:

    1. <template>
    2. <div class="login-wrap">
    3. <el-form class="login-container">
    4. <h1 class="title">用户注册</h1>
    5. <el-form-item label="">
    6. <el-input type="text" v-model="username" placeholder="登录账号" autocomplete="off"></el-input>
    7. </el-form-item>
    8. <el-form-item label="">
    9. <el-input type="password" v-model="password" placeholder="登录密码" autocomplete="off"></el-input>
    10. </el-form-item>
    11. <el-form-item>
    12. <el-button type="primary" style="width:100%;" @click="doSubmit()">提交</el-button>
    13. </el-form-item>
    14. <el-row style="text-align: center;margin-top:-10px">
    15. <el-link type="primary">忘记密码</el-link>
    16. <el-link type="primary" @click="gotoLogin()">用户登录</el-link>
    17. </el-row>
    18. </el-form>
    19. </div>
    20. </template>
    21. <script>
    22. export default {
    23. name: 'Register',
    24. data () {
    25. return {
    26. username:"",
    27. password:""
    28. }
    29. },
    30. methods:{
    31. gotoLogin(){
    32. this.$router.push("/")
    33. }
    34. }
    35. }
    36. </script>
    37. <style scoped>
    38. .login-wrap {
    39. box-sizing: border-box;
    40. width: 100%;
    41. height: 100%;
    42. padding-top: 10%;
    43. background-image:
    44. /* background-color: #112346; */
    45. background-repeat: no-repeat;
    46. background-position: center right;
    47. background-size: 100%;
    48. }
    49. .login-container {
    50. border-radius: 10px;
    51. margin: 0px auto;
    52. width: 350px;
    53. padding: 30px 35px 15px 35px;
    54. background: #fff;
    55. border: 1px solid #eaeaea;
    56. text-align: left;
    57. box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
    58. }
    59. .title {
    60. margin: 0px auto 40px auto;
    61. text-align: center;
    62. color: #505458;
    63. }
    64. </style>

         APP.vue里面的样式也添加以下:

    1. <style>
    2. html,
    3. body {
    4. width: 100%;
    5. height: 100%;
    6. box-sizing: border-box;
    7. padding: 0px;
    8. margin: 0px;
    9. }
    10. #app {
    11. font-family: "Avenir", Helvetica, Arial, sans-serif;
    12. -webkit-font-smoothing: antialiased;
    13. -moz-osx-font-smoothing: grayscale;
    14. color: #2c3e50;
    15. widows: 100%;
    16. height: 100%;
    17. }
    18. style>

      下一步就是配置路由啦

    1. import Vue from 'vue'
    2. import Router from 'vue-router'
    3. import HelloWorld from '@/components/HelloWorld'
    4. import Login from '@/views/Login'
    5. import Register from '@/views/Register'
    6. Vue.use(Router)
    7. export default new Router({
    8. routes: [{
    9. path: '/',
    10. name: 'Login',
    11. component: Login
    12. },
    13. {
    14. path: '/Register',
    15. name: 'Register',
    16. component: Register
    17. }
    18. ]
    19. })

    好啦,最后看效果:

    三.vue axios前后端交互--- Get请求

            接下来使用SSM项目构建Java后台,模拟提供一个用户登录的action地址,Vue通过请求指定的用户登录接口。

            在Idea软件中写登录的后台,如何创建Idea项目,自动生成方法,Dao方法等,在之前的博客中我已经和大家介绍过了,大家可以去看,找不到的可以私信我哦~,具体的博客链接放下方啦

    http://t.csdn.cn/PQag3icon-default.png?t=N7T8http://t.csdn.cn/PQag3注册的方法:

    1. package com.zking.ssm.service;
    2. import com.zking.ssm.model.Region;
    3. import com.zking.ssm.util.PageBean;
    4. import org.springframework.stereotype.Repository;
    5. import java.util.List;
    6. public interface IRegionService {
    7. List queryRegionPager(Region region, PageBean pageBean);
    8. List queryRegionById(Region region);
    9. }

    写一个注册的web层

    1. package com.zking.ssm.controller;
    2. import com.zking.ssm.model.Region;
    3. import com.zking.ssm.service.IRegionService;
    4. import com.zking.ssm.util.JsonResponseBody;
    5. import com.zking.ssm.util.PageBean;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.stereotype.Controller;
    8. import org.springframework.web.bind.annotation.RequestMapping;
    9. import org.springframework.web.bind.annotation.RestController;
    10. import javax.servlet.http.HttpServletRequest;
    11. import java.util.List;
    12. @RestController
    13. @RequestMapping("/region")
    14. public class RegionController {
    15. @Autowired
    16. private IRegionService regionService;
    17. @RequestMapping("/queryRegionPager")
    18. public JsonResponseBody> queryRegionPager(Region region, HttpServletRequest request){
    19. try {
    20. PageBean pageBean=new PageBean();
    21. pageBean.setRequest(request);
    22. List regions = regionService.queryRegionPager(region, pageBean);
    23. return new JsonResponseBody<>("OK",true,pageBean.getTotal(),regions);
    24. } catch (Exception e) {
    25. e.printStackTrace();
    26. return new JsonResponseBody<>("分页查询行政区划信息失败",false,0,null);
    27. }
    28. }
    29. @RequestMapping("/queryRegionById")
    30. public JsonResponseBody> queryRegionById(Region region){
    31. try {
    32. List regions = regionService.queryRegionById(region);
    33. return new JsonResponseBody<>("OK",true,0,regions);
    34. } catch (Exception e) {
    35. e.printStackTrace();
    36. return new JsonResponseBody<>("初始化行政区划代码失败",false,0,null);
    37. }
    38. }
    39. }

    写一个登录的web层:

    1. package com.zking.ssm.controller;
    2. import com.zking.ssm.service.IUserService;
    3. import com.zking.ssm.util.JsonResponseBody;
    4. import com.zking.ssm.util.PageBean;
    5. import com.zking.ssm.vo.UserVo;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.stereotype.Controller;
    8. import org.springframework.web.bind.annotation.RequestMapping;
    9. import org.springframework.web.bind.annotation.ResponseBody;
    10. import javax.servlet.http.HttpServletRequest;
    11. import javax.servlet.http.HttpServletResponse;
    12. import java.util.HashMap;
    13. import java.util.List;
    14. import java.util.Map;
    15. import com.zking.ssm.jwt.*;
    16. @Controller
    17. @RequestMapping("/user")
    18. public class UserController {
    19. @Autowired
    20. private IUserService userService;
    21. @RequestMapping("/userLogin")
    22. @ResponseBody
    23. public JsonResponseBody<?> userLogin(UserVo userVo, HttpServletResponse response){
    24. if(userVo.getUsername().equals("admin")&&userVo.getPassword().equals("123")){
    25. //私有要求claim
    26. // Map<String,Object> json=new HashMap<String,Object>();
    27. // json.put("username", userVo.getUsername());
    28. //生成JWT,并设置到response响应头中
    29. // String jwt=JwtUtils.createJwt(json, JwtUtils.JWT_WEB_TTL);
    30. // response.setHeader(JwtUtils.JWT_HEADER_KEY, jwt);
    31. return new JsonResponseBody<>("用户登陆成功!",true,0,null);
    32. }else{
    33. return new JsonResponseBody<>("用户名或密码错误!",false,0,null);
    34. }
    35. }
    36. @RequestMapping("/queryUserPager")
    37. @ResponseBody
    38. public JsonResponseBody<List<Map<String,Object>>>
    39. queryUserPager(UserVo userVo, HttpServletRequest request){
    40. try {
    41. PageBean pageBean=new PageBean();
    42. pageBean.setRequest(request);
    43. List<Map<String, Object>> users = userService.queryUserPager(userVo, pageBean);
    44. return new JsonResponseBody<>("OK",true,pageBean.getTotal(),users);
    45. } catch (Exception e) {
    46. e.printStackTrace();
    47. return new JsonResponseBody<>("分页查询用户信息失败!",false,0,null);
    48. }
    49. }
    50. }

    后台就写好啦!接下来写前台:

    在此之前先来安装axios

    axios是vue2提倡使用的轻量版的ajax。它是基于promise的HTTP库。它会从浏览器中创建XMLHttpRequests,与Vue配合使用非常好。

    在cmd窗口中输入:

    npm i axios -S

     接着在Login.vue页面写逻辑代码:                                                                                           
    1. <script>
    2. import axios from 'axios'
    3. export default {
    4. name: 'Login',
    5. data() {
    6. return {
    7. username: "",
    8. password: ""
    9. }
    10. },
    11. methods: {
    12. gotoRegister() {
    13. this.$router.push("/Register")
    14. },
    15. doSubmit() {
    16. let url = "http://localhost:8080/ssm/user/userLogin";
    17. let params = {
    18. username: this.username,
    19. password: this.password
    20. };
    21. axios.get(url, {
    22. params: params
    23. }).then(r => {
    24. if (r.data.success) {
    25. this.$message({
    26. showClose: true,
    27. message: r.data.msg,
    28. type: 'success'
    29. });
    30. }else{
    31. this.$message.error(r.data.msg)
    32. }
    33. }).catch(e => {
    34. });
    35. }
    36. }
    37. }
    38. script>
    注册也是一样:
    1. <script>
    2. import axios from 'axios'
    3. export default {
    4. name: 'Register',
    5. data() {
    6. return {
    7. username: "",
    8. password: ""
    9. }
    10. },
    11. methods: {
    12. gotoLogin() {
    13. this.$router.push("/")
    14. },
    15. doSubmit() {
    16. let url = "http://localhost:8080/ssm/region/queryRegionPager";
    17. let params = {
    18. username: this.username,
    19. password: this.password
    20. };
    21. axios.get(url, {
    22. params: params
    23. }).then(r => {
    24. if (r.data.success) {
    25. this.$message({
    26. showClose: true,
    27. message: r.data.msg,
    28. type: 'success'
    29. });
    30. }else{
    31. this.$message.error(r.data.msg)
    32. }
    33. }).catch(e => {
    34. });
    35. }
    36. }
    37. }
    38. script>

    接下俩看效果吧!!

    四.vue axios前后端交互--- Post请求

            在写post请求之前可以发现我们可以在此基础之上做优化,将地址可以单独做一个类

    action.js将接口单独领出来做一个类

     将配置也可以单独领出来做一个类 http.js

    1. /**
    2. * vue项目对axios的全局配置
    3. */
    4. import axios from 'axios'
    5. import qs from 'qs'
    6. //引入action模块,并添加至axios的类属性urls上
    7. import action from '@/api/action'
    8. axios.urls = action
    9. // axios默认配置
    10. axios.defaults.timeout = 10000; // 超时时间
    11. // axios.defaults.baseURL = 'http://localhost:8080/j2ee15'; // 默认地址
    12. axios.defaults.baseURL = action.SERVER;
    13. //整理数据
    14. // 只适用于 POST,PUT,PATCH,transformRequest` 允许在向服务器发送前,修改请求数据
    15. axios.defaults.transformRequest = function(data) {
    16. data = qs.stringify(data);
    17. return data;
    18. };
    19. // 请求拦截器
    20. axios.interceptors.request.use(function(config) {
    21. return config;
    22. }, function(error) {
    23. return Promise.reject(error);
    24. });
    25. // 响应拦截器
    26. axios.interceptors.response.use(function(response) {
    27. return response;
    28. }, function(error) {
    29. return Promise.reject(error);
    30. });
    31. // // 路由请求拦截
    32. // // http request 拦截器
    33. // axios.interceptors.request.use(
    34. // config => {
    35. // //config.data = JSON.stringify(config.data);
    36. // //config.headers['Content-Type'] = 'application/json;charset=UTF-8';
    37. // //config.headers['Token'] = 'abcxyz';
    38. // //判断是否存在ticket,如果存在的话,则每个http header都加上ticket
    39. // // if (cookie.get("token")) {
    40. // // //用户每次操作,都将cookie设置成2小时
    41. // // cookie.set("token", cookie.get("token"), 1 / 12)
    42. // // cookie.set("name", cookie.get("name"), 1 / 12)
    43. // // config.headers.token = cookie.get("token");
    44. // // config.headers.name = cookie.get("name");
    45. // // }
    46. // return config;
    47. // },
    48. // error => {
    49. // return Promise.reject(error.response);
    50. // });
    51. // // 路由响应拦截
    52. // // http response 拦截器
    53. // axios.interceptors.response.use(
    54. // response => {
    55. // if (response.data.resultCode == "404") {
    56. // console.log("response.data.resultCode是404")
    57. // // 返回 错误代码-1 清除ticket信息并跳转到登录页面
    58. // // cookie.del("ticket")
    59. // // window.location.href='http://login.com'
    60. // return
    61. // } else {
    62. // return response;
    63. // }
    64. // },
    65. // error => {
    66. // return Promise.reject(error.response) // 返回接口返回的错误信息
    67. // });
    68. export default axios;

    现在开始用post的请求写一遍吧!!

           先要下载一个post请求需要的在cmd中输入:

    npm install qs -S

    接着,前面将接口类和配置单独领出来了,所以要建立连接,需要下载一个vue-axios,在cmd中输入:

    npm i vue-axios -S

    再将刚刚那一串get请求换成post请求,注册也是一样

    1. // post请求
    2. this.axios.post(url,params).then(r => {
    3. if (r.data.success) {
    4. this.$message({
    5. showClose: true,
    6. message: r.data.msg,
    7. type: 'success'
    8. });
    9. }else{
    10. this.$message.error(r.data.msg)
    11. }
    12. }).catch(e => {
    13. });

    接下来看效果,和上面的get请求时一样的

    五.跨域问题

            在使用Vue开发前端应用时,如果前端代码部署在一个域名下,而后端接口部署在另一个域名下,就会出现跨域问题。跨域是指在浏览器中,当发起一个HTTP请求时,如果请求的目标域名、端口或协议与当前页面的域名、端口或协议不一致,就会触发跨域。

    当出现跨域问题时,浏览器会阻止跨域请求,并在控制台中报错:

    "Access to XMLHttpRequest at 'url' from origin 'origin' has been blocked by CORS policy.":这是最常见的跨域错误,表示浏览器拒绝了跨域请求。这是因为浏览器的同源策略限制了跨域请求。

    在上面的代码中没有报跨域问题是因为,在web.xml配置文件中

    也写了一个跨域工具类

    1. package com.zking.ssm.util;
    2. import java.io.IOException;
    3. import javax.servlet.Filter;
    4. import javax.servlet.FilterChain;
    5. import javax.servlet.FilterConfig;
    6. import javax.servlet.ServletException;
    7. import javax.servlet.ServletRequest;
    8. import javax.servlet.ServletResponse;
    9. import javax.servlet.http.HttpServletRequest;
    10. import javax.servlet.http.HttpServletResponse;
    11. /**
    12. * 配置tomcat允许跨域访问
    13. *
    14. * @author Administrator
    15. *
    16. */
    17. public class CorsFilter implements Filter {
    18. @Override
    19. public void init(FilterConfig filterConfig) throws ServletException {
    20. }
    21. @Override
    22. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
    23. throws IOException, ServletException {
    24. HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
    25. HttpServletRequest req = (HttpServletRequest) servletRequest;
    26. // Access-Control-Allow-Origin就是我们需要设置的域名
    27. // Access-Control-Allow-Headers跨域允许包含的头。
    28. // Access-Control-Allow-Methods是允许的请求方式
    29. httpResponse.setHeader("Access-Control-Allow-Origin", "*");// *,任何域名
    30. httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
    31. //允许客户端发一个新的请求头jwt
    32. httpResponse.setHeader("Access-Control-Allow-Headers","responseType,Origin,X-Requested-With, Content-Type, Accept, jwt");
    33. //允许客户端处理一个新的响应头jwt
    34. httpResponse.setHeader("Access-Control-Expose-Headers", "jwt,Content-Disposition");
    35. //httpResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    36. //httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
    37. // axios的ajax会发两次请求,第一次提交方式为:option,直接返回即可
    38. if ("OPTIONS".equals(req.getMethod())) {
    39. return;
    40. }
    41. filterChain.doFilter(servletRequest, servletResponse);
    42. }
    43. @Override
    44. public void destroy() {
    45. }
    46. }

    好啦!,今天的分享就到这啦!!

  • 相关阅读:
    RHCE8 资料整理(二)
    yolov5剪枝实战2:网络剪枝原理介绍
    Burp suite常用操作(Target、Option)
    PLC中ST编程的比较运算
    GP规范--STORE DATA
    预测杭州五一黄金周的旅游出行人数
    AGI STK EOIR对地精细成像
    【无标题】
    【Azure Key Vault】在Azure Databricks上获取Azure Key Vault中所存储的机密(secret)的两种方式
    Linux——进程信号
  • 原文地址:https://blog.csdn.net/YZZdear/article/details/133180310