成品动画演示:?
在这里插入图片描述
具体步骤较多,一下午功夫吧!入门vue嘻嘻~ ?

正文

一、router路由配置

1.1 创建项目

vue脚手架项目

  1. 到工程目录下打开cmd,输入以下命令行,生成vue脚手架工程

    $ vue init webpack Vue_Springboot

  2. 接下来根据提示输入工程的信息
    vue-router需要安装,作为入门,我们选择不安装ESLint和所有测试工具

    ? Project name vue_springboot
    ? Project description A Vue.js project
    ? Author your name
    ? Vue build standalone
    ? Install vue-router? Yes
    ? Use ESLint to lint your code? No
    ? Set up unit tests No
    ? Setup e2e tests with Nightwatch? No
    ? Should we run npm install for you after the project has been created? (recommended) npm

  3. 脚手架工程安装完成后就可以用编译工具打开文件夹 Vue_Springboot我是用的HBuilder),目录如下,编程都在src目录下进行 (这是我全部创建完成后的目录,参照位置 创建和修改)
    在这里插入图片描述

1.2 router路由配置

  1. 先在目录src/components/ 下创建两个空文件Main.vueLogin.vue

  2. 创建工程时,会自动导入vue-router,不用手动创建的;
    若没有自动导入,则打开cmd在 Vue_Springboot目录下安装包如下

    cnpm intall vue-router

  3. 修改src/router/ 下创建index.js文件(仿照helloworld写路由)

    import Vue from 'vue'
    import Router from 'vue-router'
    import HelloWorld from '@/components/HelloWorld'
    import Main from '@/components/Main.vue'//【引入Main.vue模块,重命名为Main】
    import Login from '@/components/Login.vue'
    
    Vue.use(Router)//注册vue-router
    
    export default new Router({
      routes: [
        {
          path: '/',// 【路径】
          name: 'Main',// 【名字】,推荐,因为路径可能会改动,而 name 不会
          component: Main// 设置导向的【组件】页面,在上方import的重命名
        },
        {
          path: '/login',
          name: 'Login',
          component: Login
        },
      ]
    })
    
    
  4. main.js中引入前面的配置的路由

    import Vue from 'vue'
    import App from './App'
    import router from './router'//引入【路由配置】,其中“./router”特指router下index.js
    
    Vue.config.productionTip = false
    
    new Vue({
      el: '#app',
      router,// 调用,等价于 router: router
      components: { App },
      template: '<App/>'
    })
    
    
  5. 路由就设置成功了,接下来修改App.vue,Main.vue和Login.vue的代码

    • App.vue:删去了多余的样式
      <template>
        <div id="app">
          <img src="./assets/logo.png">
          <router-view/><!-- 路由注入的地方 -->
        </div>
      </template>
      
      <script>
      export default {
        name: 'App'
      }
      </script>
      
      <style></style>
      
      
    • Main.vue:首页,点击文字,url路径跳转到登录页面
      <template>
          <div>
              <h1>主页面</h1>
              欢迎!<b @click="login">点这里登录</b>
          </div>
      </template>
      
      <script>
          export default {
              methods: {
                  login () {
                      this.$router.replace('/login')
                  }
              }
          }
      </script>
      
      
    • Login.vue:简单的登录界面,如果登陆成功(这里没有其他页面,暂时返回首页)
      <template>
          <div>
              <h1>登录界面</h1>
              用户名:<Input /><br/>
              密码:<Input /><br/>
              <button @click="login">登录</button>
          </div>
      </template>
      
      <script>
          export default {
              methods: {
                  login () {
                      this.$router.replace('/')
                  }
              }
          }
      </script>
      

1.3 router测试 ?

  1. 路由模块运行
    输入cnpm run dev启动项目,热启动,边修改边响应
  2. 浏览器请求本地端口(点击登录实现页面切换,即router路由配置成功)
    在这里插入图片描述 在这里插入图片描述

二、element优化前端

2.1 引入element

引入Element框架对界面进行美化,并对表单添加基础的验证功能

  1. 打开cmd在 Vue_Springboot目录下安装包如下

    cnpm install element-ui -S

  2. 创建目录src/element/ ,并创建文件index.js
    在这里插入图片描述

  3. 修改index.js

    import Vue from 'vue'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    
    Vue.use(ElementUI)
    
    
  4. 然后在全局配置main.js中添加以下代码进行引入element

    import './element'//引入样式
    

2.2 修改整体布局

App.vue进行修改

