Vue3从0到1组件开发-业务组件:断网重载

572 阅读2分钟

这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战

功能介绍

2021年的现在,5G网逐渐普及, 对我们普通人而言,5G以手机为突破口冲进了我们的生活,它给我们最直接的第一印象就是比4G更快的网络。也让我们感受到了4G网被逐渐的减速(唉)。

但即便如此,在进行项目开发时,我们也不得不将用户突然断网、或者服务器的网络波动等原因导致的断网情况考虑仅我们的项目。那么如何在断网时反馈给用户提示并引导用户进行重连,一次来规避网络波动导致的断网问题。

image.png

但是这就有另一个问题了,在电脑端断网有默认的提示、或者自定义弹框。可若是在移动端就需要自己处理包含获取网络请求失败信息反馈引导重载重载等所有的内容了。

捕获断网

首先第一步当然是需要捕获是否断网了,这里以uniapp举例,但因为是封装一个请求,所以基本是差不多的。

做法也有好几种, 其一借助浏览器事件window.addEventlistener('offline', fn)监听当前网络状态 (online监听是否联网)

第二基于Axios库或其他库使用自带的请求拦截器axios.interceptors.request.use()

axios.interceptors.request.use(config => {
  // 在发送请求之前做某事,比如说 设置token
  // config.headers['token'] = 'token';
  config.headers['Token'] = 'xxxxxxxxxxxxxxxxxxx';
  return config;
}, error => {
  // 请求错误时做些事
  return Promise.reject(error);
});

拦截到请求之后是通过弹窗还是借助路由展示专门的网络错误信息就可以自定义处理。

但是因为之类是引导用户刷新重载,所以更倾向于用类似弹窗的方式处理。

引导重载与重载

当然并非是一定要引导用户进行冲下操作的,即便要重载也并非一定是要通过弹窗的。但这里为了分析就默认是在弹窗是情况下

image.png

接下来分析下怎么重载界面吧。

最简单的粗暴的当然是直接调用浏览器函数location.reload()了, 但是这一方法会全局重载,如果用户只是短时的网络波动就会在消耗性能的同时,增加用户的操作量,并不大友好,备选。

其次是借用Vue的Router-view

// app.vue
<router-view v-if="reload"></router-view>

data(){
  return {
    reload: true
  }
},
watch:{
  '$store.state.reload'(newVal)}{
      this.reload = false;
      setTimeout(()=> this.reload = true, 400);
  }

这里关于reload值的切换可以自定义,主要是借助v-if的值来重新挂载界面达到刷新的目的。

众所周知,v-if是移除dom和渲染dom,而非通过css属性控制显示隐藏。

但是这就有个问题, Vue默认是页面都挂载在app.vuerouter-view组件下面,即便个别是挂载在界面中也可以很好的处理。

但是在uniapp中App.vue是不能挂载html结构的,那这里就不能用这种方法了,就需要剑走偏锋了。

我在项目中的做法是,在每个界面混入一个mixin.js文件作公共方法库,当然也可以挂载在Vue的全局属性下。

currentPageReload(){
    uni.redirectTo({ 
        url: `${this.$Route.path}?${this.processReloadKey(this.$Route.query)}`
    }) 
},

使用uniapp的redirecTo方法关闭当前页,打开新的页面, 新的页面仍然是当前页并保留路由参数,避免意外。

以此来达到重载的目的。