Vben
2021-04-10 967b28c4c06cf92e9ab90cff51f59a0d6ced5d7b
提交 | 用户 | 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>