第一步:创建脚手架
vue2.0:创建命令为: vue create 项目名称
======================================
vue2.0的操作手段:
创建好了脚手架后:
->(1)安装router:指令为: npm install vue-router --save
->(2)在src下创建一个router,在创建一个index.js文件
*配置首页和登录页 (index.js) 路由文件名具体看项目*
`
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
<!--配置首页和登录页面-->
const routes = [
{
// 网页打开第一次默认路由路径就是'/'
path:'/',
//@/views/layout首页组件名
component: ()=>import('@/views/layout'),
redirect:'/home'
},
{
path:'/login',
component:() => import('@/views/login')
}
]
const router = new VueRouter({
routes
})
export default router
`
->(3):把配置好的路由导入到main.js中
(main.js)
`
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
`
->(4)安装store.js(安装指令: npm install vuex --save)
->(5)在src下创建一个store文件在创建index.js文件
(*写入代码)
`
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
},
mutations:{
},
getters:{
},
actions:{
}
})
`
->(6)把store引入到main.js中
import store from './store'
-> (7)封装接口
-> (7.1)安装axios,安装命令为(npm i axios)
-> (8)在src下创建一个utils文件夹在创建(request.js文件)
(*在request.js下写入代码)
`
import axios from 'axios'
import store from '@/store'
import router from '@/router'
//项目基地址
export const baseURL = 'http://big-event-vue-api-t.itheima.net'
const myAxios = axios.create({
baseURL
//请求拦截器(为后面的请求头部添加token)
myAxios.interceptors.request.use(function(config){
return config
},function(error) {
return Promise.reject(error)
})
})
//响应拦截器(用于处理接口错误问题)
myAxios.interceptors.response.use(function(response){
return response
},function(error){
return Promise.reject(error)
})
//自定义导出
export default myAxios
`
->(9)再在src下创建api文件夹,在之下创建user.js文件
(*user.js)写入代码(登录接口和获取用户接口具体要看后端api)
` import request from '@/utils/request'
/**
* 登录接口
* @param{ * } param0 { username :'用户名',password:密码}
* @returns Promise对象
*/
export function LoginAPI(){
return request({
url:'/api/login',
method:'POST',
data
})
}
}
//获取用户信息接口
export function getUserInfoAPI() {
return request({
url:'/my/userinfo',
method:'GET'
})
} `
->(10)在store下的vuex里面把token和用户信息接口处理都写入
->(11)注入vuex项目持久化插件
( 安装指令:npm install vuex-persistedstate --save)
(*代码写入)
`
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
//引入用户信息接口
import { getUserInfoAPI } from '@/api'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
// 保存token字符串
token:'',
//定义用户对象信息
userInfo:{}
},
mutations:{
// 保存token(保存)用户信息
updateToken(state,val){
state.token = val
},
//更新用户信息
updateUserInfo(state,val){
state.userInfo = val
}
},
getters:{
//用于方便获取用户信方便组件的调用
username: state => state.userInfo.username, //用户名
nickname: state => state.userInfo.nickname, //用户昵称
user_pic: state => state.userInfo.user_pic //用户名头像
},
actions:{
//调用用户接口
async getUserInfoActions(store){
// 调用获取用户信息的接口
const { data :res } = await getUserInfoAPI()
if(res.code === 0){
store.commit('updateUserInfo',res.data)
}
}
},
plugins:[
//注入持久化插件
createPersistedState()
]
})
`
->(12)写登录页面把token存储到vuex里面方便后期接口复用
(login.vue)写入代码
`
页面省略....
<script>
import { loginAPI } from '@/api'
//使用mapMutations映射函数拿到mutations的函数
import { mapMutations } from 'vuex';
export default {
data(){
return {
loginForm:{
username:"",
password:"",
}
}
},
methods:{
...mapMutations(['updateToken']),
// 登录
loginFn(){
this.$refs.loginRef.validate( async valid =>{
if(valid){
//调用登录接口
const { data:res } = await loginAPI(this.loginForm);
console.log(res);
if(res.code !== 0){
return this.$message.error(res.message);
}
this.$message.success(res.message);
//保存token
this.updateToken(res.token)
//跳转到布局页
this.$router.push('/')
}else{
return false
}
})
}
}
}
</script>
`
->(13)处理路由跳转(添加导航守卫)
(*在router.js里面添加路由导航守卫)
`
import store from '@/store'
// 白名单(无需登录就可以访问的路由地址)
let whileList = ['/login','/reg']
router.beforeEach((to,from,next)=>{
//拿到vuex里面的token
const token = store.state.token
if(token){
//登录了
if(!store.state.userInfo.username){
//现在本地有token值,才会请求用户信息
store.dispatch('getUserInfoAction')
}
next()
}else{
if(whileList.includes(to.path)){
next()
}else{
//next()强制切换到登录的路径上
next('/login')
}
}
}
})
export default router
`
->(14)给请求拦截器添加token头字段和响应拦截去处理接口报错问题
(* 在src/utils下的 request.js写入代码)
`
import router from '@/router'
//请求拦截器
myAxios.interceptors.request.use(function(config){
//判断有无token,有则为后面的接口头添加token字段
if(store.state.token){
config.headers.Authorization = store.state.token
}
return config
},function(error){
return Promise.reject(error)
})
//响应拦截器
myAxios.interceptors.response.use(function(response){
return response
},function(error){
//响应拦截器状态码不是4xx 5xx时触发失败的回调,形参中的error是失败的结果
if(error.response.status === 401){
//清除token
store.commit('updateToken','')
//清除用户信息
store.commit('updateUserInfo',{})
//跳转回登录页
router.push('/login')
Message.error('用户身份已过期!!!!')
}
return Promise.reject(error)
})
`
->(15)退出登录
(*代码如下)
` <template> <el-button @click="logout"></el-button> </template>
<script>
import { mapGetters } from 'vuex'
import { getMenuListAPI } from '@/api'
export default {
data(){
return{
}
},
methods:{
// 退出登录
logoutFn(){
//用户是否退出登录
this.$confirm('您确认退出登录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//1.清空token
this.$store.commit('updateToken','')
this.$store.commit('updateUserInfo',{})
//2.跳转到登录页面
this.$router.push('/login')
}).catch((err)=>err)
}
}
}
</script>
`
->(16)首页布局:
(*Layout.vue代码如下)
`
<template>
<el-container class="main-container">
<!--头部区域-->
<el-header></el-header>
<el-container>
<!-- 侧边栏区域 -->
<el-aside></el-aside>
<el-container>
<!-- 页面主体区域 -->
<el-main>
<router-view></router-view>
</el-main>
<!-- 底部 -->
<el-footer>@www.xiamo.com - 夏沫凉城</el-footer>
</el-container>
</el-container>
</el-container>
</el-container>
</template>
`