使用vue-cli、axios、vuex、seccionstorage来实现简单的登陆与退出
首先使用npm install 安装需要的
npm install axios
npm install vuex
在main.js引入import
//main.js
import Vue from 'vue'
import axios from 'axios'
import store from './store'
import api from './api/index.js'
Vue.prototype.$api=api
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
axios,
components: { App },
template: '<App/>'
})
配置vuex
在src文件夹下新建store/index.js
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
token: sessionStorage.getItem('token') || '',
CityCode: sessionStorage.getItem('CityCode') || '',
},
mutations: {
//登陆成功后设置缓存
ADD_COUNT(state,params){
sessionStorage.setItem("token", params.token);
sessionStorage.setItem("CityCode", params.city_code);
},
//退出登陆
REMOVE_COUNT(state,params){
sessionStorage.removeItem("token", params.token);
sessionStorage.removeItem("CityCode",params.city_code);
}
}
})
简单的封装axios
在src文件夹下新建api/index.js
const HOST='服务器域名'
// 引用axios
var axios = require('axios')
axios.defaults.baseURL = process.env.NODE_ENV == 'production' ? HOST : '/'
// 自定义判断元素类型JS
function toType(obj) {
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
// 参数过滤函数
function filterNull(o) {
for (var key in o) {
if (o[key] === null) {
delete o[key]
}
if (toType(o[key]) === 'string') {
o[key] = o[key].trim()
} else if (toType(o[key]) === 'object') {
o[key] = filterNull(o[key])
} else if (toType(o[key]) === 'array') {
o[key] = filterNull(o[key])
}
}
return o
}
/*
接口处理函数
这个函数每个项目都是不一样的,我现在调整的是适用于
https://cnodejs.org/api/v1 的接口,如果是其他接口
需要根据接口的参数进行调整。参考说明文档地址:
https://cnodejs.org/topic/5378720ed6e2d16149fa16bd
主要是,不同的接口的成功标识和失败提示是不一致的。
另外,不同的项目的处理方法也是不一致的,这里出错就是简单的alert
*/
function apiAxios(method, url, params, success, failure) {
if (params) {
params = filterNull(params)
}
axios({
method: method,
url: url,
data: method === 'POST' || method === 'PUT' ? params : null,
params: method === 'GET' || method === 'DELETE' ? params : null,
withCredentials: false
})
.then(function (res) {
if (res.status === 200 && res.data.status == 0) {
if (success) {
success(res.data)
}
} else {
if (failure) {
failure(res.data)
} else {
router.replace({
path: '/',
})
window.alert(res.data.msg)
}
}
})
.catch(function (err) {
let res = err.response
if (err) {
window.alert('api error, HTTP CODE: ')
}
})
}
export default {
get: function (url, params, success, failure) {
return apiAxios('GET', url, params, success, failure)
},
post: function (url, params, success, failure) {
return apiAxios('POST', url, params, success, failure)
},
put: function (url, params, success, failure) {
return apiAxios('PUT', url, params, success, failure)
},
delete: function (url, params, success, failure) {
return apiAxios('DELETE', url, params, success, failure)
}
}
解决跨域问题
在config/index.js下的proxyTable进行如下配置
proxyTable: {
'/api': {
target: '你的服务器域名', // 你接口的域名
changeOrigin: true,
pathRewrite: {
'^/api': '/api' // 这里用‘/api’代替target里面的地址,组件中调用接口时直接用api代替 比如我要调用'http://xxx.com:8080/api/NEWS/getNews.json?page=1&pageSize=10',直接写‘/api/NEWS/getNews.json?page=1&pageSize=10’即可
}
}
},
如果需要为请求添加请求头,
在api下新建文http.js添加拦截器
import axios from 'axios';
import qs from 'qs';
import store from '@/store'
import router from '@/router'
//拦截发送请求前做什么
axios.interceptors.request.use(
config => {
if (config.method != "get") {
config.data = Object.assign(config.data || {}, {
Authorization: sessionStorage.getItem('token'),
CityCode: sessionStorage.getItem('CityCode')
})
config.data = qs.stringify(config.data);
}
if (sessionStorage.token) {
config.headers.Authorization = sessionStorage.getItem('token')
}
if (sessionStorage.CityCode) {
config.headers.CityCode = sessionStorage.getItem('CityCode')
}
return config
},
err => {
return Promise.reject(err);
});
// http response 拦截器,对响应数据的操作
axios.interceptors.response.use(
response => {
return response;
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
// 返回 401 清除token信息并跳转到登录页面
router.replace({
path: '/',//替换当前的路由
query: {
redirect: router.currentRoute.fullPath
}
})
}
}
return Promise.reject(error.response.data.msg) // 返回接口返回的错误信息
});
Login()实现登陆
template form表单的demo
<el-form :model="loginForm" :rules="rules" ref="loginForm" class="el-form">
<el-form-item prop="username">
<el-input v-model="loginForm.username" placeholder="请输入账号" ></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" v-model="loginForm.password"></el-input>
</el-form-item>
<el-form-item class="checkbox">
<el-checkbox-group v-model="loginForm.checked" text-color="#303133" >
<el-checkbox label="记住用户名和密码" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('loginForm')" class="submintbutton" >登 录</el-button>
</el-form-item>
</el-form>
登陆输入验证的rules和data的定义
loginForm: {
username: "",
password: "",
checked: false
},
rules: {
username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }]
},
submitForm(‘loginForm’)
submitForm(loginForm) {
this.$refs[loginForm].validate(valid => {
if (valid) {
var params = {
phone: this.loginForm.username,
password: this.loginForm.password
};
this.$api.post("请求路径", params, r => {
var params = {
token: r.data.token,
city_code: r.data.city_code
}
this.$store.commit("ADD_COUNT", params);
this.$router.push({ path: "header" })
}
});
} else {
console.log("error submit!!");
return false;
}
});
},
这样就完成了一个简单的登陆操作,退出时只需要commit之前store里的mutations就可以了,第一次写博客有错的地方请大家温柔的怼。请点个赞再走谢谢(⊙﹏⊙)