<template>
  <div id="app">
    <el-container>
        <!-- 头部区域 -->
        <el-header class="header" height="100px">
          <h2>Vue登录模块</h2>
          <h4>路 由 配 置 登 录 跳 转</h4>
        </el-header>
        <!-- 主区域 -->
        <el-main>
          <router-view/><!-- 路由注入的地方 -->
        </el-main>
      </el-container>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
  .header{
    background-color: #409EFF;
    color: white;
  }
</style>

2.3 修改登录布局

Login.vue:前端样式判断提交不能为空,提交内容判断
在这里插入图片描述

<!--基本html代码区域-->
<template>
  <div class="logindemo">
    <el-form ref="form" :model="user" :rules="rules" status-icon label-width="100px">
      <el-row type="flex" justify="center">
        <el-col :span="5">
          <el-form-item label-width="70px">
            <span>
              <font color="#B3D8FF" size="5">注册登录页面</font>
            </span>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row type="flex" justify="center">
        <el-col :span="5">
          <el-form-item label="账户:" prop="name">
            <el-input v-model="user.name" size="small"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row type="flex" justify="center">
        <el-col :span="5">
          <el-form-item label="密码:" prop="password">
            <el-input v-model="user.password" size="small"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row type="flex" justify="center">
        <el-col :span="5">
          <el-form-item>
            <el-button type="primary" @click="submit">登录</el-button>
            <el-button @click="register">注册</el-button>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row type="flex" justify="center">
        <font color="pink" size="3">1.账户admin,密码123,登录<br>2.点击注册返回主页</font>
      </el-row>
    </el-form>
  </div>
</template>


<!--数据存贮交互,事件控制地区-->
<script>
  export default {
    name: 'logindemo',
    data() {
      return {
        user: {},
        rules: {
          name: [{
            required: true,
            message: '用户名不能为空',
            trigger: 'blur'
          }],
          password: [{
            required: true,
            message: '密码不能为空',
            trigger: 'blur'
          }],
        },
      }
    },
    methods: {
      /*提交进行判断的函数 */
      submit: function() {
        if (this.user.name === 'admin' && this.user.password === '123') {
          this.$notify({
            type: 'success',
            message: '欢迎你,' + this.user.name + '!',
            duration: 3000
          })
          this.$router.replace('/')
        } else {
          this.$message({
            type: 'error',
            message: '用户名或密码错误',
            showClose: true
          })
        }
      },
      register: function() {
        this.$router.replace('/') //返回主页
      },
    },
  }
</script>

<!-- 写样式的地方 -->
<style scoped>

</style>

2.4 登录验证测试 ?

  1. 验证是否为空:(mode模型user,传回user.name和user.password)
    :model 是传过来的一个对象
    :rules="rules" 是动态绑定的rules,表单验证规则
    status-icon是符号提示
    <div class="logindemo">
    	<el-form ref="form" :model="user" :rules="rules" status-icon label-width="100px">
    		<el-form-item label="账户:" prop="name">
    		</el-form-item>
    		<el-form-item label="密码:" prop="password">
    		</el-form-item>
    	</el-form>
    </div>
    
    在这里插入图片描述 在这里插入图片描述
  2. 登录验证:
    在这里插入图片描述
    在这里插入图片描述
    主要就是submit()函数+if else判断,这里多加了2个提示弹窗
    判断依据 if(this.mode.content)mode对应data里的user模型,对应user的各个属性判断。
    在这里插入图片描述
    在这里插入图片描述

2.5 优化vue-method表单验证

tips:其中submit函数可以优化图2写法:
在这里插入图片描述
在这里插入图片描述
这样的好处:

  1. 首先打印一下this.$refs[formName],检查是否拿到了正确的需要验证的form;
  2. 其次在拿到了正确的form后,检查该form上添加的表单验证是否正确。

Login.vue优化后的全部代码:

<script>
  export default {
    name: 'logindemo',
    data() {
      return {
        user: {},
        rules: {
          name: [{
            required: true,
            message: '用户名不能为空',
            trigger: 'blur'
          }],
          password: [{
            required: true,
            message: '密码不能为空',
            trigger: 'blur'
          }],
        },
      }
    },
    methods: {
      /*提交进行判断的函数 */
      // submit: function() {
      //   if (this.user.name === 'admin' && this.user.password === '123') {
      //     this.$notify({
      //       type: 'success',
      //       message: '欢迎你,' + this.user.name + '!',
      //       duration: 3000
      //     })
      //     this.$router.replace('/')
      //   } else {
      //     this.$message({
      //       type: 'error',
      //       message: '用户名或密码错误',
      //       showClose: true
      //     })
      //   }
      // },
      submit() {
        this.$refs.form.validate((valid) => {//form是el-form 标签中ref="form"名称
          if (valid) {
            if (this.user.name === 'admin' && this.user.password === '123') {
              this.$notify({
                type: 'success',
                message: '欢迎你,' + this.user.name + '!',
                duration: 3000
              })
              this.$router.replace('/')
            } else {
              this.$message({
                type: 'error',
                message: '用户名或密码错误',
                showClose: true
              })
            }
          } else {
            return false
          }
        })
      },
      register: function() {
        this.$router.replace('/') //返回主页
      },
    },
  }
