当CV工程师碰到了拷贝粘贴的需求——useClipboard的使用及源码解析

大家好,我是若川。持续组织了近一年的源码共读活动,感兴趣的可以 点此加我微信ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外:目前建有江西|湖南|湖北籍前端群,可加我微信进群。

本文来自读者@NewName 的投稿。(基本我出一期源码共读就写一篇笔记的小伙伴),他自己曾说学到很多,同时更热爱学习了。


日常开发中我们有时会遇到拷贝粘贴的功能,笔者还记得曾经使用过react-copy-to-clipboard 和 vue-clipboard2。最近在看vueuse的时候发现了useClipboard就简单研究了一下,日后vue3项目中如果有使用场景可以用一下。

1.原生Clipboard

在看useClipboard源码之前,需要一些前置知识,那就是原生Clipboard的API。首先通过一张图概览一下浏览器原生Clipboard的相关知识:06b6ec5bb55f269c1f1ee2c431f84345.jpeg对上图涉及的知识逐一解释:

  • 剪贴板 Clipboard API 提供了响应剪贴板命令与异步读写系统剪贴板的能力。

  • 从权限 Permissions API 获取权限之后,才能访问剪贴板内容。

  • Clipboard API 包括异步剪贴板 API(AsyncClipboard API)和 剪贴板事件 API(Clipboard Event API)。

  • Clipboard读取剪切板有两个方法read()和readText()分别用于读取数据(比如图片)和文本;写入剪切板有两个方法write()和writeText()分别用于将任意数据写入和将文本写入。

  • ClipboardEvent接口描述了与修改剪切板相关信息的事件,包括剪切,复制和粘贴。

更多关于Clipboard API的细节以及兼容性问题您可以访问MDN文档详细学习。看一段示例代码:

navigator.clipboard.readText().then(
  clipText => document.querySelector(".editor").innerText += clipText);

2.useClipboard

2.1简介

useClipboard是响应式的剪贴板 API。提供剪贴板命令(剪切、复制和粘贴)以及异步读取和写入系统剪贴板的能力。访问剪贴板内容需要获得Permission API的相关权限,未经用户许可则不允许读取或更改剪贴板内容。

2.2例子

官方文档的示例代码如下所示:

<script setup lang="ts">
import { ref } from 'vue'
import { useClipboard, usePermission } from '@vueuse/core'

const input = ref('')

const { text, isSupported, copy } = useClipboard()
const permissionRead = usePermission('clipboard-read')
const permissionWrite = usePermission('clipboard-write')
</script>

<template>
  <div v-if="isSupported">
    <note>
      Clipboard Permission: read <b>{{ permissionRead }}</b> | write
      <b>{{ permissionWrite }}</b>
    </note>
    <p>
      Current copied: <code>{{ text || 'none' }}</code>
    </p>
    <input v-model="input" type="text">
    <button @click="copy(input)">
      Copy
    </button>
  </div>
  <p v-else>
    Your browser does not support Clipboard API
  </p>
</template>

首先引入 useClipboard,从useClipboard中解构出text, isSupported, copy。text是当前从剪切板读取到的文本,isSupported用于判断当前浏览器是否支持剪切板API,copy是将文本写入到剪切板的方法。usePermission用于获取权限,使用其查看了clipboard-read和clipboard-write的权限,并将权限展示到页面上。通过下图可以看到读取的权限是prompt也就是询问,而写入操作被授权了即granted。定义了响应式的变量input绑定到input标签上,当用户点击按钮时则调用copy()方法将input的内容写入剪切板。初始时我们没有向剪切板写入内容,text是空字符串,所以页面显示当前拷贝内容为none:b1f3ce7b52cbc47ec201b5865baae7bf.png当用户输入'123'点击copy按钮后,text的值也就是从剪切板读取到的文本变成了'123',所以页面展示内容也变成了'123'c5b61efafb8de262384eb7ec5cbc813b.png

2.3源码

这里我们只保留了核心逻辑的40多行代码,您可以查看源码 浏览全部代码。

export function useClipboard(options: ClipboardOptions<MaybeRef<string> | undefined> = {}): ClipboardReturn<boolean> {
  const {
    navigator = defaultNavigator,
    read = false,
    source,
    copiedDuring = 1500,
  } = options

  const events = ['copy', 'cut']
  const isSupported = Boolean(navigator && 'clipboard' in navigator)
  const text = ref('') // 与剪切板内容相对应的响应式值
  const copied = ref(false) // 是否拷贝完成

  const timeout = useTimeoutFn(() => copied.value = false, copiedDuring)
  // 更新text
  function updateText() {
    navigator!.clipboard.readText().then((value) => {
      text.value = value
    })
  }
  // 监听拷贝和剪切事件
  if (isSupported && read) {
    for (const event of events)
      useEventListener(event as WindowEventName, updateText)
  }
  // 将响应式值value拷贝到text
  async function copy(value = unref(source)) {
    if (isSupported && value != null) {
      await navigator!.clipboard.writeText(value)
      text.value = value
      copied.value = true
      timeout.start()
    }
  }
  
  return {
    isSupported,
    text: text as ComputedRef<string>,
    copied: copied as ComputedRef<boolean>,
    copy,
  }
}
2.3.1参数

