Refactor:移除useCopyToClipboard hook, 使用navigator.clipboard进行替代。close #2723 (#3105)

* feat: 重写复制文本功能

* refactor: 替换复制文本示例代码

* chore: delete useCopyToClipboard hook
This commit is contained in:
invalid w
2023-10-08 10:50:05 +08:00
committed by GitHub
parent 18f55833e2
commit f3f2f548e6
6 changed files with 29 additions and 113 deletions

View File

@@ -65,7 +65,7 @@
</a-input>
</template>
<script lang="ts" setup>
import { ref, watchEffect, watch, unref } from 'vue';
import { ref, watchEffect, watch } from 'vue';
import { useDesign } from '/@/hooks/web/useDesign';
import { ScrollContainer } from '/@/components/Container';
import { Input, Popover, Pagination, Empty } from 'ant-design-vue';
@@ -77,10 +77,8 @@
import { usePagination } from '/@/hooks/web/usePagination';
import { useDebounceFn } from '@vueuse/core';
import { useI18n } from '/@/hooks/web/useI18n';
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
import { useMessage } from '/@/hooks/web/useMessage';
import svgIcons from 'virtual:svg-icons-names';
import { copyText } from '/@/utils/copyTextToClipboard';
// 没有使用别名引入是因为WebStorm当前版本还不能正确识别会报unused警告
const AInput = Input;
const APopover = Popover;
@@ -107,7 +105,7 @@
value: propTypes.string,
width: propTypes.string.def('100%'),
pageSize: propTypes.number.def(140),
copy: propTypes.bool.def(false),
copy: propTypes.bool.def(true),
mode: propTypes.oneOf<('svg' | 'iconify')[]>(['svg', 'iconify']).def('iconify'),
});
@@ -125,17 +123,6 @@
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,
@@ -160,10 +147,7 @@
function handleClick(icon: string) {
currentSelect.value = icon;
if (props.copy) {
clipboardRef.value = icon;
if (unref(isSuccessRef)) {
createMessage.success(t('component.icon.copy'));
}
copyText(icon, t('component.icon.copy'));
}
}

View File

@@ -1,70 +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

@@ -29,8 +29,7 @@
import { useDesign } from '/@/hooks/web/useDesign';
import { useI18n } from '/@/hooks/web/useI18n';
import { useMessage } from '/@/hooks/web/useMessage';
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
import { copyText } from '/@/utils/copyTextToClipboard';
import { updateColorWeak } from '/@/logics/theme/updateColorWeak';
import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
import defaultSetting from '/@/settings/projectSetting';
@@ -49,14 +48,12 @@
const appStore = useAppStore();
function handleCopy() {
const { isSuccessRef } = useCopyToClipboard(
JSON.stringify(unref(appStore.getProjectConfig), null, 2),
);
unref(isSuccessRef) &&
createSuccessModal({
title: t('layout.setting.operatingTitle'),
content: t('layout.setting.operatingContent'),
});
copyText(JSON.stringify(unref(appStore.getProjectConfig), null, 2), null);
createSuccessModal({
title: t('layout.setting.operatingTitle'),
content: t('layout.setting.operatingContent'),
});
}
function handleResetSetting() {
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(
function () {
prompt && message.success(prompt);
},
function (error: Error) {
message.error('复制失败!' + error.message);
},
);
}

View File

@@ -11,9 +11,9 @@
<script lang="ts">
import { defineComponent, unref, ref } from 'vue';
import { CollapseContainer } from '/@/components/Container/index';
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
import { useMessage } from '/@/hooks/web/useMessage';
import { PageWrapper } from '/@/components/Page';
import { copyText } from '/@/utils/copyTextToClipboard';
export default defineComponent({
name: 'Copy',
@@ -21,7 +21,6 @@
setup() {
const valueRef = ref('');
const { createMessage } = useMessage();
const { clipboardRef, copiedRef } = useCopyToClipboard();
function handleCopy() {
const value = unref(valueRef);
@@ -29,10 +28,7 @@
createMessage.warning('请输入要拷贝的内容!');
return;
}
clipboardRef.value = value;
if (unref(copiedRef)) {
createMessage.warning('copy success');
}
copyText(value);
}
return { handleCopy, value: valueRef };
},

View File

@@ -19,10 +19,10 @@
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, unref } from 'vue';
import { defineComponent, reactive, toRefs } from 'vue';
import { CodeEditor, MODE } from '/@/components/CodeEditor';
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
import { copyText } from '/@/utils/copyTextToClipboard';
import { useMessage } from '/@/hooks/web/useMessage';
export default defineComponent({
@@ -58,7 +58,7 @@
const handleExportJson = () => {
exportData(props.editorJson);
};
const { clipboardRef, copiedRef } = useCopyToClipboard();
const { createMessage } = useMessage();
const handleCopyJson = () => {
@@ -68,10 +68,7 @@
createMessage.warning('代码为空!');
return;
}
clipboardRef.value = value;
if (unref(copiedRef)) {
createMessage.warning('复制成功!');
}
copyText(value);
};
return {