- useAsyncData
- useFetch
- useError
- useHead
- useSeoMeta
- useNuxtApp
- useState
- useAppConfig
- useRuntimeConfig
useCookie#
Cookie 的工作原理。

- 浏览器向服务器发送请求
- 服务器进行响应,并且在响应头里面通过 Set-Cookie 来指示浏览器保存或者更新 Cookie
- 浏览器保存最新的 Cookie
- 后续请求带上这个 Cookie
以前前端开发中要操作 Cookie 通过 document.cookie 接口进行操作。
读取Cookie
document.cookie 返回的是一个字符串,包含当前页面所有的 Cookie,每个 Cookie 之间用分号和空格分隔。你需要对这个字符串自行分割和解析。
'name=value; expires=DATE; path=PATH; domain=DOMAIN; sameSite=VALUE'更新 Cookie
通过重新赋值新的字符串给 document.cookie 可以设置新的 Cookie 值。
删除 Cookie
删除 Cookie 通常是将 Cookie 的过期时间设置为一个过去的时间。
思考一下🤔 SSR 场景下操作 Cookie 会遇到什么问题?
在 SSR 环境下,并没有浏览器的 DOM 对象,因此也就不存在 document.cookie。Nuxt 为我们提供了 useCookie 的组合式函数来做 Cookie 的处理。
useCookie 的基本用法:
读取 Cookie
const token = useCookie('token')token.value更新 Cookie
const token = useCookie('token')token.value = 'new_token'删除 Cookie
const token = useCookie('token')token.value = nulluseCookie 函数接受第二个参数 options,用于配置 Cookie 的行为。常见的配置选项包括:
- maxAge:设置 Cookie 的有效期(单位:秒)。例如,设置 7 天有效期
- expires:直接指定一个 Date 对象,作为 Cookie 的过期时间。
- httpOnly:若设为 true,则 Cookie 只能在服务端访问,不可通过客户端 JavaScript 操作。
- secure:若设为 true,则 Cookie 只能通过 HTTPS 传输。
- domain 和 path:分别指定 Cookie 的适用域名和路径。
- sameSite:控制 Cookie 的同站策略。
例如,我们可以这样设置一个 Cookie 用于存储用户信息:
<script setup lang="ts">const userInfo = useCookie('userInfo', { maxAge: 60 * 60 * 24 * 30, // 30 天有效期 path: '/', secure: true, httpOnly: true, sameSite: 'lax',})// 设置默认值或更新CookieuserInfo.value = { username: 'Alice', score: 100 }</script>相较于原生的 document.cookie,有如下的优点:
- 该组合式函数更加的简洁,不需要去拆分和组合字符串。
- 返回的是响应式数据,值的变化会自动触发视图更新。
- 对 SSR 友好,这意味着在服务端渲染期间也能正确读取和写入 Cookie。无论是在服务器首次渲染页面,还是在客户端水合后继续操作 Cookie,useCookie 都能保持一致的状态。
惰性请求#
关于请求这一块儿,我们之前有接触过:
- $fetch
- useAsyncData
- useFetch
除此之外,Nuxt 还提供了惰性请求相关的组合式函数:
- useLazyAsyncData
- useLazyFetch
回忆 useAsyncData 的用法:
<script setup lang="ts">const { data, status, error, refresh, clear } = await useAsyncData( 'mountains', () => $fetch('https://api.nuxtjs.dev/mountains'))</script>参数:
- key:为 useAsyncData 提供一个唯一标识符。Nuxt 根据提供的 key 检查是否已有缓存。如果缓存存在且有效,直接返回缓存数据。如果没有缓存或缓存失效,则调用 fetcher 函数获取数据。
- fetcher 函数:定义如何获取数据。
useAsyncData 还接收第三个参数。这个参数是一个配置对象,你可以在 官方文档 中看到该配置对象支持的所有配置项。其中有一个就是 lazy。如果 lazy 项设置为 true,这意味着导航不会等待数据获取完成,页面会立即渲染,数据获取在后台进行。
<template> <div v-if="pending">加载中...</div> <div v-else-if="error">加载失败:{{ error.message }}</div> <div v-else>数据:{{ data }}</div></template>
<script setup>const { data, pending, error } = await useAsyncData( 'unique-key', () => new Promise((resolve) => setTimeout(() => resolve('模拟数据'), 5000)), { lazy: false, // 默认其实就是 false })</script>在初始 SSR 的时候,useAsyncData 会在服务器等待数据获取完成后再渲染页面。这样服务器生成的 html 是包含数据的,但是这也意味着服务器端在渲染首屏 html 的时候需要等待请求的时间。
useLoadingIndicator#
useLoadingIndicator 返回一个加载器实例对象,该对象提供 start() 和 finish() 等方法,用于在某个异步操作开始前启动加载效果,操作结束后结束加载效果。
<template> <NuxtLoadingIndicator /> <div> <button @click="fetchData">获取数据</button> </div></template>
<script setup lang="ts">const loading = useLoadingIndicator()
// 模拟一个异步数据请求async function fetchData() { // 开始加载 loading.start() try { // 模拟延时 3 秒后返回数据 const data = await new Promise((resolve) => setTimeout(() => resolve('模拟数据'), 3000) ) console.log('获取到数据:', data) } catch (error) { console.error('数据获取失败:', error) } finally { // 数据请求完成后结束加载 loading.finish() }}</script>在这个例子中:
- 调用
useLoadingIndicator()获取加载指示器实例。 - 在
fetchData函数中,调用loading.start()开始显示加载指示器。 - 模拟一个 3 秒延时的异步操作,完成后调用
loading.finish()结束加载效果
来看一个具体的例子。当用户点击“登录”按钮后,加载指示器开始工作,等待异步模拟的登录请求完成后再结束加载,从而让用户明确知道正在进行登录操作。
<template> <NuxtLoadingIndicator /> <form @submit.prevent="handleSubmit"> <div> <label for="username">用户名:</label> <input id="username" v-model="username" type="text" placeholder="请输入用户名" /> </div> <div> <label for="password">密码:</label> <input id="password" v-model="password" type="password" placeholder="请输入密码" /> </div> <button type="submit">登录</button> </form></template>
<script setup lang="ts">const username = ref('')const password = ref('')
// 获取加载指示器实例const loading = useLoadingIndicator()
async function handleSubmit() { // 启动加载效果 loading.start() try { // 模拟一个异步登录请求,延时 2 秒返回结果 const response = await new Promise((resolve) => setTimeout(() => resolve({ success: true }), 2000) ) if (response.success) { console.log('登录成功') // 这里可以继续处理登录成功后的逻辑 } else { console.error('登录失败') } } catch (error) { console.error('请求出错:', error) } finally { // 无论成功或失败,都结束加载效果 loading.finish() }}</script>-EOF-