vue3项目中如何判断网络状态?useNetwork很方便!

useNetwork是响应式的网络状态API 。Network Information API 提供像连接类型(例如wifi, 蜂窝)等有关系统连接的信息。这可用于根据用户的连接选择高清晰度内容或低清晰度内容。 整个API除了由NetworkInformation接口组成外还包括Navigator接口的单个属性:Navigator.connection

1.浏览器原生网络状态相关API

在学习useNetwork之前,需要掌握下图所示的前置知识:

图中所涉及的知识归纳如下:

2.useNetwork

2.1 示例

<script setup lang="ts">
  import { reactive,toRefs  } from 'vue'
  import { useNetwork } from '@vueuse/core'
  
  const network = reactive(useNetwork())
  const {isSupported,
         isOnline,
         saveData,
         offlineAt,
         onlineAt,
         downlink,
         downlinkMax,
         effectiveType,
         rtt,
         type} = toRefs(network)
</script>

<template>
  <ul>
    <li>是否支持检测网络状态:{{isSupported}}</li>
    <li>当前是否在线:{{isOnline}}</li>
    <li>saveData: {{saveData}}</li>
    <li>offlineAt: {{offlineAt}}</li>
    <li>onlineAt: {{onlineAt}}</li>
    <li>downlink:{{downlink}}</li>
    <li>downlinkMax: {{downlinkMax}}</li>
    <li>effectiveType:{{effectiveType}}</li>
    <li>rtt:{{rtt}}</li>
    <li>type:{{type}}</li>
  </ul>
</template>
复制代码

如上图所示代码中引入了useNetwork,并使用vue的reactive和toRefs拿到和网络状态有关的响应式数据。代码运行结果如下图实时:

2.2 useNetwork源码

核心源码不到70行,这里先看一下折叠后的大概情况,您也可以查看全部源码进行学习。

以上代码拆分为如下几部分:

2.2.1 初始化

const navigator = window?.navigator
const isSupported = Boolean(navigator && 'connection' in navigator)
  
const isOnline = ref(true)
const saveData = ref(false)
const offlineAt: Ref<number | undefined> = ref(undefined)
const onlineAt: Ref<number | undefined> = ref(undefined)
const downlink: Ref<number | undefined> = ref(undefined)
const downlinkMax: Ref<number | undefined> = ref(undefined)
const rtt: Ref<number | undefined> = ref(undefined)
const effectiveType: Ref<NetworkEffectiveType> = ref(undefined)
const type: Ref<NetworkType> = ref<NetworkType>('unknown')
复制代码

首先获取window的navigator属性,并初始化了初始化isSupported和要返回的其他9个响应式变量。解释一下之前没有介绍的变量:offlineAt表示什么时候不能链接网络了,onlineAt表示什么时候可以链接网络了。

2.2.2 updateNetworkInformation更新网络信息

function updateNetworkInformation() {
  if (!navigator)
    return

  isOnline.value = navigator.onLine
  offlineAt.value = isOnline.value ? undefined : Date.now()
  onlineAt.value = isOnline.value ? Date.now() : undefined

  if (connection) {
    downlink.value = connection.downlink
    downlinkMax.value = connection.downlinkMax
    effectiveType.value = connection.effectiveType
    rtt.value = connection.rtt
    saveData.value = connection.saveData
    type.value = connection.type
  }
}
复制代码

获取navigator.onLine属性值赋给isOnline,如果isOnline.value为真值则当前没有断网;如果navigator.connection存在则从connection上读取相应属性并赋值给相应的响应式变量。

需要注意的是在调用useNetwork的时候就调用了一次updateNetworkInformation方法。

2.2.3 监听window的online和offline事件

if (window) {
  useEventListener(window, 'offline', () => {
    isOnline.value = false
    offlineAt.value = Date.now()
  })

  useEventListener(window, 'online', () => {
    isOnline.value = true
    onlineAt.value = Date.now()
  })
}
复制代码

当发生了offline和online事件的时候更新isOnline、offlineAt和offlineAt。

2.2.4 监听connection的change事件

if (connection)
    useEventListener(connection, 'change', updateNetworkInformation, false)
复制代码

监听connection的changes事件,回调函数为updateNetworkInformation,用于更新网络连接的相关属性。

2.2.5 返回描述网络状态的相应式变量

return {
  isSupported,
  isOnline,
  saveData,
  offlineAt,
  onlineAt,
  downlink,
  downlinkMax,
  effectiveType,
  rtt,
  type,
}
复制代码

返回描述网络状态的响应式变量供用户使用。至此useNetwork的源码分析完毕。下面我们再看一下useNetwork的应用:useOnline。

2.3 useOnline源码分析

useOnline是vueuse提供的另外一个关于网络状态的API, 源码如下:

import { useNetwork } from '../useNetwork'
import type { ConfigurableWindow } from '../_configurable'

export function useOnline(options: ConfigurableWindow = {}) {
  const { isOnline } = useNetwork(options)
  return isOnline
}
复制代码

可见useOnline是对useNetwork的应用。

3.总结

首先我们学习了和网络状态有关的浏览器原生API接口和事件,有navigator.onLine,navigator.connection,offline事件,online事件;然后我们学习了useNetwork的使用和源码,其本质在于使用refs定义了表示网络状态的响应式变量并在window的offline事件、online事件,connection的change事件被触发时修改相应的响应式变量;最后我们还展示了vueuse内部对useNetwork的一个应用,那就是useOnline。

猜你喜欢

转载自juejin.im/post/7110143190052634637
今日推荐