要实现点击表格中的邀请码并复制到剪贴板的功能,可以使用 JavaScript 的 Clipboard API。以下是如何在你的
invite-code-list.vue
文件中进行相应的修改:
实现步骤
- 添加点击事件处理函数:在
methods
中添加一个处理函数,用来处理点击并复制邀请码的操作。 - 在表格列中添加点击事件:在显示邀请码的表格列中添加
@click
事件,调用复制函数。
修改代码
1. 添加复制邀请码的处理函数
在 methods
中添加一个处理函数 copyInviteCode
,用于处理点击并复制邀请码的操作。
private copyInviteCode(inviteCode: string) {
const input = document.createElement('input');
input.value = inviteCode;
document.body.appendChild(input);
input.select();
document.execCommand('copy');
document.body.removeChild(input);
this.$message.success('邀请码已复制到剪贴板');
}
2. 在表格列中添加点击事件
在显示邀请码的表格列中添加 @click
事件,调用 copyInviteCode
函数。
<el-table-column
prop="inviteCode"
label="邀请码"
header-align="center"
align="center"
>
<template slot-scope="scope">
<div class="code-desc">
<span @click="copyInviteCode(scope.row.inviteCode)" class="copyable-code">{{ scope.row.inviteCode }}</span>
</div>
</template>
</el-table-column>
3. 添加样式
为了更好地用户体验,建议添加一些样式,使得邀请码在悬停时显示为可点击状态。
<style lang="scss" scoped>
.invite-code-wrap {
.operate-bar {
margin-bottom: 16px;
}
:deep(.el-table) {
th {
border-right: none;
cursor: default; // 设置光标为默认状态
user-select: none; // 禁止文本选择
.el-resizer {
display: none !important;
}
}
td {
border-right: none;
}
}
.copyable-code {
cursor: pointer;
color: #409EFF;
&:hover {
color: #66b1ff;
text-decoration: underline;
}
}
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
}
</style>
完整的 invite-code-list.vue
文件
<template>
<el-dialog
:visible="visible"
:before-close="handleClose"
:close-on-click-modal="false"
title="邀请码"
width="1600px"
append-to-body
:modal-append-to-body="false"
destroy-on-close
@open="console.log('el-dialog 打开了')"
>
<div class="invite-code-wrap">
<div class="operate-bar">
<el-button
type="primary"
size="mini"
@click="handleAdd"
>
添加
</el-button>
</div>
<div class="table">
<el-table
:data="tableData"
:height="tableHeight"
border
:fit="true"
:resize-observer="false"
style="width: 100%;"
>
<el-table-column
prop="id"
label="邀请码ID"
header-align="center"
align="center"
/>
<el-table-column
prop="inviteCode"
label="邀请码"
header-align="center"
align="center"
>
<template slot-scope="scope">
<div class="code-desc">
<span @click="copyInviteCode(scope.row.inviteCode)" class="copyable-code">{{ scope.row.inviteCode }}</span>
</div>
</template>
</el-table-column>
<el-table-column
prop="invitorId"
label="邀请人"
header-align="center"
align="center"
/>
<el-table-column
prop="inviteLevel"
label="邀请层级"
header-align="center"
align="center"
>
<template slot-scope="scope">
{{ scope.row.inviteLevel === 0 ? '不限' : `${scope.row.inviteLevel}级` }}
</template>
</el-table-column>
<el-table-column
prop="createdDate"
label="生成时间"
header-align="center"
align="center"
>
<template slot-scope="scope">
<div class="time-wrap">
{{ formatDate(scope.row.createdDate).date }}<br />
{{ formatDate(scope.row.createdDate).time }}
</div>
</template>
</el-table-column>
<el-table-column
prop="expireTime"
label="失效时间"
header-align="center"
align="center"
>
<template slot-scope="scope">
<div class="time-wrap">
{{ formatDate(scope.row.expireTime).date }}<br />
{{ formatDate(scope.row.expireTime).time }}
</div>
</template>
</el-table-column>
<el-table-column
prop="remark"
label="备注"
show-overflow-tooltip
header-align="center"
align="center"
/>
<el-table-column
prop="status"
label="状态"
header-align="center"
align="center"
>
<template slot-scope="scope">
<el-tag
:type="getStatusType(scope.row.status)"
size="mini"
>
{{ getStatusText(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column
prop="boundPhone"
label="绑定手机号"
header-align="center"
align="center"
/>
<el-table-column
prop="weixinNickname"
label="微信昵称"
header-align="center"
align="center"
/>
<el-table-column
prop="weixinHeadimg"
label="微信头像"
header-align="center"
align="center"
/>
<el-table-column
prop="boundWxUid"
label="绑定微信UID"
show-overflow-tooltip
header-align="center"
align="center"
width="100"
/>
<el-table-column
label="操作"
header-align="center"
align="center"
>
<template slot-scope="scope">
<div class="operation-cell">
<el-button
type="text"
size="mini"
class="operation-btn"
@click="handleLock(scope.row)"
>
{{ scope.row.isLocked === 0 ? '锁定' : '解锁' }}
</el-button>
<el-button
type="text"
size="mini"
class="operation-btn"
@click="handleRemark(scope.row)"
>
备注
</el-button>
<el-button
type="text"
size="mini"
class="operation-btn"
@click="handleLog(scope.row)"
>
日志
</el-button>
</div>
</template>
</el-table-column>
<el-table-column
v-if="false"
prop="admin"
label="管理人"
header-align="center"
align="center"
/>
</el-table>
</div>
<div class="pagination-container">
<el-pagination
:current-page="currentPage"
:page-size="pageSize"
:total="total"
background
layout="prev, pager, next"
@current-change="handleCurrentChange"
/>
</div>
</div>
<invite-code-add
:visible.sync="addVisible"
@success="handleAddSuccess"
/>
</el-dialog>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator'
import { ElMessageBox } from 'element-ui/types/message-box'
import InviteCodeAdd from './invite-code-add.vue'
import { AppModule } from '@/store/modules/app'
import { getInviteCodeList } from '@/api/invite-code'
import { getInviteCodeListByInvitor } from '@/api/invite-code'
import { UserModule } from '@/store/modules/user'
type MessageBoxData = {
value: string
action: 'confirm' | 'cancel'
}
@Component({
name: 'InviteCodeForm',
components: {
InviteCodeAdd
}
})
export default class extends Vue {
get tableHeight() {
return Math.floor(AppModule.tableHeight * 2 / 3)
}
@Prop({ default: false })
private visible!: boolean
private tableData = []
private currentPage = 1
private pageSize = 10
private total = 0
private addVisible = false
private getStatusType(status: string) {
const map: { [key: string]: string } = {
effective: 'primary',
expired: 'info',
locked: 'danger',
bound: 'success'
}
return map[status] || 'info'
}
private getStatusText(status: string) {
const map: { [key: string]: string } = {
effective: '待绑定',
expired: '已失效',
locked: '已锁定',
bound: '已绑定'
}
return map[status] || status
}
private formatDate(dateString: string): { date: string; time: string } {
if (!dateString) {
return { date: '', time: '' }
}
const date = new Date(dateString)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
const seconds = String(date.getSeconds()).padStart(2, '0')
return {
date: `${year}-${month}-${day}`,
time: `${hours}:${minutes}:${seconds}`
}
}
private handleClose() {
this.$emit('update:visible', false)
}
private handleAdd() {
this.addVisible = true
}
private async handleAddSuccess() {
// TODO: 刷新列表数据
this.addVisible = false
await this.fetchInviteCodeList()
}
private handleLock(row: any) {
// TODO: 处理锁/解锁逻辑
this.$confirm(`确定要${row.isLocked === 0 ? '锁定' : '解锁'}该邀请码吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async() => {
// TODO: 调用锁定/解锁API
row.isLocked = row.isLocked === 0 ? 1 : 0
this.$message.success(`${row.isLocked === 0 ? '解锁' : '锁定'}成功`)
})
.catch(() => { })
}
private handleRemark(row: any) {
this.$prompt('请输入备注', '备注', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputValue: row.remark,
inputValidator: (value: string) => {
return value.length <= 60
},
inputErrorMessage: '备注不能超过60个字符'
})
.then(async(data: MessageBoxData) => {
// TODO: 调用保存备注API
row.remark = data.value
this.$message.success('备注保存成功')
})
.catch(() => { })
}
private handleLog(row: any) {
// TODO: 显示日志记录
// 可以打开一个新的对话框显示操作日志列表
}
private handleCurrentChange(page: number) {
this.currentPage = page
// TODO: Add your fetch data logic here
}
async mounted() {
await this.fetchInviteCodeList()
}
private async fetchInviteCodeList() {
try {
const response = await getInviteCodeListByInvitor({
invitorId: UserModule.id,
page: this.currentPage,
pageSize: this.pageSize
})
console.log(response)
if (response && response.data && response.data.list) {
this.tableData = response.data.list
this.total = response.data.total
} else {
this.$message.error('获取邀请码列表失败: 返回数据结构不符合预期')
console.error('getInviteCodeList response data error', response)
}
} catch (error) {
console.error('获取邀请码列表时发生错误', error)
this.$message.error('获取邀请码列表时发生错误')
}
}
private copyInviteCode(inviteCode: string) {
const input = document.createElement('input')
input.value = inviteCode
document.body.appendChild(input)
input.select()
document.execCommand('copy')
document.body.removeChild(input)
this.$message.success('邀请码已复制到剪贴板')
}
}
</script>
<style lang="scss" scoped>
@import '@/styles/_list-page.scss';
.invite-code-wrap {
.operate-bar {
margin-bottom: 16px;
}
:deep(.el-table) {
th {
border-right: none;
cursor: default; // 设置光标为默认状态
user-select: none; // 禁止文本选择
.el-resizer {
display: none !important;
}
}
td {
border-right: none;
}
}
.copyable-code {
cursor: pointer;
color: #409EFF;
&:hover {
color: #66b1ff;
text-decoration: underline;
}
}
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
}
</style>
通过这些修改,你可以实现点击表格中的邀请码并复制到剪贴板的功能,并且提供了用户友好的视觉反馈。