diff --git a/src/examples/src/long-polling/App/composition.js b/src/examples/src/long-polling/App/composition.js new file mode 100644 index 0000000000..b937a4f2c6 --- /dev/null +++ b/src/examples/src/long-polling/App/composition.js @@ -0,0 +1,65 @@ +import { ref, onUnmounted } from 'vue' + +const API_URL = `https://api.github.com/repos/vuejs/core/commits?per_page=3&sha=main` + +export default { + setup() { + const commits = ref([]) + const isPolling = ref(false) + const lastUpdated = ref('') + let intervalId = null + + async function fetchData() { + try { + commits.value = await (await fetch(API_URL)).json() + lastUpdated.value = new Date().toLocaleTimeString() + } catch (error) { + console.error('Failed to fetch:', error) + } + } + + function startPolling() { + fetchData() // fetch immediately + intervalId = setInterval(fetchData, 3000) + } + + function stopPolling() { + if (intervalId) { + clearInterval(intervalId) + intervalId = null + } + } + + function togglePolling() { + isPolling.value = !isPolling.value + if (isPolling.value) { + startPolling() + } else { + stopPolling() + } + } + + // Clean up interval when component is unmounted + onUnmounted(() => { + stopPolling() + }) + + function truncate(v) { + const newline = v.indexOf('\n') + return newline > 0 ? v.slice(0, newline) : v + } + + function formatDate(v) { + return v.replace(/T|Z/g, ' ') + } + + return { + commits, + isPolling, + lastUpdated, + togglePolling, + truncate, + formatDate + } + } +} diff --git a/src/examples/src/long-polling/App/options.js b/src/examples/src/long-polling/App/options.js new file mode 100644 index 0000000000..d26ea63c04 --- /dev/null +++ b/src/examples/src/long-polling/App/options.js @@ -0,0 +1,51 @@ +const API_URL = `https://api.github.com/repos/vuejs/core/commits?per_page=3&sha=main` + +export default { + data: () => ({ + commits: [], + isPolling: false, + lastUpdated: '', + intervalId: null + }), + + beforeUnmount() { + // Clean up interval when component is unmounted + this.stopPolling() + }, + + methods: { + async fetchData() { + try { + this.commits = await (await fetch(API_URL)).json() + this.lastUpdated = new Date().toLocaleTimeString() + } catch (error) { + console.error('Failed to fetch:', error) + } + }, + startPolling() { + this.fetchData() // fetch immediately + this.intervalId = setInterval(() => this.fetchData(), 3000) + }, + stopPolling() { + if (this.intervalId) { + clearInterval(this.intervalId) + this.intervalId = null + } + }, + togglePolling() { + this.isPolling = !this.isPolling + if (this.isPolling) { + this.startPolling() + } else { + this.stopPolling() + } + }, + truncate(v) { + const newline = v.indexOf('\n') + return newline > 0 ? v.slice(0, newline) : v + }, + formatDate(v) { + return v.replace(/T|Z/g, ' ') + } + } +} diff --git a/src/examples/src/long-polling/App/style.css b/src/examples/src/long-polling/App/style.css new file mode 100644 index 0000000000..576ad5a471 --- /dev/null +++ b/src/examples/src/long-polling/App/style.css @@ -0,0 +1,28 @@ +a { + text-decoration: none; + color: #42b883; +} +li { + line-height: 1.5em; + margin-bottom: 20px; +} +.author, +.date { + font-weight: bold; +} +.status { + color: #42b883; + font-style: italic; +} +button { + margin-right: 10px; + padding: 8px 16px; + background-color: #42b883; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; +} +button:hover { + background-color: #3aa876; +} diff --git a/src/examples/src/long-polling/App/template.html b/src/examples/src/long-polling/App/template.html new file mode 100644 index 0000000000..dcf9616bbb --- /dev/null +++ b/src/examples/src/long-polling/App/template.html @@ -0,0 +1,19 @@ +

Long Polling Example

+

+ + Last updated: {{ lastUpdated }} +

+

Polling every 3 seconds...

+ +

{{ isPolling ? 'Loading...' : 'Click "Start Polling" to fetch data' }}

diff --git a/src/examples/src/long-polling/description.txt b/src/examples/src/long-polling/description.txt new file mode 100644 index 0000000000..3f4cf9411c --- /dev/null +++ b/src/examples/src/long-polling/description.txt @@ -0,0 +1 @@ +This example polls the GitHub API for the latest Vue Core commits every 3 seconds and displays them as a list. You can start and stop the polling.