前言
上一篇写了数据获取的各种姿势,最终大意了没有闪,以至于pick
部分举例欠妥:
const { data: todos } = await useFetch("/api/todo", {
pick: ["id", "title", "completed"],
});
导致了500
错误,这里需要说明的是,pick期望的数据结构应该是对象,而我提供的是数组:
const todos = [
{ id: 1, title: 'nuxt3', completed: false },
{ id: 2, title: 'vue3', completed: true },
]
export default () => {
return todos
}
所以如果修改为对象:
export default () => {
return {
code: 1,
data: todos
}
}
则可以正常pick
:
const { data: todos } = await useFetch("/api/todo", {
pick: ['data']
});
pick
的行为是,摘出来这些部分做个新对象:
// 型如 { data: todos }
// 所以我之前代码:const { data: todos } = ...
// todos并非是数组而是{ data: todos }
所以页面中使用也要对应:
<div v-for="todo in todos.data" :key="todo.id">
有人问如果有层级pick需求该当如何?我估计pick选项没这个能力。如果想要对数据做强力控制,还得是transform
:
const { data: todos } = await useFetch("/api/todo", {
transform(input) {
return input.data;
},
});
此时页面也可以直接使用todos
了!
状态共享
Nuxt3提供了 useState
创建响应式且服务端友好的跨组件状态共享能力。
useState
是服务端友好的ref
替换。它的值在服务端渲染(客户端注水的过程中)将被保留并通过唯一key在组件间共享。
方法签名
useState<T>(key: string, init?: () => T): Ref<T>
- key:唯一键用于去重
- init:提供初始值的函数
useState实践
声明一个状态,index.vue
const counter = useState("counter", () => Math.round(Math.random() * 1000))
<button @click="counter++">+</button>
{{ counter }}
<button @click="counter--">-</button>
共享状态
我们的全局状态当然想要在组件之间共享,此时可以利用nuxt的composables自动导入特性,把它们定义在composables目录中,这样他们将成为全局类型安全的状态。
composables/useCounter.ts
export const useCounter = () =>
useState("counter", () => Math.round(Math.random() * 1000));
网友评论