Copied nuxt notes

This commit is contained in:
2022-09-23 14:17:18 -04:00
parent 9afa78fb68
commit bcf3bb1153
9 changed files with 287 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ export default {
sidebar: { sidebar: {
'/python/': require('../python/sidebar.json'), '/python/': require('../python/sidebar.json'),
'/rust/': require('../rust/sidebar.json'), '/rust/': require('../rust/sidebar.json'),
'/nuxt/': require('../nuxt/sidebar.json'),
'/': [ '/': [
{ {
text: 'Home', text: 'Home',

View File

@@ -0,0 +1,3 @@
# Frameworks
[Nuxtjs](/nuxt/)

103
docs/nuxt/datafetching.md Normal file
View File

@@ -0,0 +1,103 @@
# Data Fetching
## useFetch
This is the main form of fetching data from the backend. This can only be used in pages. Can be awaited.
```vue
<script setup>
const { data: count } = await useFetch('/api/count')
</script>
<template>
Page visits: {{ count }}
</template>
```
## useLazyFetch
This is the same as useFetch but does not block navigation, so you need to handle the case where data is null while still fetching. It does also provide a pending flag to know when the data is loading.
```js
const { pending, data: posts } = useLazyFetch('/api/posts')
```
## useAsyncData
Can be used in a component, composable, or page. The first argument is a key for the data. The main different between this and useFetch is that this provides some more control for the developer.
```js
const { data } = await useAsyncData('count', () => $fetch('/api/count'))
```
## useAsyncLazyData
Again, same as useAsyncData but you need to handle the case where the data is null.
```js
const { pending, data: count } = useLazyAsyncData('count', () => $fetch('/api/count'))
```
## Refreshing data
All of these functions also return a `refresh` property that can be called to refetch the data.
```js
const { data: users, pending, refresh, error } = await useFetch(() => `users?page=${page.value}&take=6`, { baseURL: config.API_BASE_URL }
function previous(){
page.value--;
refresh();
}
function next() {
page.value++;
refresh();
}
```
You can also refresh all data for a given key with `refreshNuxtData`. If no key is specified, it will refresh all queries.
```jsx
const { pending, data: count } = useLazyAsyncData('count', () => $fetch('/api/count'))
const refresh = () => refreshNuxtData('count')
```
## Trimming data
You can use the `pick` option to limit what pieces of data get returned on the request so you only get the fields you need.
```js
const { data: mountain } = await useFetch('/api/mountains/everest', { pick: ['title', 'description'] })
```
## More useFetch documentation
```ts
function useFetch(
url: string | Request,
options?: UseFetchOptions
): Promise<DataT>
type UseFetchOptions = {
key?: string,
method?: string,
params?: SearchParams,
body?: RequestInit['body'] | Record<string, any>
headers?: {key: string, value: string}[],
baseURL?: string,
server?: boolean
lazy?: boolean
default?: () => DataT
transform?: (input: DataT) => DataT
pick?: string[]
}
type DataT = {
data: Ref<DataT>
pending: Ref<boolean>
refresh: () => Promise<void>
error: Ref<Error | boolean>
}
```

35
docs/nuxt/dir.md Normal file
View File

@@ -0,0 +1,35 @@
# Directory Structure
## Pages
Contains all of our vue files that make up our main page layout. The directory structure also determines the routes (see [routing](/nuxt/routing)).
## Components
Contains all of the vue components that you want to use in multiple places in your application. These components get auto imported into all of your other files and are treeshaken to remove unused ones. The component name is dependent on the file location, so `components/base/foo/Button.vue` will be `BaseFooButton`. Then can also be chosen dynamically like below.
```vue
<template>
<component :is="clickable ? MyButton : 'div'" />
</template>
<script setup>
const MyButton = resolveComponent('MyButton')
</script>
```
## Composables
Contains javascript files that are auto imported, although only files at the `composable` root level and index files in subdirectories and only exported named functions are available. This is also where you would define your [state](/nuxt/state).
## Server
See [Server Routes](/nuxt/server/)
## Assets
Contains styles, images, and fonts.
## Static
This is directory mapped to the server root and contains files that have to keep their names (like images, etc) or likely won't change (favicon).

11
docs/nuxt/index.md Normal file
View File

@@ -0,0 +1,11 @@
# Nuxt.js
Nuxt is a server side rendering framework for Node and Vue.
## Creating a Project
```bash
npx nuxi init <project-name>
cd <project-name>
npm run dev
```

41
docs/nuxt/routing.md Normal file
View File

@@ -0,0 +1,41 @@
# Routing
Routing in Nuxt is file based. The file structure within the `pages` directory determines the routes for the front end application.
Files with `index.vue` within a directory will route to that directories name, while files with other names will append that file name onto the route.
Dynamic routes are denoted by square brackets surrounding the file name. These can be accessed with `this.$route.params.{parameterName}`. You can also have a catchall route with`[...slug].vue`. This will hit if the url matches no other routes. If multiple unknown routes are provided, they will come in as an array `/hello/world -> ['hello', 'world']`. You can also denote optional parameters by wrapping it in two sets of brackets.
- `pages/index.vue` -> /
- `pages/about/index.vue` -> /about
- `pages/about/me.vue` -> /about/me
- `pages/profile/[id].vue` -> /profile/foo
- `pages/users-[group]/[id].vue` -> /users-foo/bar
- `pages/[...slug].vue` -> /foobar (catchall)
## Accessing Route in Vue files
```vue
<script setup>
const route = useRoute()
if (route.params.group === 'admins' && !route.params.id) {
console.log('Warning! Make sure user is authenticated!')
}
</script>
<template>
<p>{{ $route.params.slug }}</p>
</template>
```
## Navigation
```vue
<template>
<NuxtLink to="/">Home page</NuxtLink>
<NuxtLink to="/about">About page</NuxtLink>
<NuxtLink to=`/user/${id}`>User page</NuxtLink>
<a href="https://nuxtjs.org">External Link to another page</a>
</template>
```

61
docs/nuxt/server.md Normal file
View File

@@ -0,0 +1,61 @@
# Server Routes
Server routes are defined in the `server` directory, and can be divided into `server/api`, `server/routes`, and `server/middleware`. Each file needs to export a default function `defineEventHandler` which takes an event object and can return either JSON, a promise, or use `event.res.send()` to return data.
```tsx
// ~/server/api/hello.ts
export default defineEventHandler((event) => {
return {
api: 'works'
}
})
```
Routes in the api subdirectory will be at a route `/api`, routes defined in the routes subdirectory will be accessible without `/api`.
You can also name files with a suffix to specify which request type hits which route. If not all methods are defined, methods without a matching handler will 404.
```tsx
// ~/server/api/test.get.ts
export default defineEventHandler(() => 'Test get handler')
// ~/server/api/test.post.ts
export default defineEventHandler(() => 'Test post handler')
```
## Dynamic server routes
These can be defined the same way we define dynamic navigation with brackets surrounding the variable in the file name. Catch all routes can be defined with a `[...].ts`.
```tsx
// ~/server/api/[name].ts
export default defineEventHandler(event => `Hello, ${event.context.params.name}!`)
```
## Getting Data from Request
```tsx
// Request body
export default defineEventHandler(async (event) => {
const body = await useBody(event)
return { body }
})
// Query params
export default defineEventHandler((event) => {
const query = useQuery(event)
return { a: query.param1, b: query.param2 }
})
// Access runtime config
export default defineEventHandler((event) => {
const config = useRuntimeConfig()
return { key: config.KEY }
})
// Accessing cookies
export default defineEventHandler((event) => {
const cookies = useCookies(event)
return { cookies }
})
```

13
docs/nuxt/sidebar.json Normal file
View File

@@ -0,0 +1,13 @@
[
{
"text": "Nuxt Basics",
"items": [
{"text": "Introduction", "link": "/nuxt/"},
{"text": "Directory Structure", "link": "/nuxt/dir"},
{"text": "Routing", "link": "/nuxt/routing"},
{"text": "Data Fetching", "link": "/nuxt/datafetching"},
{"text": "State", "link": "/nuxt/state"},
{"text": "Server Routes", "link": "/nuxt/server"}
]
}
]

19
docs/nuxt/state.md Normal file
View File

@@ -0,0 +1,19 @@
# State Management
State is created using the `useState` function. Any component that calls `useState` with the same key will share the state for that variable.
```jsx
const counter = useState('counter', () => Math.round(Math.random() * 1000))
function increment() {
counter++;
}
```
You can also create shared state by creating a composable that returns state functions. If using `useState` outside of a setup function, they must be created this way otherwise they will be shared by every user of the application, not just the current one.
```tsx
// composables/states.ts
export const useCounter = () => useState<number>('counter', () => 0)
export const useColor = () => useState<string>('color', () => 'pink')
```