</script>

三、Vuex管理全局数据

3.1 引入Vuex

  1. 引入Vuex

    cnpm install vuex

  2. 创建目录src/vuex/ ,并创建index.js文件
    在这里插入图片描述

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
        // 全局变量
        state: {
            user: undefined
        },
        // 修改全局变量必须通过mutations中的方法
        // mutations只能采用同步方法
        mutations: {
            login (state, payload) {//全局login函数
                state.user = payload//这里有缓存,在下一个页面可以继续调用user对象
            },
            logout (state) {
                state.user = undefined//清楚缓存
            }
        },
        // 异步方法用actions
        // actions不能直接修改全局变量,需要调用commit方法来触发mutation中的方法
        actions: {
            login (context, payload) {
                context.commit('login', payload)
            },
            logout (context) {
                context.commit('logout')
            }
        }
    })
    
    export default store//对外告诉全局,以上内容缓存到store中
    
    
  3. main.js中引入之前的Vuex配置

    ...
    import store from './vuex'// 引入全局数据控制
    
    ...
    new Vue({
      el: '#app',
      router,
      store,//....
      components: { App },
      template: '<App/>'
    })
    
    

3.2 登录界面

  1. 修改Login.vue
    通过dispatch方法来调用actions中的login方法
    在这里插入图片描述

Login.vue

<!--基本html代码区域-->
<template>
  <div class="logindemo">
    <el-form ref="form" :model="user" :rules="rules" status-icon label-width="100px">
      <el-row type="flex" justify="center">
        <el-col :span="5">
          <el-form-item label-width="70px">
            <span>
              <font color="#B3D8FF" size="5">注册登录页面</font>
            </span>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row type="flex" justify="center">
        <el-col :span="5">
          <el-form-item label="账户:" prop="name">
            <el-input v-model="user.name" size="small"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row type="flex" justify="center">
        <el-col :span="5">
          <el-form-item label="密码:" prop="password">
            <el-input v-model="user.password" size="small"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row type="flex" justify="center">
        <el-col :span="5">
          <el-form-item>
            <el-button type="primary" @click="submit">登录</el-button>
            <el-button @click="register">注册</el-button>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row type="flex" justify="center">
        <font color="pink" size="3">1.账户admin,密码123,登录<br>2.点击注册返回主页</font>
      </el-row>
    </el-form>
  </div>
</template>


<!--数据存贮交互,事件控制地区-->
<script>
  export default {
    name: 'logindemo',
    data() {
      return {
        user: {},
        rules: {
          name: [{
            required: true,
            message: '用户名不能为空',
            trigger: 'blur'
          }],
          password: [{
            required: true,
            message: '密码不能为空',
            trigger: 'blur'
          }],
        },
      }
    },
    methods: {
      /*提交进行判断的函数 */
      submit() {
        this.$refs.form.validate((valid) => {//form是el-form 标签中ref="form"名称
          if (valid) {
            if (this.user.name === 'admin' && this.user.password === '123') {
              // dispatch采用Promise链式调用
              this.$store.dispatch('login', this.user).then(() => {
                this.$notify({
                  type: 'success',
                  message: '欢迎你,' + this.user.name + '!',
                  duration: 3000
                })
                this.$router.replace('/')
              })
            } else {
              this.$message({
                type: 'error',
                message: '用户名或密码错误',
                showClose: true
              })
            }
          } else {
            return false
          }
        })
      },
      register: function() {
        this.$router.replace('/') //返回主页
      },
    },
  }
</script>

<!-- 写样式的地方 -->
<style scoped>

</style>

  1. 主页面
    最后修改Main.vue,用户已登录的时候显示用户名和注销按钮,未登录时显示登录按钮

    1. 注销:调用$store.dispatch销毁user
    2. 已登录时:$store.state查询到缓存的user

    在这里插入图片描述
    Main.vue

    <template>
        <div>
            <h1>主页面</h1>
            欢迎你!
            <span v-if="user"> {{user.name}}
                <el-button type="warning"  @click="logout">注销</el-button>
            </span>
            <el-button v-else type="success" @click="login">点击登录</el-button>
        </div>
    </template>
    
    <script>
        export default {
            methods: {
                login () {
                    this.$router.replace('/login')
                },
                logout () {
                    this.$store.dispatch('logout').then(() => {
                        this.$router.replace('/login')
                    })
                }
            },
            computed: {
                user () {
                    return this.$store.state.user
                }
            }
        }
    </script>
    
    

