initial-commit
This commit is contained in:
9
pages/+Head.vue
Normal file
9
pages/+Head.vue
Normal 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
55
pages/+Layout.vue
Normal 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
13
pages/+config.ts
Normal 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
|
||||
4
pages/+onPageTransitionEnd.ts
Normal file
4
pages/+onPageTransitionEnd.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export async function onPageTransitionEnd() {
|
||||
console.log('Page transition end')
|
||||
document.body.classList.remove('page-transition')
|
||||
}
|
||||
14
pages/+onPageTransitionStart.ts
Normal file
14
pages/+onPageTransitionStart.ts
Normal 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
17
pages/_error/+Page.vue
Normal 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
12
pages/index/+Page.vue
Normal 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>
|
||||
15
pages/star-wars/@id/+Page.vue
Normal file
15
pages/star-wars/@id/+Page.vue
Normal 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>
|
||||
33
pages/star-wars/@id/+data.ts
Normal file
33
pages/star-wars/@id/+data.ts
Normal 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 }
|
||||
}
|
||||
23
pages/star-wars/index/+Page.vue
Normal file
23
pages/star-wars/index/+Page.vue
Normal 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>
|
||||
34
pages/star-wars/index/+data.ts
Normal file
34
pages/star-wars/index/+data.ts
Normal 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
10
pages/star-wars/types.ts
Normal 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
10
pages/todo/+Page.vue
Normal 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
15
pages/todo/+data.ts
Normal 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
30
pages/todo/TodoList.vue
Normal 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>
|
||||
Reference in New Issue
Block a user