useNetwork是响应式的网络状态API 。Network Information API 提供像连接类型(例如wifi, 蜂窝)等有关系统连接的信息。这可用于根据用户的连接选择高清晰度内容或低清晰度内容。 整个API除了由NetworkInformation接口组成外还包括Navigator接口的单个属性:Navigator.connection。
1.浏览器原生网络状态相关API
在学习useNetwork之前,需要掌握下图所示的前置知识:
图中所涉及的知识归纳如下:
- 需要监听window上的两个事件:offline事件和online事件,这两个事件会影响到navigator的onLine属性。
- navigator的onLine属性用于表示是否在线
- navigator的connection属性 用来展示网络连接的信息,这些信息由NetworkInformation接口描述。
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。