黑马头条vue2.0项目实战(十一)——功能优化(组件缓存、响应拦截器、路由跳转与权限管理)

1. 组件缓存

1.1 介绍

先来看一个问题?

从首页切换到我的,再从我的回到首页,我们发现首页重新渲染原来的状态没有了。

首先,这是正常的状态,并非问题,路由在切换的时候会销毁切出去的页面组件,然后渲染匹配到的页面组件。

但是我想要某些页面保持状态,而不会随着路由切换导致重新渲染。

1.2 使用 keep-alive 缓存组件

官方文档:在动态组件上使用keep-alive

<keep-alive> 主要用于保留组件状态或避免重新渲染,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。

(1)组件缓存不是持久化,它只是在应用运行期间不会重新渲染,如果页面刷新还是会回到初始状态。

(2)<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。

(3)<keep-alive> 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。

(4)组件生命周期钩子和缓存

具体使用要根据实际情况来处理,在我们项目后续的业务功能中慢慢体会。

(5)includeexclude 属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示。

javascript 复制代码
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
  <component :is="view"></component>
</keep-alive>

1.3 项目中的缓存配置

参考链接:

① 在 App.vue 对根路由组件启用组件缓存

② 在 views/tabbar/index.vue 对子路由也启用组件缓存

1.4 解决缓存之后我的页面用户数据不更新问题

将原来 created 中的逻辑代码写到 activated 中:

javascript 复制代码
activated () {
  if (this.user) {
    this.loadUserInfo()
  }
},

2. 处理 token 过期

参考链接:

javascript 复制代码
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 响应成功进入这个函数
  return response;
}, async function (error) {
  // 响应失败进入这个函数,超出 2.xx 的状态码都会进入这里
  // console.log(error.response.status)
  const status = error.response.status
  if (status === 400) {
    //  客户端请求参数异常
    Toast.fail('客户端请求参数异常。')
  } else if (status === 401) {  // token 无效,过期
    // 如果没有 user或者 user.token,直接去登录
    const user = store.state.user
    if (!user || !user.token) {
      // replace 方法不会形成历史记录,push 会形成历史记录
      redirectLogin()
      return 
    }
    // 使用 refresh_token,则请求获取新的 token
    try {
      const res = await refreshTokenRequest(user.refresh_token)
      // 拿到新的 token 之后把它更新到容器之中
      user.token = res.data.data.token
      store.commit('setUser', user)
      // 把失败的请求重新发出去 error 是本次请求的相关配置对象
      return axios(error.config)
    } catch (err) {
      // token 刷新失败,直接跳转登录页面
      redirectLogin()
    }
  } else if (status === 403) {
    Toast.fail('没有权限操作。')
  } else if (status >= 500) {
    // 服务端异常
    Toast.fail('服务端异常。')
  }

  return Promise.reject(error);
});

const refreshTokenRequest = (refresh_token) => {
  return axios({
    url: 'https://toutiao.itheima.net/v1_0/authorizations',
    method: 'PUT',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: 'Bearer' + ' ' + refresh_token
    }
  })
}
const redirectLogin = () => {
  // router.currentRoute 当前路由对象,和你在组件中访问的 this.$route 是同一个东西
  // query 参数的数据格式就是:?key=value&key=value
  router.replace({
    name: 'login',
    query: {
      redirect: router.currentRoute.fullPath
    }
  })
}

3. 登录成功跳转回原来页面

4. 处理页面的访问权限

① 给需要登录状态才能访问的页面路由对象的 meta 中添加配置属性

② 通过路由拦截器统一校验

相关推荐
努力学习的小刘2 分钟前
如何使用react-router实现动态路由
前端·javascript
PasserbyX2 分钟前
JS原型链
前端·javascript
curdcv_po2 分钟前
你知道Cookie的弊端吗?
前端
curdcv_po4 分钟前
前端CSS高频面试题详解
前端
Danta7 分钟前
从0开始学习three.js(1)😁
前端·javascript·three.js
我的心巴8 分钟前
vue-print-nb 打印相关问题
前端·vue.js·elementui
coderYYY27 分钟前
element树结构el-tree,默认选中当前setCurrentKey无效
前端·javascript·vue.js
牛奶咖啡1330 分钟前
学习设计模式《十二》——命令模式
学习·设计模式·命令模式·队列请求·宏命令·可撤销恢复操作·参数化配置
余厌厌厌38 分钟前
go语言学习 第9章:映射(Map)
服务器·学习·golang
委婉待续39 分钟前
Qt的学习(一)
开发语言·qt·学习