initial-commit

This commit is contained in:
nicwands
2026-03-17 23:07:22 -04:00
commit 6fa36b26ca
30 changed files with 3233 additions and 0 deletions

9
pages/+Head.vue Normal file
View File

@@ -0,0 +1,9 @@
<!-- https://vike.dev/Head -->
<template>
<link rel="icon" :href="logoUrl" />
</template>
<script setup lang="ts">
import logoUrl from '../assets/logo.svg'
</script>

55
pages/+Layout.vue Normal file
View File

@@ -0,0 +1,55 @@
<!-- https://vike.dev/Layout -->
<template>
<div class="layout">
<Sidebar>
<Logo />
<Link href="/"> Welcome </Link>
<Link href="/todo"> Todo </Link>
<Link href="/star-wars"> Data Fetching </Link>
</Sidebar>
<Content><slot /></Content>
</div>
</template>
<script lang="ts" setup>
import Content from '../components/Content.vue'
import Link from '../components/Link.vue'
import Logo from '../components/Logo.vue'
import Sidebar from '../components/Sidebar.vue'
</script>
<style>
body {
margin: 0;
font-family: sans-serif;
}
* {
box-sizing: border-box;
}
a {
text-decoration: none;
}
</style>
<style scoped>
.layout {
display: flex;
max-width: 900px;
margin: auto;
}
.content {
padding: 20px;
padding-bottom: 50px;
min-height: 100vh;
flex-grow: 1;
}
/* Page Transition Animation */
#page-content {
opacity: 1;
transition: opacity 0.3s ease-in-out;
}
body.page-transition #page-content {
opacity: 0;
}
</style>

13
pages/+config.ts Normal file
View File

@@ -0,0 +1,13 @@
import type { Config } from 'vike/types'
import vikeVue from 'vike-vue/config'
// Default config (can be overridden by pages)
// https://vike.dev/config
export default {
// https://vike.dev/head-tags
title: 'My Vike App',
description: 'Demo showcasing Vike',
extends: [vikeVue],
} as Config

View File

@@ -0,0 +1,4 @@
export async function onPageTransitionEnd() {
console.log('Page transition end')
document.body.classList.remove('page-transition')
}

View File

@@ -0,0 +1,14 @@
// https://vike.dev/onPageTransitionStart
import type { PageContextClient } from 'vike/types'
export async function onPageTransitionStart(
pageContext: Partial<PageContextClient>,
) {
console.log('Page transition start')
console.log(
'pageContext.isBackwardNavigation',
pageContext.isBackwardNavigation,
)
document.body.classList.add('page-transition')
}

17
pages/_error/+Page.vue Normal file
View File

@@ -0,0 +1,17 @@
<template>
<h1>{{ heading }}</h1>
<p>{{ abortReason }}</p>
</template>
<script lang="ts" setup>
import { usePageContext } from 'vike-vue/usePageContext'
const pageContext = usePageContext()
let { is404, abortReason } = pageContext
if (!abortReason) {
abortReason = is404
? 'This page could not be found.'
: 'Something went wrong.'
}
const heading = is404 ? 'Page Not Found' : 'Internal Error'
</script>

12
pages/index/+Page.vue Normal file
View File

@@ -0,0 +1,12 @@
<template>
<h1>My Vike app</h1>
<p>This page is:</p>
<ul>
<li>Rendered to HTML.</li>
<li>Interactive. <Counter /></li>
</ul>
</template>
<script setup lang="ts">
import Counter from '../../components/Counter.vue'
</script>

View File

@@ -0,0 +1,15 @@
<template>
<h1>{{ movie.title }}</h1>
Release Date: {{ movie.release_date }}
<br />
Director: {{ movie.director }}
<br />
Producer: {{ movie.producer }}
</template>
<script lang="ts" setup>
import { useData } from 'vike-vue/useData'
import type { Data } from './+data.js'
const { movie } = useData<Data>()
</script>

View File

