Skip to content

浏览器API

浏览器api是一套在浏览器端实现的功能

复制功能 clipboard

复制底层基于navigator.clipboard和document.execCommand('copy')

document.execCommand('copy')已经被web标准标记为废弃,但目前仍然需要使用它, 因为navigator.clipboard要求在安全URL下访问的网站应用才可访问。

1234567891011121314151617181920212223242526
<template>
  <div>
    <input type="text" placeholder="输入" style="border: 1px solid #ccc;" v-model="text" />
    <v-button style="cursor: pointer;" @click="copy">复制</v-button>

    <v-button @click="handleImport">从剪切板中导入</v-button>
  </div>
</template>

<script lang="ts" setup>
import { clipboard } from '@cat-kit/fe'
import { shallowRef } from 'vue'

const text = shallowRef('')

const copy = async () => {
  await clipboard.copy(text.value)
  alert('复制成功, 粘贴测试')
}

const handleImport = async () => {
  const data = await clipboard.readText()
  alert(`当前导入的内容为: ${data}`)
}
</script>

读取文件 readFile

文件读取操作用于获取文件的二进制内容, 将媒体文件读取后展示在页面上等等。

TIP

可以在WebWorker中使用

ts
// read-file.worker.ts
import { readFile } from '@cat/fe'

onmessage = async (e: MessageAccept) {
  const { result } = await readFile(e.data, 'arrayBuffer')
  postMessage(result)

  self.close()
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
<template>
  <div>
    <div>
      <label>
        <input v-model="readType" type="radio" value="text" /> 文本
      </label>

      <label>
        <input v-model="readType" type="radio" value="dataUrl" /> 链接
      </label>

      <label>
        <input v-model="readType" type="radio" value="arrayBuffer" /> 缓冲数据
      </label>
      <label>
        <input v-model="readType" type="radio" value="binaryString" />
        二进制字符串
      </label>
    </div>

    <div>当前文件类型: {{ fileType }}</div>

    <!-- 读取文本 -->
    <div style="word-break: break-all" v-if="readType === 'text'">
      <input
        type="file"
        accept="text/*, image/svg+xml"
        @change="handleChange"
      />

      <div>{{ content }}</div>
    </div>

    <!-- 读取图片 -->
    <div style="word-break: break-all" v-else-if="readType === 'dataUrl'">
      <input type="file" accept="image/*" @change="handleChange" />
      <img style="width: 100px; height: 100px" v-if="content" :src="content" />
    </div>

    <!-- 读取缓冲区数据 -->
    <div style="word-break: break-all" v-else-if="readType === 'arrayBuffer'">
      <input type="file" @change="handleChange" />

      <div>
        总计 {{ bytes.length }}字节, {{ n(bytes.length / 1024).fixed(2) }}KB,
        {{ n(bytes.length / 1024 / 1024).fixed(2) }}MB
        <br />
        前100个字节: {{ bytes.slice(0, 100) }}...
      </div>
    </div>
    <!-- 读取二进制字符串 -->
    <div style="word-break: break-all" v-else-if="readType === 'binaryString'">
      <input type="file" @change="handleChange" />

      <div>{{ content?.slice(0, 100) }}...</div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { readFile, type ReadType, n } from '@cat-kit/fe'
import { computed, shallowRef, watch } from 'vue'

const readType = shallowRef<ReadType>('text')

const content = shallowRef<any>()

const fileType = shallowRef('')

watch(readType, v => {
  content.value = undefined
})

const handleChange = async (e: Event) => {
  const target = e.target as HTMLInputElement
  const file = target.files![0]
  if (!file) {
    fileType.value = ''
    content.value = undefined
    return
  }
  fileType.value = file.type
  const { result } = await readFile(file, readType.value as any)
  content.value = result
}

const bytes = computed(() => {
  return readType.value === 'arrayBuffer'
    ? new Uint8Array(content.value)
    : new Uint8Array()
})
</script>

MIT Licensed