04-首页(二级路由)
1.1-配置二级路由
-
细节:这个二级路由的路径不要乱写,因为我们的菜单栏是有服务器接口的。路径最好跟接口写的一致- 至于为什么这个菜单栏要设计成服务器接口,主要是因为这个地方设计到v-for一个特别难的不同标签渲染,到时候就知道了。(总之为了让大家学习到更加有深度的知识)
- 1.配置二级路由: router/index.js
-
import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter); //1.导入组件 import Register from "@/views/Register.vue"; import Login from "@/views/Login.vue"; import Main from "@/views/Main.vue"; //导入二级路由 import Home from '@/views/Home/Home.vue' import UserInfo from '@/views/User/UserInfo.vue' import UserAvatar from '@/views/User/UserAvatar.vue' import UserPwd from '@/views/User/UserPwd.vue' import ArtCate from '@/views/Article/ArtCate.vue' import ArtList from '@/views/Article/ArtList.vue' //2.路由规则 const routes = [ { path: "/register", component: Register }, { path: "/login", component: Login }, { path: "/", component: Main,children:[ //二级路由配置 { path: '/', component: Home }, { path: '/home', component: Home }, { path: '/user-info', component: UserInfo }, { path: '/user-avatar', component: UserAvatar }, { path: '/user-pwd', component: UserPwd }, { path: '/art-cate', component: ArtCate }, { path: '/art-list', component: ArtList } ] } ]; //3.路由对象 const router = new VueRouter({ routes }); export default router;
1.2-添加二级路由出口
- 2.添加二级路由出口 Main.vue
- 3.最终成品效果
05-项目token处理(vuex+axios拦截器)
1.1-使用vuex存储token
- store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//1.state:存储数据
state: {
// 登录成功之后的 token 值
token: '',
},
//2.mutations:更新数据
mutations: {
//更新 token
updateToken(state, newToken) {
state.token = newToken
},
},
//3.actions: 异步更新数据
actions: {
},
//4.modules:模块化state中的数据
modules: {
}
})
1.2-登录成功之后将数据存入vuex
- Login.vue
1.3-使用vuex的插件持久化vuex数据
默认情况下: vuex中的数据是存储在内存中的,只要页面一刷新就会消失
如果希望将vuex中的数据存入硬盘持久化,就需要使用vuex的插件:vuex-persistedstate
底层原理:自动将vuex中的数据用localStorage存入硬盘中
-
1.下载插件
- npm install --save vuex-persistedstate@3.2.1
-
2.在vuex中配置插件
-
-
import Vue from 'vue' import Vuex from 'vuex' // 导入持久化插件 import creteState from 'vuex-persistedstate' Vue.use(Vuex) export default new Vuex.Store({ //配置持久化存储数据的 vuex 插件 plugins: [creteState()], //1.state:存储数据 state: { // 登录成功之后的 token 值 token: '', }, //2.mutations:更新数据 mutations: { //更新 token updateToken(state, newToken) { state.token = newToken }, }, //3.actions: 异步更新数据 actions: { }, modules: { } })
1.4-使用vuex的actions存储用户信息
什么时候用vuex的actions : 当需要存储在vuex的数据需要异步获取
actions使用四个流程
(1)组件给actions发送消息: this.$store.dispatch('actions名',载荷)
(2) actions发送异步请求
(3)actions提交mutations更新
(4)mutations更新state数据
- store/index.js
import Vue from "vue";
import Vuex from "vuex";
// 导入持久化插件
import creteState from "vuex-persistedstate";
//导入axios
import axios from 'axios'
Vue.use(Vuex);
export default new Vuex.Store({
//配置持久化存储数据的 vuex 插件
plugins: [creteState()],
//1.state:存储数据
state: {
// 登录成功之后的 token 值
token: "",
// 用户的基本信息
userInfo: {}
},
//2.mutations:更新数据
mutations: {
//更新 token
updateToken(state, newToken) {
state.token = newToken;
},
// 更新用户基本信息
updateUserInfo(state, obj) {
state.userInfo = obj;
}
},
//3.actions: 异步更新数据
actions: {
//context:当前的vuex实例对象store
async initUserInfo(context) {
const { data: res } = await axios.get("/my/userinfo");
console.log(res)
// 获取成功,调用mutations更新数据
if (res.code === 0) {
context.commit("updateUserInfo", res.data);
}
}
},
modules: {}
});
- 登录成功之后,请求个人信息
- Main.vue的created钩子中
-
//提交actions:异步请求用户信息 this.$store.dispatch('initUserInfo')
1.5-使用axios拦截器发送token
axios拦截器作用: 在发送请求之前和响应数据之后拦截axios
应用场景 发送请求之前: 给服务器发token
响应数据之后:判断401错误,自动跳转登录页
-
main.js中配置axios拦截器
-
细节:因为main.js中已经导入了router和store,所以在main.js中访问路由和vuex直接访问即可
-
(1)如果是在组件.vue文件中访问:
this.$router和this.$store和this.$axios -
(2)如果是在js文件中访问 :
先使用es6模块化语法导入,然后才能使用- 你导入的是什么对象,就用什么对象
-
-
字符串的startsWith是js原生的方法,作用是判断字符串是否以某个字符串开头
-
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
Vue.config.productionTip = false;
//1.导入全局样式表
import "@/assets/global.less";
//2.导入 element-ui
//(1)导入+注册 组件
import ElementUI from "element-ui";
Vue.use(ElementUI);
//(2)导入css样式
import "element-ui/lib/theme-chalk/index.css";
//3.导入 axios
import axios from "axios";
//挂载到Vue原型中
Vue.prototype.$axios = axios;
//设置基地址
axios.defaults.baseURL = "http://big-event-vue-api-t.itheima.net";
// 添加请求拦截器
axios.interceptors.request.use(
function(config) {
//请求发送之前做点什么
// 判断本次请求是否以 /my 开头,决定是否添加身份认证的字段
if (config.url.startsWith("/my") && store.state.token) {
config.headers.Authorization = store.state.token
}
return config;
},
function(error) {
//请求错误做点什么
return Promise.reject(error);
}
);
// 响应拦截器
axios.interceptors.response.use(
function(response) {
// 响应成功之后做点什么
return response;
},
function(error) {
// 响应失败之后做点什么
//判断是不是token无效导致
if (error.response.status === 401) {
// 1. 立即清空无效的 token
store.commit("updateToken", "");
// 2. 跳转到登录页面
alert('请先登录')
router.push("/login");
}
return Promise.reject(error);
}
);
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
1.6-退出登录
-
el-messageBox弹窗:element.eleme.cn/#/zh-CN/com…
- 这个组件可以直接使用js代码展示:
this.$confirm().then()
- 这个组件可以直接使用js代码展示:
-
Main.vue
-
绑定退出登录事件
-
<el-menu-item index="2" @click="logout"> <i class="el-icon-switch-button"></i>退出 </el-menu-item>
-
-
完成退出登录功能
-
细节:这里catch可以省略, 写上了点取消浏览器不爆红。 不写的话点取消浏览器爆红。(没啥区间,看你自己强迫症程度了)- - 完成退出登录功能 -
logout() { this.$confirm("您确认退出登录吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }).then(() => { // 1. 清空 token this.$store.commit("updateToken", ""); // 2. 跳转到登录页面 this.$router.push("/login"); }).catch(()=>{}) }
-
-