@@ -0,0 +1,33 @@
// https://vike.dev/data
import type { PageContextServer } from 'vike/types'
import { useConfig } from 'vike-vue/useConfig'
import type { MovieDetails } from '../types.js'
export type Data = Awaited<ReturnType<typeof data>>
export async function data(pageContext: PageContextServer) {
// https://vike.dev/useConfig
const config = useConfig()
const response = await fetch(
`https://brillout.github.io/star-wars/api/films/${pageContext.routeParams.id}.json`,
)
let movie = (await response.json()) as MovieDetails
config({
// Set <title>
title: movie.title,
})
// We remove data we don't need because the data is passed to
// the client; we should minimize what is sent over the network.
movie = minimize(movie)
return { movie }
}
function minimize(movie: MovieDetails): MovieDetails {
const { id, title, release_date, director, producer } = movie
return { id, title, release_date, director, producer }
}

View File

@@ -0,0 +1,23 @@
<template>
<h1>Star Wars Movies</h1>
<ol>
<li v-for="item in movies" :key="item.id">
<a :href="'/star-wars/' + item.id">{{ item.title }}</a> ({{
item.release_date
}})
</li>
</ol>
<p>
Source:
<a href="https://brillout.github.io/star-wars"
>brillout.github.io/star-wars</a
>.
</p>
</template>
<script lang="ts" setup>
import { useData } from 'vike-vue/useData'
import type { Data } from './+data.js'
const { movies } = useData<Data>()
</script>

View File

@@ -0,0 +1,34 @@
// https://vike.dev/data
import { useConfig } from 'vike-vue/useConfig'
import type { Movie, MovieDetails } from '../types.js'
export type Data = Awaited<ReturnType<typeof data>>
export async function data() {
// https://vike.dev/useConfig
const config = useConfig()
const response = await fetch(
'https://brillout.github.io/star-wars/api/films.json',
)
const moviesData = (await response.json()) as MovieDetails[]
config({
// Set <title>
title: `${moviesData.length} Star Wars Movies`,
})
// We remove data we don't need because the data is passed to the client; we should
// minimize what is sent over the network.
const movies = minimize(moviesData)
return { movies }
}
function minimize(movies: MovieDetails[]): Movie[] {
return movies.map((movie) => {
const { title, release_date, id } = movie
return { title, release_date, id }
})
}

10
pages/star-wars/types.ts Normal file
View File

@@ -0,0 +1,10 @@
export type Movie = {
id: string
title: string
release_date: string
}
export type MovieDetails = Movie & {
director: string
producer: string
}

10
pages/todo/+Page.vue Normal file
View File

@@ -0,0 +1,10 @@
<template>
<div>
<h1>To-do List</h1>
<TodoList />
</div>
</template>
<script lang="ts" setup>
import TodoList from './TodoList.vue'
</script>

15
pages/todo/+data.ts Normal file
View File

@@ -0,0 +1,15 @@
// https://vike.dev/data
import type { PageContextServer } from 'vike/types'
export type Data = Awaited<ReturnType<typeof data>>
export async function data(_pageContext: PageContextServer) {
// NOTE: This +data hook is only for demonstration — it doesn't actually retrieve data from a database.
// Go to https://vike.dev/new and select a database to scaffold an app with a persisted to-do list.
const todoItemsInitial = [
{ text: 'Buy milk' },
{ text: 'Buy strawberries' },
]
return { todoItemsInitial }
}

30
pages/todo/TodoList.vue Normal file
View File

@@ -0,0 +1,30 @@
<template>
<ul>
<li v-for="(item, index) in todoItems" :key="index">
{{ item.text }}
</li>
<li>
<form @submit.prevent="submitNewTodo()">
<input v-model="newTodo" type="text" />
<button type="submit">Add to-do</button>
</form>
</li>
</ul>
</template>
<script lang="ts" setup>
import type { Data } from './+data'
import { useData } from 'vike-vue/useData'
import { ref } from 'vue'
const { todoItemsInitial } = useData<Data>()
const todoItems = ref<{ text: string }[]>(todoItemsInitial)
const newTodo = ref('')
const submitNewTodo = async () => {
const text = newTodo.value
todoItems.value.push({ text })
newTodo.value = ''
}
</script>