Vue 團隊正式發佈!未來 Vue 也能寫後端啦!
前言
大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心~
背景需求
最近,我遇到了一個需求:有兩個頁面,每個頁面各自連接到一個獨立的WebSocket
。這兩個頁面能夠通過WebSocket
相互影響。
爲了更好地理解需求,以下是兩個頁面的簡化版本:
頁面 1 和頁面 2 的需求:
-
頁面 1:當點擊更新按鈕時,頁面 1 的數值加 1,同時頁面 2 的數值變爲頁面 1 數值的 10 倍。
-
頁面 2:當點擊清空按鈕時,頁面 1 和頁面 2 的數值都會清零。
-
頁面 2:定時獲取頁面 1 的數值,並展示出來。
效果演示:
簡單實現方案
實現這個需求並不複雜,核心思路是通過Node.js
創建兩個WebSocket
連接,並通過一個count
變量來同步頁面的數據。
首先,安裝ws
庫:
npm install ws
如何實現兩個WebSocket
之間的通信呢?其實就是維護兩個全局變量來存儲這兩個WebSocket
實例。
然後,在前端頁面通過 WebSocket 通信來實現數據同步。
頁面 1
頁面 2
通過這種方式,基本實現了需求,效果如下:
優化思路
上述方法雖能實現需求,但維護起來可能會很麻煩,尤其是當多個WebSocket
連接實例增加時,代碼可能變得難以管理。
我有一個想法:能否讓每個WebSocket
連接管理自己的狀態?
問題在於,儘管每個連接管理自己的狀態,它們仍然需要依賴一個共同的變量(即count)。當某個實例更新了``count
,另一個實例如何被通知並作出反應呢?
想到這裏,我就聯想到了 Vue3 的響應式機制。Vue3 提供了一套非常優秀的響應式 API,當數據變化時,它能夠自動通知相關的組件進行更新。
能否將 Vue3 的響應式 API 移植到Node.js
環境中呢?
答案是:可以!Vue3 將響應式 API 拆分成了一個獨立的庫@vue/reactivity
,即使在 Node.js 環境下,也可以使用這個庫來實現響應式功能。
通過安裝這個包:
npm install @vue/reactivity
我們可以使用ref、computed 和 watch
來讓每個WebSocket 實例獨立管理自己的狀態。
最終的效果展示:
代碼實現(完整方案)
可以將@vue/reactivity
作爲一個響應式工具庫使用,它不僅可以在Node.js
環境下使用,甚至可以在 React 項目中使用。
Node.js 端:index.js
// 引入 WebSocket 庫
const WebSocket = require('ws');
// 引入 Vue3 響應式 API
const reactivity = require('@vue/reactivity');
const { ref, computed, watch } = reactivity;
// 創建 WebSocket 服務器
const wss1 = new WebSocket.Server({ port: 8001 });
const wss2 = new WebSocket.Server({ port: 8002 });
// 記錄數字
const count = ref(0);
// 計算數值的 10 倍
const sum = computed(() =>10 * count.value);
// 處理連接1
wss1.on('connection', (ws) => {
ws.on('message', (message) => {
// 更新 count 的值
count.value = Number(message);
});
// 監聽 count 變化,併發送到頁面1
watch(count, (newValue) => {
ws.send(newValue);
});
});
// 處理連接2
wss2.on('connection', (ws) => {
ws.on('message', () => {
// 清空 count 和 sum
count.value = 0;
});
// 監聽 sum 變化,併發送到頁面2
watch(sum, (newValue) => {
ws.send(newValue);
});
// 模擬定時任務,定期發送 sum
setTimeout(() => {
ws.send(sum.value);
}, 3600 * 12); // 12小時後發送
});
頁面 1:Page1.vue
<template>
<div class="flex justify-center mb-3 text-4xl font-bold">頁面1</div>
<Button type="primary" @click="click">點擊更新數據</Button>
<div class="text-lg">當前數值:{{ count }}</div>
</template>
<script setup lang="ts">
import { Button } from'ant-design-vue';
import { ref } from'vue';
const count = ref(0);
// 創建 WebSocket 客戶端
const socket = new WebSocket('ws://localhost:8001');
const click = () => {
count.value++;
// 發送更新後的 count 到服務器
socket.send(`${count.value}`);
};
// 接收來自服務端的消息
socket.addEventListener('message', (e) => {
count.value = e.data;
});
</script>
頁面 2:Page2.vue
<template>
<div class="flex justify-center mb-3 text-4xl font-bold">頁面2</div>
<Button type="primary" @click="click">清空數據</Button>
<div class="text-lg">當前數值:{{ count }}</div>
</template>
<script setup lang="ts">
import { Button } from'ant-design-vue';
import { ref } from'vue';
const count = ref(0);
// 創建 WebSocket 客戶端
const socket = new WebSocket('ws://localhost:8002');
const click = () => {
// 向服務器發送清空命令
socket.send('Hello, server!');
};
// 接收來自服務端的消息
socket.addEventListener('message', (e) => {
count.value = e.data;
});
</script>
最終效果
這樣,通過 Vue3 的響應式 API 和WebSocket
的結合,我們可以輕鬆地實現兩個頁面間的實時數據同步,並使代碼更加易於維護和擴展。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Ba62Zn5JxHShdIAAFWhJKA