diff --git a/package.json b/package.json index 65f09e6..e074c4f 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "@microsoft/signalr": "^6.0.4", "@vueuse/core": "^8.5.0", "axios": "^0.27.1", - "clipboard": "^2.0.10", "countup.js": "^2.1.0", "echarts": "5.2.2", "echarts-wordcloud": "^2.0.0", @@ -33,6 +32,7 @@ "nprogress": "0.2.0", "sortablejs": "^1.15.0", "vue": "^3.2.36", + "vue-clipboard3": "^2.0.0", "vue-cropper": "1.0.2", "vue-i18n": "^9.1.10", "vue-router": "^4.0.15", @@ -50,4 +50,4 @@ "vite-plugin-svg-icons": "1.0.5", "vite-plugin-vue-setup-extend": "^0.4.0" } -} +} \ No newline at end of file diff --git a/src/directive/index.js b/src/directive/index.js index c7e412e..7564339 100644 --- a/src/directive/index.js +++ b/src/directive/index.js @@ -3,11 +3,13 @@ import hasPermi from './permission/hasPermi' import clipboard from './module/clipboard' import drag from './module/drag' import waves from './module/waves' +// import copyText from './module/copyText' -export default function directive(app){ +export default function directive(app) { app.directive('hasRole', hasRole) app.directive('hasPermi', hasPermi) - app.directive('clipboard', clipboard) - app.directive('drag', drag) - app.directive('waves', waves) + app.directive('clipboard', clipboard) + app.directive('drag', drag) + app.directive('waves', waves) + // app.directive('copyText', copyText) } \ No newline at end of file diff --git a/src/directive/module/clipboard.js b/src/directive/module/clipboard.js index ae954ac..e186c55 100644 --- a/src/directive/module/clipboard.js +++ b/src/directive/module/clipboard.js @@ -1,55 +1,77 @@ /** * v-clipboard 文字复制剪贴 - * Copyright (c) 2021 ruoyi + * + 作者: CodePlayer + 链接: https: //juejin.cn/post/7052968352007847972 + 来源: 稀土掘金 + 著作权归作者所有。 商业转载请联系作者获得授权, 非商业转载请注明出处。 */ -import Clipboard from 'clipboard' +// import Clipboard from 'clipboard' +import useClipboard from "vue-clipboard3"; +const { toClipboard } = useClipboard(); export default { - mounted(el, binding, vnode) { + // 挂载 + mounted(el, binding) { + // binding.arg 为动态指令参数 + // 由于 指令是支持响应式的 因此我们指令需要有一个“全局”对象,这里我们为了不借助其他对象浪费资源,就直接使用el自身了 + // 将copy的值 成功回调 失败回调 及 click事件都绑定到el上 这样在更新和卸载时方便操作 switch (binding.arg) { - case 'success': - el._vClipBoard_success = binding.value; + case "copy": + // copy值 + el.clipValue = binding.value; + // click事件 + el.clipCopy = function () { + toClipboard(el.clipValue) + .then(result => { + el.clipSuccess && el.clipSuccess(result); + }) + .catch(err => { + el.clipError && el.clipError(err); + }); + }; + // 绑定click事件 + el.addEventListener("click", el.clipCopy); break; - case 'error': - el._vClipBoard_error = binding.value; + case "success": + // 成功回调 + el.clipSuccess = binding.value; + break; + case "error": + // 失败回调 + el.clipError = binding.value; break; - default: { - const clipboard = new Clipboard(el, { - text: () => binding.value, - action: () => binding.arg === 'cut' ? 'cut' : 'copy' - }); - clipboard.on('success', e => { - const callback = el._vClipBoard_success; - callback && callback(e); - }); - clipboard.on('error', e => { - console.log('复制失败', e) - const callback = el._vClipBoard_error; - callback && callback(e); - }); - el._vClipBoard = clipboard; - } } }, - update(el, binding) { - if (binding.arg === 'success') { - el._vClipBoard_success = binding.value; - } else if (binding.arg === 'error') { - el._vClipBoard_error = binding.value; - } else { - el._vClipBoard.text = function () { return binding.value; }; - el._vClipBoard.action = () => binding.arg === 'cut' ? 'cut' : 'copy'; + // 相应修改 这里比较简单 重置相应的值即可 + updated(el, binding) { + switch (binding.arg) { + case "copy": + el.clipValue = binding.value; + break; + case "success": + el.clipSuccess = binding.value; + break; + case "error": + el.clipError = binding.value; + break; } }, - unbind(el, binding) { - if (!el._vClipboard) return - if (binding.arg === 'success') { - delete el._vClipBoard_success; - } else if (binding.arg === 'error') { - delete el._vClipBoard_error; - } else { - el._vClipBoard.destroy(); - delete el._vClipBoard; + // 卸载 删除click事件 删除对应的自定义属性 + unmounted(el, binding) { + switch (binding.arg) { + case "copy": + el.removeEventListener("click", el.clipCopy); + delete el.clipValue; + delete el.clipCopy; + break; + case "success": + delete el.clipSuccess; + break; + case "error": + delete el.clipError; + break; } - } + }, + } \ No newline at end of file diff --git a/src/directive/module/copyText.js b/src/directive/module/copyText.js new file mode 100644 index 0000000..7063df8 --- /dev/null +++ b/src/directive/module/copyText.js @@ -0,0 +1,66 @@ +/** +* v-copyText 复制文本内容 +* Copyright (c) 2022 ruoyi +*/ + +export default { + beforeMount(el, { value, arg }) { + if (arg === "callback") { + el.$copyCallback = value; + } else { + el.$copyValue = value; + const handler = () => { + copyTextToClipboard(el.$copyValue); + if (el.$copyCallback) { + el.$copyCallback(el.$copyValue); + } + }; + el.addEventListener("click", handler); + el.$destroyCopy = () => el.removeEventListener("click", handler); + } + } +} + +function copyTextToClipboard(input, { target = document.body } = {}) { + const element = document.createElement('textarea'); + const previouslyFocusedElement = document.activeElement; + + element.value = input; + + // Prevent keyboard from showing on mobile + element.setAttribute('readonly', ''); + + element.style.contain = 'strict'; + element.style.position = 'absolute'; + element.style.left = '-9999px'; + element.style.fontSize = '12pt'; // Prevent zooming on iOS + + const selection = document.getSelection(); + const originalRange = selection.rangeCount > 0 && selection.getRangeAt(0); + + target.append(element); + element.select(); + + // Explicit selection workaround for iOS + element.selectionStart = 0; + element.selectionEnd = input.length; + + let isSuccess = false; + try { + isSuccess = document.execCommand('copy'); + } catch { } + + element.remove(); + + if (originalRange) { + selection.removeAllRanges(); + selection.addRange(originalRange); + } + + // Get the focus back on the previously focused element, if any + if (previouslyFocusedElement) { + previouslyFocusedElement.focus(); + } + + return isSuccess; +}