Browse Source

perf: useClipboard

kailong321200875 1 year ago
parent
commit
1db22482b4
4 changed files with 90 additions and 0 deletions
  1. 9 0
      mock/role/index.ts
  2. 47 0
      src/hooks/web/useClipboard.ts
  3. 8 0
      src/router/index.ts
  4. 26 0
      src/views/hooks/useClipboard.vue

+ 9 - 0
mock/role/index.ts

@@ -361,6 +361,14 @@ const adminList = [
         meta: {
           title: 'useCrudSchemas'
         }
+      },
+      {
+        path: 'useClipboard',
+        component: 'views/hooks/useClipboard',
+        name: 'UseClipboard',
+        meta: {
+          title: 'useClipboard'
+        }
       }
     ]
   },
@@ -626,6 +634,7 @@ const testList: string[] = [
   '/hooks/useTagsView',
   '/hooks/useValidator',
   '/hooks/useCrudSchemas',
+  '/hooks/useClipboard',
   '/level',
   '/level/menu1',
   '/level/menu1/menu1-1',

+ 47 - 0
src/hooks/web/useClipboard.ts

@@ -0,0 +1,47 @@
+import { ref } from 'vue'
+
+const useClipboard = () => {
+  const copied = ref(false)
+  const text = ref('')
+  const isSupported = ref(false)
+
+  if (!navigator.clipboard && !document.execCommand) {
+    isSupported.value = false
+  } else {
+    isSupported.value = true
+  }
+
+  const copy = (str: string) => {
+    if (navigator.clipboard) {
+      navigator.clipboard.writeText(str).then(() => {
+        text.value = str
+        copied.value = true
+        resetCopied()
+      })
+      return
+    }
+    const input = document.createElement('input')
+    input.setAttribute('readonly', 'readonly')
+    input.setAttribute('value', str)
+    document.body.appendChild(input)
+    input.select()
+    input.setSelectionRange(0, 9999)
+    if (document.execCommand('copy')) {
+      text.value = str
+      document.execCommand('copy')
+      copied.value = true
+      resetCopied()
+    }
+    document.body.removeChild(input)
+  }
+
+  const resetCopied = () => {
+    setTimeout(() => {
+      copied.value = false
+    }, 1500)
+  }
+
+  return { copy, text, copied, isSupported }
+}
+
+export { useClipboard }

+ 8 - 0
src/router/index.ts

@@ -403,6 +403,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
         meta: {
           title: 'useCrudSchemas'
         }
+      },
+      {
+        path: 'useClipboard',
+        component: () => import('@/views/hooks/useClipboard.vue'),
+        name: 'UseClipboard',
+        meta: {
+          title: 'useClipboard'
+        }
       }
     ]
   },

+ 26 - 0
src/views/hooks/useClipboard.vue

@@ -0,0 +1,26 @@
+<script setup lang="ts">
+import { ContentWrap } from '@/components/ContentWrap'
+import { useClipboard } from '@/hooks/web/useClipboard'
+import { ElButton, ElInput } from 'element-plus'
+import { ref } from 'vue'
+
+const { copy, copied, text, isSupported } = useClipboard()
+
+const source = ref('')
+</script>
+
+<template>
+  <ContentWrap title="useClipboard">
+    <ElInput v-model="source" placeholder="请输入要复制的内容" />
+    <div v-if="isSupported">
+      <ElButton @click="copy(source)" type="primary" class="mt-20px">
+        <span v-if="!copied">复制</span>
+        <span v-else>已复制</span>
+      </ElButton>
+      <p>
+        当前已复制: <code>{{ text || 'none' }}</code>
+      </p>
+    </div>
+    <p v-else> 你的浏览器不支持 Clipboard API </p>
+  </ContentWrap>
+</template>