3.1 Browser -- useClipboard

发布于:2024-09-05 ⋅ 阅读:(28) ⋅ 点赞:(0)

3.1 Browser – useClipboard

https://vueuse.org/core/useClipboard/

作用

响应式剪贴板API。提供响应剪贴板命令(剪切、复制和粘贴)以及异步读取和写入系统剪贴板的能力。对剪贴板内容的访问是在Permissions API后面进行控制的。未经用户许可,不得阅读或修改剪贴板内容。

官方示例

import { useClipboard } from '@vueuse/core'

const source = ref('Hello')
const { text, copy, copied, isSupported } = useClipboard({ source })
  • text:剪贴板的内容
  • copy:复制操作,也就是往剪贴板写入的操作
  • copied:是否复制了内容,默认copy后为true,一定时间后重新改为false
  • isSupported:浏览器是否支持剪贴板。注意不能配置legacy: true,否则始终返回true
  • 当浏览器不支持Clipboard API的时候,可以配置legacy: true,来使用execCommand方式来实现复制的功能。

源码分析

一般的用法就以下几种:

  1. 调用copy复制文件
  2. 手动修改text,从而影响剪贴板的内容
  3. *如果增加 {read: true}这个配置项,那么会在command+c 或者command+x的时候,自动更新text的值。
export function useClipboard(options: UseClipboardOptions<MaybeComputedRef<string> | undefined> = {}): UseClipboardReturn<boolean> {
  const {
    navigator = defaultNavigator,
    read = false, // 如果开启read,会在复制和剪切的时候,更新text的值
    source, 
    copiedDuring = 1500, // 如果调用copy,copied会变成true,1.5s后重新变成false
    legacy = false,
  } = options

  const events = ['copy', 'cut']
  const isClipboardApiSupported = useSupported(() => (navigator && 'clipboard' in navigator))
  const isSupported = computed(() => isClipboardApiSupported.value || legacy)
  const text = ref('')
  const copied = ref(false)
  const timeout = useTimeoutFn(() => copied.value = false, copiedDuring)

  function updateText() {
    // 如果支持ClipboardApi,那么从剪贴板读取文字,赋值给text
    if (isClipboardApiSupported.value) {
      navigator!.clipboard.readText().then((value) => {
        text.value = value
      })
    }
    else {
      // 如果不支持,那么使用传统方式读取
      text.value = legacyRead()
    }
  }

  // 如果read是true,那么监听'copy', 'cut'这两个事件,当事件触发,修改text
  if (isSupported.value && read) {
    for (const event of events)
      useEventListener(event as WindowEventName, updateText)
  }
 
  /**
  * 这是主要函数,只做了一件事,就是把传入的value写出剪贴板
  */
  async function copy(value = resolveUnref(source)) {
    if (isSupported.value && value != null) {
      if (isClipboardApiSupported.value)
        await navigator!.clipboard.writeText(value)
      else
        legacyCopy(value)

      text.value = value
      copied.value = true
      // 定时是为了1.5s后再改回来
      timeout.start()
    }
  }

  function legacyCopy(value: string) {
    const ta = document.createElement('textarea')
    ta.value = value ?? ''
    ta.style.position = 'absolute'
    ta.style.opacity = '0'
    document.body.appendChild(ta)
    ta.select()
    // execCommand 指的是执行命令,这里的copy的是选中的内容
    // 因为是传入value的形式,所以用户实际上没有选中任何值,才创建了一个textarea并自动选中它
    document.execCommand('copy')
    ta.remove()
  }

  // 传统方式这里,直接返回 选中的文字
  function legacyRead() {
    return document?.getSelection?.()?.toString() ?? ''
  }

  return {
    isSupported,
    text: text as ComputedRef<string>,
    copied: copied as ComputedRef<boolean>,
    copy,
  }
}


网站公告

今日签到

点亮在社区的每一天
去签到