提交 | 用户 | age
|
c62546
|
1 |
<template> |
V |
2 |
<PageWrapper title="WebSocket 示例"> |
|
3 |
<div class="flex"> |
|
4 |
<div class="w-1/3 bg-white p-4"> |
|
5 |
<div class="flex items-center"> |
|
6 |
<span class="text-lg font-medium mr-4"> 连接状态: </span> |
|
7 |
<Tag :color="getTagColor">{{ status }}</Tag> |
|
8 |
</div> |
|
9 |
<hr class="my-4" /> |
|
10 |
|
|
11 |
<div class="flex"> |
|
12 |
<a-input v-model:value="server" disabled> |
|
13 |
<template #addonBefore> 服务地址 </template> |
|
14 |
</a-input> |
|
15 |
<a-button :type="getIsOpen ? 'danger' : 'primary'" @click="toggle"> |
|
16 |
{{ getIsOpen ? '关闭连接' : '开启连接' }} |
|
17 |
</a-button> |
|
18 |
</div> |
|
19 |
<p class="text-lg font-medium mt-4">设置</p> |
|
20 |
<hr class="my-4" /> |
|
21 |
|
|
22 |
<InputTextArea |
|
23 |
placeholder="需要发送到服务器的内容" |
|
24 |
:disabled="!getIsOpen" |
|
25 |
v-model:value="sendValue" |
|
26 |
allowClear |
|
27 |
/> |
|
28 |
|
|
29 |
<a-button type="primary" block class="mt-4" :disabled="!getIsOpen" @click="handlerSend"> |
|
30 |
发送 |
|
31 |
</a-button> |
|
32 |
</div> |
|
33 |
|
|
34 |
<div class="w-2/3 bg-white ml-4 p-4"> |
|
35 |
<span class="text-lg font-medium mr-4"> 消息记录: </span> |
|
36 |
<hr class="my-4" /> |
|
37 |
|
|
38 |
<div class="max-h-80 overflow-auto"> |
|
39 |
<ul> |
967b28
|
40 |
<li v-for="item in getList" class="mt-2" :key="item.time"> |
c62546
|
41 |
<div class="flex items-center"> |
V |
42 |
<span class="mr-2 text-primary font-medium">收到消息:</span> |
|
43 |
<span>{{ formatToDateTime(item.time) }}</span> |
|
44 |
</div> |
|
45 |
<div> |
|
46 |
{{ item.res }} |
|
47 |
</div> |
|
48 |
</li> |
|
49 |
</ul> |
|
50 |
</div> |
|
51 |
</div> |
|
52 |
</div> |
|
53 |
</PageWrapper> |
|
54 |
</template> |
|
55 |
<script lang="ts"> |
|
56 |
import { defineComponent, reactive, watchEffect, computed, toRefs } from 'vue'; |
e5b2cc
|
57 |
import { Tag, Input } from 'ant-design-vue'; |
c62546
|
58 |
|
V |
59 |
import { PageWrapper } from '/@/components/Page'; |
|
60 |
|
|
61 |
import { useWebSocket } from '@vueuse/core'; |
|
62 |
|
|
63 |
import { formatToDateTime } from '/@/utils/dateUtil'; |
|
64 |
export default defineComponent({ |
|
65 |
components: { |
|
66 |
PageWrapper, |
|
67 |
[Input.name]: Input, |
|
68 |
InputTextArea: Input.TextArea, |
|
69 |
Tag, |
|
70 |
}, |
|
71 |
setup() { |
|
72 |
const state = reactive({ |
|
73 |
server: 'ws://localhost:3380/test', |
|
74 |
sendValue: '', |
|
75 |
recordList: [] as { id: number; time: number; res: string }[], |
|
76 |
}); |
|
77 |
|
|
78 |
const { status, data, send, close, open } = useWebSocket(state.server, { |
|
79 |
autoReconnect: true, |
|
80 |
heartbeat: true, |
|
81 |
}); |
|
82 |
|
|
83 |
watchEffect(() => { |
|
84 |
if (data.value) { |
|
85 |
try { |
|
86 |
const res = JSON.parse(data.value); |
|
87 |
state.recordList.push(res); |
|
88 |
} catch (error) { |
|
89 |
state.recordList.push({ |
|
90 |
res: data.value, |
|
91 |
id: Math.ceil(Math.random() * 1000), |
|
92 |
time: new Date().getTime(), |
|
93 |
}); |
|
94 |
} |
|
95 |
} |
|
96 |
}); |
|
97 |
|
|
98 |
const getIsOpen = computed(() => status.value === 'OPEN'); |
|
99 |
const getTagColor = computed(() => (getIsOpen.value ? 'success' : 'red')); |
|
100 |
|
|
101 |
const getList = computed(() => { |
|
102 |
return [...state.recordList].reverse(); |
|
103 |
}); |
|
104 |
|
|
105 |
function handlerSend() { |
|
106 |
send(state.sendValue); |
|
107 |
state.sendValue = ''; |
|
108 |
} |
|
109 |
|
|
110 |
function toggle() { |
|
111 |
if (getIsOpen.value) { |
|
112 |
close(); |
|
113 |
} else { |
|
114 |
open(); |
|
115 |
} |
|
116 |
} |
|
117 |
return { |
|
118 |
status, |
|
119 |
formatToDateTime, |
|
120 |
...toRefs(state), |
|
121 |
handlerSend, |
|
122 |
getList, |
|
123 |
toggle, |
|
124 |
getIsOpen, |
|
125 |
getTagColor, |
|
126 |
}; |
|
127 |
}, |
|
128 |
}); |
|
129 |
</script> |