(1)navigator默认为window.navigator, 其定义如下:

export const defaultNavigator = /* #__PURE__ */ isClient ? window.navigator : undefined

(2)read表示是否允许读取剪切板的内容,默认值是false, 也就是默认不实时读取剪切板的内容。我们通过例子的截图知道默认clipboard-read的值是prompt即询问,您可以通过浏览器的隐私设置来设置对于剪切板的权限:eb6fc19a74a719613a6ea1249d3063ec.png当调用useClipboard时指定了read为true, 并且你允许查看复制到剪切板中的数据,则此时只要剪切板里有内容就会实时显示:

const { text, isSupported, copy } = useClipboard({read:true})

8195ff78b0301d95018f3bde20243fe7.png上图是选中了"Clipboard"这几个字后右键点击复制后系统弹出确认框。363c9b810d36480110f2999dc62a63de.png上图是点击“允许”后复制到剪切板的内容实时赋值给了text并显示在页面中了。(3)source拷贝的源数据,可选的。source的原始值可以作为copy函数的默认值:

async function copy(value = unref(source)) {//省略}

如下图所示当没有指定source时的情况:233a4e1c373a82d0f089e0dc61fcaf42.png760a8aa9fbe9d502a773bced3ac740f3.png可以看到value对应传给copy的参数input, 而source是undefined。(4)copiedDuring为重置copied的毫秒数,copied用来表示是否拷贝完成。

2.3.2updateText
function updateText() {
  navigator!.clipboard.readText().then((value) => {
    text.value = value
  })
}

updateText用于更新text的值,从剪切板中读取数据然后更新text,读取剪切板数据使用的是readText()方法。

2.3.3监听拷贝和剪切
if (isSupported && read) {
  for (const event of events)
    useEventListener(event as WindowEventName, updateText)
}

在允许读取剪切板的情况下,如果发生拷贝和剪切则用剪切板中的内容更新text。

2.3.4 copy方法
async function copy(value = unref(source)) {
  if (isSupported && value != null) {
    await navigator!.clipboard.writeText(value)
    text.value = value
    copied.value = true
    timeout.start()
  }
}

copy方法用于将参数value写入剪切板并赋值给text,写入剪切板使用的是writeText()方法。至此,useClipbord的源码就分析完了,挺简单的但是读完也有收获。

3.总结

本文介绍了原生的Clipboard API之后又介绍了useClipboard 的使用,然后结合示例代码的调试过程分析了useClipboard 的源码。Clipboard API中的readText()和 writeText()是useClipboard 的灵魂。

9ded8d43d23a8b393b346aa2cd042e74.gif

················· 若川简介 ·················

你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇,在知乎、掘金收获超百万阅读。
从2014年起,每年都会写一篇年度总结,已经坚持写了8年,点击查看年度总结
同时,最近组织了源码共读活动,帮助4000+前端人学会看源码。公众号愿景:帮助5年内前端人走向前列。

98aabc9aa6a7ac5d5852195cef37dfc2.jpeg

扫码加我微信 ruochuan12、拉你进源码共读

今日话题

目前建有江西|湖南|湖北 籍 前端群,想进群的可以加我微信 ruochuan12 进群。分享、收藏、点赞、在看我的文章就是对我最大的支持

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
视觉惯性SLAM(Simultaneous Localization and Mapping)是一种在无人机、机器人和增强现实等领域广泛应用的技术,它结合了视觉和惯性传感器的信息,实现同时定位和地图构建。这种技术主要基于滤波器、优化和深度学习等方法。 视觉惯性SLAM的基本思想是通过相机和惯性传感器(例如加速度计和陀螺仪)融合数据,估计相机的位姿(位置和方向)以及地图的结构。其中,相机主要用于提取特征点或者进行直接法,从而计算相机位姿;惯性传感器主要用于补偿相机的运动和姿态估计。 在SLAM中,地图通常以稀疏或稠密的形式表示。稀疏地图主要通过特征点或关键帧来表示,而稠密地图则以像素级别的深度图表示。对于特征点的选择和跟踪,通常会使用特征描述子(如SIFT、ORB等)来进行匹配和跟踪。 在实现视觉惯性SLAM时,有一些常用的开源库和工具,例如: 1. OpenCV:一个广泛使用的计算机视觉库,提供了各种视觉算法和工具,如特征提取、特征匹配、相机标定等。 2. OpenVINS:一个基于视觉惯性传感器的SLAM系统,提供了实时的位姿估计和地图构建。 3. OKVIS:一个高性能的开源视觉惯性SLAM库,基于优化方法,提供了稠密地图和位姿估计等功能。 4. g2o:一个用于图优化的开源库,可用于SLAM中的位姿优化和地图构建。 以上是视觉惯性SLAM的基本理论和一些常用的开源工具,希望对你有所帮助。如果你需要进一步了解源码实现细节,可以查阅相关文献或者具体的开源项目代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值