Files
JoyD/Web/Vue/CubeLib/examples/CubeWebSocket/BasicExample.vue
2026-01-30 15:38:48 +08:00

321 lines
6.4 KiB
Vue

<template>
<div class="basic-example">
<div class="status-panel">
<h3>基础使用示例</h3>
<div class="status-item">
<span class="label">连接状态:</span>
<span :class="['status', status]">{{ statusText }}</span>
</div>
<div class="status-item">
<span class="label">已连接:</span>
<span :class="['value', isConnected ? 'yes' : 'no']">
{{ isConnected ? '是' : '否' }}
</span>
</div>
<div class="status-item">
<span class="label">重连次数:</span>
<span class="value">{{ reconnectCount }}</span>
</div>
</div>
<div class="message-panel">
<h3>消息列表</h3>
<div class="message-list">
<div v-for="(msg, index) in messages" :key="index" class="message-item">
<div class="message-type">{{ msg.type }}</div>
<div class="message-content">{{ JSON.stringify(msg.data, null, 2) }}</div>
</div>
<div v-if="messages.length === 0" class="empty">暂无消息</div>
</div>
</div>
<div class="control-panel">
<h3>控制面板</h3>
<div class="control-buttons">
<button @click="handleConnect" :disabled="isConnected">连接</button>
<button @click="handleDisconnect" :disabled="!isConnected">断开</button>
<button @click="handleSend" :disabled="!isConnected">发送测试消息</button>
<button @click="handleClearMessages">清空消息</button>
</div>
</div>
<CubeWebSocket
ref="wsRef"
ws-url="ws://localhost:8086/ws"
:auto-connect="false"
:reconnect="true"
:debug-mode="true"
@connected="handleConnected"
@disconnected="handleDisconnected"
@error="handleError"
@message="handleMessage"
@status-changed="handleStatusChanged"
@connecting="handleConnecting"
@reconnecting="handleReconnecting"
@message-sent="handleMessageSent"
@message-queued="handleMessageQueued"
@message-failed="handleMessageFailed"
/>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import CubeWebSocket from 'joyd.web.vue.cubelib'
const wsRef = ref(null)
const status = ref('disconnected')
const messages = ref([])
const reconnectCount = ref(0)
const errorMessage = ref('')
const statusText = computed(() => {
const statusMap = {
disconnected: '未连接',
connecting: '连接中',
connected: '已连接',
reconnecting: '重连中',
error: '错误'
}
return statusMap[status.value] || status.value
})
const isConnected = computed(() => status.value === 'connected')
const handleConnected = () => {
console.log('[基础示例] WebSocket 已连接')
reconnectCount.value = 0
}
const handleDisconnected = (code, reason) => {
console.log('[基础示例] WebSocket 已断开:', code, reason)
}
const handleError = (error) => {
console.error('[基础示例] WebSocket 错误:', error)
errorMessage.value = error.message || '连接错误'
setTimeout(() => {
errorMessage.value = ''
}, 3000)
}
const handleMessage = (message) => {
console.log('[基础示例] 收到消息:', message)
messages.value.push({
...message,
timestamp: new Date().toLocaleTimeString()
})
}
const handleStatusChanged = (newStatus) => {
console.log('[基础示例] 状态变化:', newStatus)
status.value = newStatus
}
const handleConnecting = () => {
console.log('[基础示例] 开始连接')
}
const handleReconnecting = () => {
console.log('[基础示例] 开始重连')
reconnectCount.value++
}
const handleMessageSent = (message) => {
console.log('[基础示例] 消息已发送:', message)
}
const handleMessageQueued = (message) => {
console.log('[基础示例] 消息已加入队列:', message)
}
const handleMessageFailed = (data) => {
console.error('[基础示例] 消息发送失败:', data)
}
const handleConnect = () => {
wsRef.value?.connect()
}
const handleDisconnect = () => {
wsRef.value?.disconnect()
}
const handleSend = () => {
wsRef.value?.send('test', {
text: 'Hello from CubeWebSocket',
timestamp: Date.now()
})
}
const handleClearMessages = () => {
messages.value = []
}
</script>
<style scoped>
.basic-example {
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}
.status-panel {
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
}
.status-panel h3 {
margin-top: 0;
margin-bottom: 15px;
color: #333;
}
.status-item {
display: flex;
align-items: center;
margin-bottom: 10px;
font-size: 14px;
}
.status-item .label {
width: 100px;
color: #666;
}
.status-item .value {
font-weight: 600;
color: #333;
}
.status {
padding: 4px 12px;
border-radius: 4px;
font-weight: 600;
}
.status.disconnected {
background: #999;
color: #fff;
}
.status.connecting {
background: #faad14;
color: #fff;
}
.status.connected {
background: #52c41a;
color: #fff;
}
.status.reconnecting {
background: #1890ff;
color: #fff;
}
.status.error {
background: #ff4d4f;
color: #fff;
}
.value.yes {
color: #52c41a;
}
.value.no {
color: #999;
}
.message-panel {
background: #fff;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #e0e0e0;
}
.message-panel h3 {
margin-top: 0;
margin-bottom: 15px;
color: #333;
}
.message-list {
max-height: 400px;
overflow-y: auto;
}
.message-item {
padding: 12px;
border-bottom: 1px solid #f0f0f0;
}
.message-item:last-child {
border-bottom: none;
}
.message-type {
font-weight: 600;
color: #667eea;
margin-bottom: 6px;
}
.message-content {
font-family: 'Courier New', monospace;
font-size: 12px;
color: #333;
white-space: pre-wrap;
word-break: break-all;
}
.empty {
text-align: center;
padding: 40px;
color: #999;
}
.control-panel {
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
}
.control-panel h3 {
margin-top: 0;
margin-bottom: 15px;
color: #333;
}
.control-buttons {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.control-buttons button {
padding: 10px 20px;
border: none;
border-radius: 4px;
background: #667eea;
color: #fff;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
}
.control-buttons button:hover:not(:disabled) {
background: #5568d3;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(102, 126, 234, 0.3);
}
.control-buttons button:disabled {
background: #ccc;
cursor: not-allowed;
opacity: 0.6;
}
</style>