目录
序
成品动画演示:?
具体步骤较多,一下午功夫吧!入门vue嘻嘻~ ?
正文
一、router路由配置
1.1 创建项目
vue脚手架项目
-
到工程目录下打开cmd,输入以下命令行,生成vue脚手架工程
$ vue init webpack Vue_Springboot
-
接下来根据提示输入工程的信息
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 runnpm install
for you after the project has been created? (recommended) npm -
脚手架工程安装完成后就可以用编译工具打开文件夹
Vue_Springboot
我是用的HBuilder),目录如下,编程都在src目录
下进行 (这是我全部创建完成后的目录,参照位置 创建和修改)
1.2 router路由配置
-
先在目录src/components/ 下创建两个空文件
Main.vue
和Login.vue
-
创建工程时,会自动导入vue-router,不用手动创建的;
若没有自动导入,则打开cmd在Vue_Springboot
目录下安装包如下cnpm intall vue-router
-
修改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 }, ] })
-
在
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/>' })
-
路由就设置成功了,接下来修改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>
- App.vue:删去了多余的样式
1.3 router测试 ?
- 路由模块运行
输入cnpm run dev
启动项目,热启动,边修改边响应 - 浏览器请求本地端口(点击登录实现页面切换,即router路由配置成功)
二、element优化前端
2.1 引入element
引入Element框架对界面进行美化,并对表单添加基础的验证功能
-
打开cmd在
Vue_Springboot
目录下安装包如下cnpm install element-ui -S
-
创建目录src/element/ ,并创建文件
index.js
-
修改
index.js
import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI)
-
然后在全局配置
main.js
中添加以下代码进行引入elementimport './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 登录验证测试 ?
- 验证是否为空:(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>
- 登录验证:
主要就是submit()
函数+if else
判断,这里多加了2个提示弹窗;
判断依据 if(this.mode.content)mode对应data里的user模型,对应user的各个属性判断。
2.5 优化vue-method表单验证
tips:其中submit函数可以优化图2写法:
这样的好处:
- 首先打印一下
this.$refs[formName]
,检查是否拿到了正确的需要验证的form;- 其次在拿到了正确的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
-
引入Vuex
cnpm install vuex
-
创建目录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中
-
在
main.js
中引入之前的Vuex配置... import store from './vuex'// 引入全局数据控制 ... new Vue({ el: '#app', router, store,//.... components: { App }, template: '<App/>' })
3.2 登录界面
- 修改
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>
-
主页面
最后修改Main.vue
,用户已登录的时候显示用户名和注销按钮,未登录时显示登录按钮- 注销:调用$store.dispatch销毁user
- 已登录时:$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 缓存测试 ?
-
缓存
登陆以后:主页显示:欢迎 admin(其中admin
为store缓存的user.name
)
在computed中设置console.log(this.$store.state)
打印缓存全部内容
F12调出chrome控制台,查看到缓存的user信息:
-
注销登录
返回登陆页面!并且查看到user信息被清空了:
四、axios登录验证(结合后台)
4.1 引入axios
-
打开cmd,在
Vue_Springboot
根目录下安装cnpm install axios
-
创建 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即可调用
-
在main.js
中引入axiosimport './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
- 配置端口号,与步骤4.1.2中的axios/index.js相同
4.3 测试问题解决
目前遇到问题:
-
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" };
-
请求类型错误: 默认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) })
-
(
405报错
:post和get弄错了)
后端(springboot+cors):
后端check是get方法,前端用的post,难怪!
赶快修改后端代码。
4.4 最终测试
数据库成员:
成员test登录:
? 登陆成功 ?
五、源码&总结 ?
总结:今天遇到的问题:
- post请求变option:
一直纠结后端请求头allowedOrigins("*"),结果是前端header一直为content-type的问题; - 就post和get的原因:
纠结于params和data是否需要添加请求头,想自定义http.js将post重定义为params,emmmm完全方向错误。后端在requestMapping时的method用错了; - 以及formdata原因:
这个比较好解决,引入qs即可。
总之,吃一盏长一智!!! ?
Github:
前端:第一个Vue前后端分离小项目
后端:springbootDay6
参考:
究极死胖兽的博客——Vue.js分类
https://blog.csdn.net/sps900608/article/category/7482283