成品动画演示:?
具体步骤较多,一下午功夫吧!入门vue嘻嘻~ ?
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目录
下进行 (这是我全部创建完成后的目录,参照位置 创建和修改)
先在目录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.vue,Main.vue和Login.vue的代码
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
div>
template>
<script>
export default {
name: 'App'
}
script>
<style>style>
<template>
<div>
<h1>主页面h1>
欢迎!<b @click="login">点这里登录b>
div>
template>
<script>
export default {
methods: {
login () {
this.$router.replace('/login')
}
}
}
script>
<template>
<div>
<h1>登录界面h1>
用户名:<Input /><br/>
密码:<Input /><br/>
<button @click="login">登录button>
div>
template>
<script>
export default {
methods: {
login () {
this.$router.replace('/')
}
}
}
script>
引入Element框架对界面进行美化,并对表单添加基础的验证功能
打开cmd在 Vue_Springboot
目录下安装包如下
cnpm install element-ui -S
修改index.js
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
然后在全局配置main.js
中添加以下代码进行引入element
import './element'//引入样式
对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>
<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>
: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个提示弹窗;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
cnpm install vuex
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: ' '
})
Login.vue
<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
,用户已登录的时候显示用户名和注销按钮,未登录时显示登录按钮
<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>
缓存
登陆以后:主页显示:欢迎 admin(其中admin
为store缓存的user.name
)
在computed中设置console.log(this.$store.state)
打印缓存全部内容
F12调出chrome控制台,查看到缓存的user信息:
打开cmd,在Vue_Springboot
根目录下安装
cnpm install axios
import Vue from 'vue'
import axios from 'axios'
axios.defaults.baseURL="http://localhost:8090"
Vue.prototype.$ajax = axios//重命名为ajax,使用$ajax.get即可调用
在main.js
中引入axios
import './axios'
接下来修改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
}
})
},
目前遇到问题:
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,难怪!
赶快修改后端代码。
总结:今天遇到的问题:
总之,吃一盏长一智!!! ?
Github:
前端:第一个Vue前后端分离小项目
后端:springbootDay6
参考:
究极死胖兽的博客——Vue.js分类
https://blog.csdn.net/sps900608/article/category/7482283