jingrowtools/src/shared/components/ClickToCopyField.vue
jingrow 911ae5e53b feat: 系统设置页面增加个人资料和开发者标签页
- 使用 naive-ui Tabs 组件实现标签页布局,对齐 jcloud dashboard 前端
- 个人资料标签页:显示和编辑用户信息(用户名、手机、邮箱)、邮箱通知设置
- 开发者标签页:API 访问(创建/重新生成 API Key)、SSH 密钥管理、功能标志配置
- 创建账户相关 API 接口文件(account.ts),使用 jcloud.api.account.get 获取用户信息
- 创建 ClickToCopyField 组件用于一键复制文本内容
- API 接口与 jcloud dashboard 保持一致,实现相同的功能
2026-01-04 19:54:02 +08:00

79 lines
1.5 KiB
Vue

<template>
<div class="click-to-copy-field">
<n-input
:value="textContent"
readonly
:placeholder="placeholder"
class="copy-input"
>
<template #suffix>
<n-button
quaternary
size="small"
@click="handleCopy"
:loading="copying"
class="copy-button"
>
<template #icon>
<n-icon>
<Icon :icon="copied ? 'tabler:check' : 'tabler:copy'" />
</n-icon>
</template>
</n-button>
</template>
</n-input>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { NInput, NButton, NIcon, useMessage } from 'naive-ui'
import { Icon } from '@iconify/vue'
interface Props {
textContent: string
placeholder?: string
}
const props = withDefaults(defineProps<Props>(), {
placeholder: ''
})
const message = useMessage()
const copying = ref(false)
const copied = ref(false)
const handleCopy = async () => {
if (!props.textContent) return
copying.value = true
try {
await navigator.clipboard.writeText(props.textContent)
copied.value = true
message.success('已复制到剪贴板')
setTimeout(() => {
copied.value = false
}, 2000)
} catch (error) {
message.error('复制失败')
} finally {
copying.value = false
}
}
</script>
<style scoped>
.click-to-copy-field {
width: 100%;
}
.copy-input {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 13px;
}
.copy-button {
margin-right: 4px;
}
</style>