refactor(util): 移除useCopyToClipboard hook, 使用navigator.clipboard进行替代

pull/38/head
xingyu 2023-10-10 11:14:15 +08:00
parent 0bdfd88035
commit aa63382d1a
6 changed files with 29 additions and 109 deletions

View File

@ -1,9 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, unref } from 'vue' import { ref } from 'vue'
import { CodeEditor, MODE } from '@/components/CodeEditor' import { CodeEditor, MODE } from '@/components/CodeEditor'
import { useCopyToClipboard } from '@/hooks/web/useCopyToClipboard'
import { useMessage } from '@/hooks/web/useMessage' import { useMessage } from '@/hooks/web/useMessage'
import { copyText } from '@/utils/copyTextToClipboard'
const props = defineProps( const props = defineProps(
{ {
@ -33,7 +33,6 @@ function exportData(data: string, fileName = `file.${props.fileFormat}`) {
function handleExportJson() { function handleExportJson() {
exportData(props.editorJson) exportData(props.editorJson)
} }
const { clipboardRef, copiedRef } = useCopyToClipboard()
const { createMessage } = useMessage() const { createMessage } = useMessage()
function handleCopyJson() { function handleCopyJson() {
@ -43,9 +42,7 @@ function handleCopyJson() {
createMessage.warning('代码为空!') createMessage.warning('代码为空!')
return return
} }
clipboardRef.value = value copyText(value)
if (unref(copiedRef))
createMessage.warning('复制成功!')
} }
</script> </script>

View File

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, unref, watch, watchEffect } from 'vue' import { ref, watch, watchEffect } from 'vue'
import { Empty, Input, Pagination, Popover } from 'ant-design-vue' import { Empty, Input, Pagination, Popover } from 'ant-design-vue'
import { useDebounceFn } from '@vueuse/core' import { useDebounceFn } from '@vueuse/core'
import svgIcons from 'virtual:svg-icons-names' import svgIcons from 'virtual:svg-icons-names'
@ -12,14 +12,13 @@ import { ScrollContainer } from '@/components/Container'
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { usePagination } from '@/hooks/web/usePagination' import { usePagination } from '@/hooks/web/usePagination'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { useCopyToClipboard } from '@/hooks/web/useCopyToClipboard' import { copyText } from '@/utils/copyTextToClipboard'
import { useMessage } from '@/hooks/web/useMessage'
const props = defineProps({ const props = defineProps({
value: propTypes.string, value: propTypes.string,
width: propTypes.string.def('100%'), width: propTypes.string.def('100%'),
pageSize: propTypes.number.def(140), pageSize: propTypes.number.def(140),
copy: propTypes.bool.def(false), copy: propTypes.bool.def(true),
mode: propTypes.oneOf(['svg', 'iconify']).def('iconify'), mode: propTypes.oneOf(['svg', 'iconify']).def('iconify'),
}) })
const emit = defineEmits(['change', 'update:value']) const emit = defineEmits(['change', 'update:value'])
@ -52,17 +51,6 @@ const { prefixCls } = useDesign('icon-picker')
const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100) const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100)
let clipboardRef
let isSuccessRef
if (props.copy) {
const clipboard = useCopyToClipboard(props.value)
clipboardRef = clipboard?.clipboardRef
isSuccessRef = clipboard?.isSuccessRef
}
const { createMessage } = useMessage()
const { getPaginationList, getTotal, setCurrentPage } = usePagination(currentList, props.pageSize) const { getPaginationList, getTotal, setCurrentPage } = usePagination(currentList, props.pageSize)
watchEffect(() => { watchEffect(() => {
@ -83,11 +71,8 @@ function handlePageChange(page: number) {
function handleClick(icon: string) { function handleClick(icon: string) {
currentSelect.value = icon currentSelect.value = icon
if (props.copy) { if (props.copy)
clipboardRef.value = icon copyText(icon, t('component.icon.copy'))
if (unref(isSuccessRef))
createMessage.success(t('component.icon.copy'))
}
} }
function handleSearchChange(e: ChangeEvent) { function handleSearchChange(e: ChangeEvent) {

View File

@ -1,69 +0,0 @@
import { ref, watch } from 'vue'
import { isDef } from '@/utils/is'
interface Options {
target?: HTMLElement
}
export function useCopyToClipboard(initial?: string) {
const clipboardRef = ref(initial || '')
const isSuccessRef = ref(false)
const copiedRef = ref(false)
watch(
clipboardRef,
(str?: string) => {
if (isDef(str)) {
copiedRef.value = true
isSuccessRef.value = copyTextToClipboard(str)
}
},
{ immediate: !!initial, flush: 'sync' },
)
return { clipboardRef, isSuccessRef, copiedRef }
}
export function copyTextToClipboard(input: string, { target = document.body }: Options = {}) {
const element = document.createElement('textarea')
const previouslyFocusedElement = document.activeElement
element.value = input
element.setAttribute('readonly', '')
;(element.style as any).contain = 'strict'
element.style.position = 'absolute'
element.style.left = '-9999px'
element.style.fontSize = '12pt'
const selection = document.getSelection()
let originalRange
if (selection && selection.rangeCount > 0)
originalRange = selection.getRangeAt(0)
target.append(element)
element.select()
element.selectionStart = 0
element.selectionEnd = input.length
let isSuccess = false
try {
isSuccess = document.execCommand('copy')
}
catch (e: any) {
throw new Error(e)
}
element.remove()
if (originalRange && selection) {
selection.removeAllRanges()
selection.addRange(originalRange)
}
if (previouslyFocusedElement) {
;(previouslyFocusedElement as HTMLElement).focus()
}
return isSuccess
}

View File

@ -10,8 +10,7 @@ import { useUserStore } from '@/store/modules/user'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage' import { useMessage } from '@/hooks/web/useMessage'
import { useCopyToClipboard } from '@/hooks/web/useCopyToClipboard' import { copyText } from '@/utils/copyTextToClipboard'
import { updateColorWeak } from '@/logics/theme/updateColorWeak' import { updateColorWeak } from '@/logics/theme/updateColorWeak'
import { updateGrayMode } from '@/logics/theme/updateGrayMode' import { updateGrayMode } from '@/logics/theme/updateGrayMode'
import defaultSetting from '@/settings/projectSetting' import defaultSetting from '@/settings/projectSetting'
@ -28,12 +27,11 @@ const userStore = useUserStore()
const appStore = useAppStore() const appStore = useAppStore()
function handleCopy() { function handleCopy() {
const { isSuccessRef } = useCopyToClipboard(JSON.stringify(unref(appStore.getProjectConfig), null, 2)) copyText(JSON.stringify(unref(appStore.getProjectConfig), null, 2), null)
unref(isSuccessRef) createSuccessModal({
&& createSuccessModal({ title: t('layout.setting.operatingTitle'),
title: t('layout.setting.operatingTitle'), content: t('layout.setting.operatingContent'),
content: t('layout.setting.operatingContent'), })
})
} }
function handleResetSetting() { function handleResetSetting() {
try { try {

View File

@ -0,0 +1,12 @@
import { message } from 'ant-design-vue'
export function copyText(text: string, prompt: string | null = '已成功复制到剪切板!') {
navigator.clipboard.writeText(text).then(
() => {
prompt && message.success(prompt)
},
(error: Error) => {
message.error(`复制失败!${error.message}`)
},
)
}

View File

@ -1,21 +1,20 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, unref } from 'vue' import { ref } from 'vue'
import { columns, searchFormSchema } from './file.data' import { columns, searchFormSchema } from './file.data'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage' import { useMessage } from '@/hooks/web/useMessage'
import { useCopyToClipboard } from '@/hooks/web/useCopyToClipboard'
import { IconEnum } from '@/enums/appEnum' import { IconEnum } from '@/enums/appEnum'
import { BasicUpload } from '@/components/Upload' import { BasicUpload } from '@/components/Upload'
import { BasicTable, TableAction, useTable } from '@/components/Table' import { BasicTable, TableAction, useTable } from '@/components/Table'
import { deleteFile, getFilePage } from '@/api/infra/file' import { deleteFile, getFilePage } from '@/api/infra/file'
import { getAccessToken, getTenantId } from '@/utils/auth' import { getAccessToken, getTenantId } from '@/utils/auth'
import { copyText } from '@/utils/copyTextToClipboard'
import { uploadApi } from '@/api/base/upload' import { uploadApi } from '@/api/base/upload'
defineOptions({ name: 'InfraFile' }) defineOptions({ name: 'InfraFile' })
const { t } = useI18n() const { t } = useI18n()
const { createMessage } = useMessage() const { createMessage } = useMessage()
const { clipboardRef, copiedRef } = useCopyToClipboard()
const uploadParams = ref({ const uploadParams = ref({
'Authorization': `Bearer ${getAccessToken()}`, 'Authorization': `Bearer ${getAccessToken()}`,
@ -43,9 +42,7 @@ function handleChange() {
} }
function handleCopy(record: Recordable) { function handleCopy(record: Recordable) {
clipboardRef.value = record.url copyText(record.url)
if (unref(copiedRef))
createMessage.warning('复制成功')
} }
async function handleDelete(record: Recordable) { async function handleDelete(record: Recordable) {