3.3 缓存测试 ?

  1. 缓存
    登陆以后:主页显示:欢迎 admin(其中admin为store缓存的user.name
    在这里插入图片描述
    在computed中设置console.log(this.$store.state)打印缓存全部内容
    在这里插入图片描述
    F12调出chrome控制台,查看到缓存的user信息:
    在这里插入图片描述

  2. 注销登录
    返回登陆页面!并且查看到user信息被清空了:
    在这里插入图片描述

四、axios登录验证(结合后台)

4.1 引入axios

  1. 打开cmd,在Vue_Springboot根目录下安装

    cnpm install axios

  2. 创建 src/axios/ 目录,并创建index.js
    在这里插入图片描述

    import Vue from 'vue'
    import axios  from 'axios'
    
    axios.defaults.baseURL="http://localhost:8090"
    Vue.prototype.$ajax = axios//重命名为ajax,使用$ajax.get即可调用
    
    
  3. 在main.js中引入axios

    import './axios'
    

4.2 发送Ajax请求

接下来修改Login.vue,在submit方法中发送ajax请求

 submit() {
        this.$refs.form.validate((valid) => {
          if (valid) {
            console.log(this.user)
            this.$ajax.post('/user/check', this.user).then((res) => {
              if (res.data) {
                this.$store.dispatch('login', res.data).then(() => {
                  this.$notify({
                    type: 'success',
                    message: '欢迎你,' + res.data.name + '!',
                    duration: 3000
                  })
                  this.$router.replace('/')
                })
              } else {
                this.$message({
                  type: 'error',
                  message: '用户名或密码错误',
                  showClose: true
                })
              }
            }).catch((err) => {
              this.$message({
                type: 'error',
                message: '网络错误,请重试',
                showClose: true
              })
            })
          } else {
            return false
          }
        })
      },

4.2 后端配置Springboot+Cors

  1. 配置端口号,与步骤4.1.2中的axios/index.js相同
    在这里插入图片描述

4.3 测试问题解决

目前遇到问题:

  1. Post请求变Option:
    在这里插入图片描述
    解决办法 修改请求头为application/x-www-form-urlencoded;charset=utf-8"

    axios/index.js加上:

    	axios.defaults.headers = {
    		"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
    	};
    
  2. 请求类型错误: 默认post请求传参是json格式,但后台需要formData格式
    在这里插入图片描述
    在这里插入图片描述
    解决办法 需要引入qs模块

    cnpm install qs

    原理:非get请求时,把所有post(url,data)
    转变为post(url,qs.stringify(config.data)
    axios/index.js

    import Vue from 'vue'
    import axios  from 'axios'
    import qs from 'qs'
    
    axios.defaults.baseURL="http://localhost:8090"
    Vue.prototype.$ajax = axios
    
    axios.defaults.headers = {
    	"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
    };
    
    // 添加请求拦截器
    axios.interceptors.request.use(function (config) {
        if(config.method!='get'){
            config.data=qs.stringify(config.data);
        }
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        return config;
    },function (error) {
        return Promise.reject(error)
    })
    
    
  3. (405报错:post和get弄错了)
    后端(springboot+cors):
    在这里插入图片描述
    后端check是get方法,前端用的post,难怪!
    赶快修改后端代码。
    在这里插入图片描述
    在这里插入图片描述

4.4 最终测试

数据库成员:
在这里插入图片描述
成员test登录:
在这里插入图片描述
? 登陆成功 ?
在这里插入图片描述
在这里插入图片描述

五、源码&总结 ?

总结:今天遇到的问题:

  1. post请求变option:
    一直纠结后端请求头allowedOrigins("*"),结果是前端header一直为content-type的问题;
  2. 就post和get的原因:
    纠结于params和data是否需要添加请求头,想自定义http.js将post重定义为params,emmmm完全方向错误。后端在requestMapping时的method用错了;
  3. 以及formdata原因:
    这个比较好解决,引入qs即可。

总之,吃一盏长一智!!! ?

Github:

前端:第一个Vue前后端分离小项目
后端:springbootDay6

参考:
究极死胖兽的博客——Vue.js分类
https://blog.csdn.net/sps900608/article/category/7482283

Logo

前往低代码交流专区

更多推荐