Vue项目实战踩坑(vue-cli3+axios跨域问题)
Vue项目实战踩坑(vue-cli3+axios跨域问题)
下面简单介绍一下我们的后台部分,后台运行在本地,总体框架使用springboot,使用8088端口,满足简单的crud操作,下面开始vuei项目的初始化,首先在全局安装@vue/cli的情况下,进行项目的初始化
使用命令行工具进入到我们的项目目录,然后使用指令初始化项目
vue create vue-cli-2
具体的安装流程初次安装应该有些麻烦,但是在这里不再赘述,因为完全可以在b站找个vue教学视频学习,创建完毕以后,我们会得到一个项目目录,对于vue-cli4的情况下,我们的项目目录下会有一个main,js我们需要在这里完成需要导入的js和插件,还有一个app.vue这是官方默认装载在首页的组件,这一点可以在main.js的vue实例中看出来
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
那么,接下来,我们先运行一下项目,看看效果,执行指令
npm run build
这样就能构建成功,可以注意查看控制台的信息,接下来运行项目
npm run serve
项目成功运行,我们可以在浏览器打开页面,下面我们进行一些改造,第一个就是,我们要改变项目初始化加载的组件,我们先创建一个组件login.vue,他其实是一个登录页,具体信息如下
<template>
<div class="login-container">
<el-form :model="ruleForm2" :rules="rules2"
status-icon
ref="ruleForm2"
label-position="left"
label-width="0px"
class="demo-ruleForm login-page">
<h3 class="title">系统登录</h3>
<el-form-item prop="username">
<el-input type="text"
v-model="ruleForm2.username"
auto-complete="off"
placeholder="用户名"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password"
v-model="ruleForm2.password"
auto-complete="off"
placeholder="密码"
></el-input>
</el-form-item>
<el-checkbox
v-model="checked"
class="rememberme"
>记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-button type="primary" style="width:100%;" @click="handleSubmit" :loading="logining">登录</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data(){
return {
logining: false,
ruleForm2: {
username: 'admin',
password: '123456',
},
rules2: {
username: [{required: true, message: 'please enter your account', trigger: 'blur'}],
password: [{required: true, message: 'enter your password', trigger: 'blur'}]
},
checked: false
}
},
methods: {
handleSubmit(event){
this.$refs.ruleForm2.validate((valid) => {
if(valid){
this.logining = true;
this.$axios.get('/user/login?username='+this.ruleForm2.username+'&password='+this.ruleForm2.password).then((data)=>{
//在这里需要使用箭头函数,保证我们的this依旧指向原想的vue实例
//进入到这一步只能表示登录请求发送成功
//验证结果要看data里面的code
//100---成功
//200---失败
this.$alert(data.data.data.msg, '老肖的提示', {
confirmButtonText: '确定'
});
if(data.data.code==100){
//this.logining用来处理那个加载的小图标
this.logining = false;
this.$router.push({path:'/default'})
}
else{
this.logining = false;
}
}).catch((error)=>{
console.log(error)
this.$alert('网络请求问题,联系管理员修复', '老肖的提示', {
confirmButtonText: '确定'
});
})
}else{
console.log('error submit!');
return false;
}
})
}
}
};
</script>
<style scoped>
.login-container {
width: 100%;
height: 100%;
margin-top: 0 auto;
}
.login-page {
-webkit-border-radius: 5px;
border-radius: 5px;
margin: 180px auto;
width: 350px;
padding: 35px 35px 15px;
background: #fff;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
}
.title{
text-align: center;
}
label.el-checkbox.rememberme {
margin: 0px 0px 15px;
text-align: left;
}
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateX(80px);
}
.v-enter-active,
.v-leave-active{
transition: all 0.6s ease;
}
</style>
下面,要使用改变路由的方式切换到login.vue,首先我们要创建路由信息,项目src/router下面有一个index.js,这里定义着我们的单页面应用所需要的所有路由信息
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../views/login.vue' //添加
Vue.use(VueRouter)
const routes = [
{ //添加
path:'/login',
component:Login
} //添加
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
在这里,我们设置了这样一个路由,下面我们再vue组件中使用它
在组件中定义一个钩子函数mounted,在这里将路由push到login即可,但是这有一个问题,因为我们在login.vue中使用了element-ui,但是我们还未引入,所以要先导入这个插件库,首先本地安装element-ui,并且启用服务
npm install element-ui -D
然后,我们在我们的main.js中引用element-ui,并且启用它
下面是main,js的内容
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Element from 'element-ui' //添加
import 'element-ui/lib/theme-chalk/index.css' 添加
Vue.use(Element) //添加
Vue.config.productionTip = false
new Vue({
mounted:function(){
this.$router.push({path:'/login'})
},
router,
store,
render: h => h(App)
}).$mount('#app')
这样就有了首页,也就是登录页
下面进入今天的主题,登录肯定要经过后台验证,后台已经写好了接口我们可以先使用postman进行登录测试
请注意,此时我们登录请求的url是
localhost:8088/user/login?username=admin&password=123456
现在我们先引入axios模块,完成请求结构的构建
npm install axios -D
接下来,我们在main.js中简单配置我们的axios
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import axios from 'axios' //添加
Vue.prototype.$axios = axios //添加
axios.defaults.baseURL = '/api' //添加
axios.defaults.headers.post['Content-Type'] = 'application/json' //添加
Vue.use(Element)
Vue.config.productionTip = false
new Vue({
mounted:function(){
this.$router.push({path:'/login'})
},
router,
store,
render: h => h(App)
}).$mount('#app')
Vue.prototype.$axios = axios这一步,我们将axios配置到this中,方便我们可以在组件中使用axios发请求
axios.defaults.baseURL = '/api’这一步,我们给每一个请求加上了一个根,举个例子原来请求localhost:8080/admin/login---->localhost:8080/api/admin/login,也就是每个请求都在主机后面加一个api,这个用处以后介绍
axios.defaults.headers.post[‘Content-Type’] = ‘application/json’,这一步则配置了一个请求头,接下来我们测试登录请求能否触发
,因为在组件的定义过的登陆方法
this.$axios.get('/user/login?username='+this.ruleForm2.username+'&password='+this.ruleForm2.password).then((data)=>{
//在这里需要使用箭头函数,保证我们的this依旧指向原想的vue实例
//进入到这一步只能表示登录请求发送成功
//验证结果要看data里面的code
//100---成功
//200---失败
this.$alert(data.data.data.msg, '老肖的提示', {
confirmButtonText: '确定'
});
if(data.data.code==100){
//this.logining用来处理那个加载的小图标
this.logining = false;
this.$router.push({path:'/default'})
}
else{
this.logining = false;
}
}).catch((error)=>{
console.log(error)
this.$alert('网络请求问题,联系管理员修复', '老肖的提示', {
confirmButtonText: '确定'
});
})
我们打开浏览器的控制台,我们点击登录按钮,可以看到一个404的请求
不难看出,此时我们的请求链接是
http://localhost:8080/api/user/login?username=admin&password=123456
这样做其实会跨域因为我们接了一个根/api的原因,变成了404,如果没有配置/api的情况下,我们会发生跨域,为了解决这个问题,我们现在项目根目录创建一个文件vue.config.js
内容如下
module.exports = {
devServer: {
open: false,
port: 8080,
https: false,
proxy: {
'api': {
target: 'http://localhost:8088/',
ws: true, //开启跨域
changeOrigin: true,
pathRewrite: {
'^/api':''
}
}
}
}
};
可以看到,我们在这里使用proxy,配置了一个代理。名字是api,在这个代理中,我们配置了一个taget, 还有一个pathRewrite, pathRewrite里面的内容表示,但我们发现请求中含有api时,我们会将请求中/api和之前的内容替换成target中的内容,接上一个例子
那么最终的请求是localhost:8088/admin/login,确实神奇,下面验证我的说法,先重新构建项目,在启动
npm run build
npm run serve
之后,再次点击登录按钮,我们就能看到,请求已然变成了200,即,我们的请求成功了
今天这个跨域问题折腾了半天,记录下来,明天继续写项目