如何在 Nuxt 中的 2 个数据集之间建立交集?
How to make an intersection between 2 datasets in Nuxt?
我试图从 api 获取数据,其中的参数来自 v-for 中的参数。
在 findUser
方法中,我可以 console.log
我正在寻找的数据。但是我在findUser
的末尾获取不到,为什么?
我知道有一个 async
方法可以获取它,但我不知道如何管理它以使其与我想做的事情一起工作;
我也想过同时调用这两个API,但是结果一样,不知道怎么管
<template>
<div>
<h4>Listes Reçues</h4>
<p v-for="element in results" id="flex-list" :key="element.list_id">
{{ element.list_name }} de {{ findUser(element.user_id) }}
</p>
</div>
</template>
<script>
export default {
data() {
return {
results: '',
nickname: '',
}
},
created() {
this.$axios
.get(`/api/listReceived/${this.$auth.user[0].user_id}`)
.then((res) => {
this.results = res.data
console.log(JSON.stringify(this.results))
})
.catch((err) => {
console.error(err)
})
},
methods: {
findUser(id) {
console.log(id)
let data = ''
this.$axios
.get(`http://localhost:3000/api/userdata/${id}`)
.then((res) => {
data = res.data[0].nickname
console.log(data)
})
.catch((err) => {
console.error(err)
})
return data
},
},
}
</script>
created()
在 Vue 中完全没问题,但通常你会在 Nuxt 中使用 fetch()
和 asyncData()
钩子。
这是使用 JSONplaceholder's API.
的基本思想
这是一个可能的/pages/index.vue
<template>
<div class="flex flex-col items-center">
<h1 class="p-4 bg-green-700 rounded-md">
List of users from JSONplaceholder
</h1>
<section class="mt-4">
<p v-for="user in users" :key="user.id">
{{ user.name }} {{ user.email }} ~
<nuxt-link
:to="{ name: 'users-id', params: { id: user.id } }"
class="border-b-4 border-green-500"
>
Check details
</nuxt-link>
</p>
</section>
</div>
</template>
<script>
export default {
name: 'Index',
data() {
return {
users: [],
}
},
async fetch() {
this.users = await this.$axios.$get('/users')
},
}
</script>
<style>
* {
@apply bg-gray-800 text-gray-100;
}
</style>
详细页面又名 /pages/users/_id.vue
使用 fetch()
hook。
<template>
<div class="flex flex-col items-center">
<nuxt-link class="p-4 bg-purple-700 rounded-md" :to="{ name: 'index' }">
Go back
</nuxt-link>
<h2>User details ID: # {{ $route.params.id }}</h2>
<p v-if="$fetchState.pending">Loading user's info...</p>
<p v-else-if="$fetchState.error">Error while fetching user</p>
<div v-else>
<p>{{ user.name }}</p>
<p>{{ user.phone }}</p>
<p>{{ user.website }}</p>
<p>{{ user.company.name }}</p>
</div>
</div>
</template>
<script>
export default {
name: 'UserId',
data() {
return {
user: {},
}
},
async fetch() {
this.user = await this.$axios.$get(`/users/${this.$route.params.id}`)
},
}
</script>
我确实更喜欢这种方法,因为它不会阻塞渲染,您可以添加一些 smooth skeleton 以仍然让用户知道正在发生某些事情。最重要的是,fetch()
在组件和页面上都可用,而 asyncData()
仅适用于页面。
它还提供了非常方便的 $fetchState
helper!
这是使用 asyncData() hook
的相同 /pages/users/_id.vue
页面。
<template>
<div class="flex flex-col items-center">
<nuxt-link class="p-4 bg-purple-700 rounded-md" :to="{ name: 'index' }">
Go back
</nuxt-link>
<p>{{ user.name }}</p>
<p>{{ user.phone }}</p>
<p>{{ user.website }}</p>
<p>{{ user.company.name }}</p>
</div>
</template>
<script>
export default {
name: 'UserId',
async asyncData({ route, $axios }) {
const user = await $axios.$get(`/users/${route.params.id}`)
return { user }
},
}
</script>
使用 asyncData
的主要好处是它更安全并且它会阻止渲染(可以是赞成也可以是反对,对我个人来说更多是反对)。
这里有一些 比较 fetch()
与 asyncData()
。
看看这个 handy blog article on the subject and also this dev.to clone example.
最后,如果您想采用 SSG 路径并在 client-side 上以最少的 API 调用次数优化整个过程,您还可以检查 。
除了我的最佳答案之外,这个问题与问题无关但仍然相关,这里有一个关于如何正确处理交叉路口的示例。
我没有使用端点,而是在 data()
中本地模拟了数据,因此我将 post 保留在上面。
<template>
<div class="flex flex-col items-center">
<h1 class="p-4 bg-green-700 rounded-md">
List of users ordered by their according message
</h1>
<!-- <pre>{{ messages }}</pre> -->
<section>
<div v-for="user in groupedMessages" :key="user.id" class="mt-4">
<p>
User: <b>{{ user.name }}</b>
</p>
<aside>
Messages:
<span v-if="!user.messages.length">No messages actually</span>
</aside>
<p v-for="message in user.messages" :key="message.id">
<span class="italic">- {{ message.text }}</span>
</p>
</div>
</section>
</div>
</template>
<script>
// ES version of lodash, lighter overall
import { cloneDeep } from 'lodash-es'
export default {
name: 'Index',
data() {
return {
messages: [
{
id: 1,
text: 'Hello world',
userId: 1,
},
{
id: 2,
text: 'Nice cool message',
userId: 1,
},
{
id: 3,
text: 'Still for the first user?',
userId: 1,
},
{
id: 4,
text: 'Yep, apparently...',
userId: 1,
},
{
id: 5,
text: "Eh, surprise, I'm a sneaky one...",
userId: 3,
},
{
id: 6,
text: 'Oh, a second one.',
userId: 2,
},
{
id: 7,
text: "You're damn right!!",
userId: 2,
},
],
users: [
{
name: 'Patrick',
id: 1,
messages: [],
},
{
name: 'Pablo',
id: 2,
messages: [],
},
{
name: 'Unkown author',
id: 5,
messages: [],
},
{
name: 'Escobar',
id: 3,
messages: [],
},
],
}
},
computed: {
groupedMessages() {
// we use that to avoid any kind of further mutation to the initial `users` array
const clonedUsers = cloneDeep(this.users)
// we do loop on each message and find a corresponding user for it
this.messages.forEach((message) =>
clonedUsers.forEach((user) => {
if (user.id === message.userId) {
user.messages.push(message)
}
})
)
return clonedUsers
},
},
}
</script>
github repo is available中的无关名称请不要关注
这是它的样子 on Netlify。
我试图从 api 获取数据,其中的参数来自 v-for 中的参数。
在 findUser
方法中,我可以 console.log
我正在寻找的数据。但是我在findUser
的末尾获取不到,为什么?
我知道有一个 async
方法可以获取它,但我不知道如何管理它以使其与我想做的事情一起工作;
我也想过同时调用这两个API,但是结果一样,不知道怎么管
<template>
<div>
<h4>Listes Reçues</h4>
<p v-for="element in results" id="flex-list" :key="element.list_id">
{{ element.list_name }} de {{ findUser(element.user_id) }}
</p>
</div>
</template>
<script>
export default {
data() {
return {
results: '',
nickname: '',
}
},
created() {
this.$axios
.get(`/api/listReceived/${this.$auth.user[0].user_id}`)
.then((res) => {
this.results = res.data
console.log(JSON.stringify(this.results))
})
.catch((err) => {
console.error(err)
})
},
methods: {
findUser(id) {
console.log(id)
let data = ''
this.$axios
.get(`http://localhost:3000/api/userdata/${id}`)
.then((res) => {
data = res.data[0].nickname
console.log(data)
})
.catch((err) => {
console.error(err)
})
return data
},
},
}
</script>
created()
在 Vue 中完全没问题,但通常你会在 Nuxt 中使用 fetch()
和 asyncData()
钩子。
这是使用 JSONplaceholder's API.
这是一个可能的/pages/index.vue
<template>
<div class="flex flex-col items-center">
<h1 class="p-4 bg-green-700 rounded-md">
List of users from JSONplaceholder
</h1>
<section class="mt-4">
<p v-for="user in users" :key="user.id">
{{ user.name }} {{ user.email }} ~
<nuxt-link
:to="{ name: 'users-id', params: { id: user.id } }"
class="border-b-4 border-green-500"
>
Check details
</nuxt-link>
</p>
</section>
</div>
</template>
<script>
export default {
name: 'Index',
data() {
return {
users: [],
}
},
async fetch() {
this.users = await this.$axios.$get('/users')
},
}
</script>
<style>
* {
@apply bg-gray-800 text-gray-100;
}
</style>
详细页面又名 /pages/users/_id.vue
使用 fetch()
hook。
<template>
<div class="flex flex-col items-center">
<nuxt-link class="p-4 bg-purple-700 rounded-md" :to="{ name: 'index' }">
Go back
</nuxt-link>
<h2>User details ID: # {{ $route.params.id }}</h2>
<p v-if="$fetchState.pending">Loading user's info...</p>
<p v-else-if="$fetchState.error">Error while fetching user</p>
<div v-else>
<p>{{ user.name }}</p>
<p>{{ user.phone }}</p>
<p>{{ user.website }}</p>
<p>{{ user.company.name }}</p>
</div>
</div>
</template>
<script>
export default {
name: 'UserId',
data() {
return {
user: {},
}
},
async fetch() {
this.user = await this.$axios.$get(`/users/${this.$route.params.id}`)
},
}
</script>
我确实更喜欢这种方法,因为它不会阻塞渲染,您可以添加一些 smooth skeleton 以仍然让用户知道正在发生某些事情。最重要的是,fetch()
在组件和页面上都可用,而 asyncData()
仅适用于页面。
它还提供了非常方便的 $fetchState
helper!
这是使用 asyncData() hook
的相同 /pages/users/_id.vue
页面。
<template>
<div class="flex flex-col items-center">
<nuxt-link class="p-4 bg-purple-700 rounded-md" :to="{ name: 'index' }">
Go back
</nuxt-link>
<p>{{ user.name }}</p>
<p>{{ user.phone }}</p>
<p>{{ user.website }}</p>
<p>{{ user.company.name }}</p>
</div>
</template>
<script>
export default {
name: 'UserId',
async asyncData({ route, $axios }) {
const user = await $axios.$get(`/users/${route.params.id}`)
return { user }
},
}
</script>
使用 asyncData
的主要好处是它更安全并且它会阻止渲染(可以是赞成也可以是反对,对我个人来说更多是反对)。
这里有一些 fetch()
与 asyncData()
。
看看这个 handy blog article on the subject and also this dev.to clone example.
最后,如果您想采用 SSG 路径并在 client-side 上以最少的 API 调用次数优化整个过程,您还可以检查
除了我的最佳答案之外,这个问题与问题无关但仍然相关,这里有一个关于如何正确处理交叉路口的示例。
我没有使用端点,而是在 data()
中本地模拟了数据,因此我将 post 保留在上面。
<template>
<div class="flex flex-col items-center">
<h1 class="p-4 bg-green-700 rounded-md">
List of users ordered by their according message
</h1>
<!-- <pre>{{ messages }}</pre> -->
<section>
<div v-for="user in groupedMessages" :key="user.id" class="mt-4">
<p>
User: <b>{{ user.name }}</b>
</p>
<aside>
Messages:
<span v-if="!user.messages.length">No messages actually</span>
</aside>
<p v-for="message in user.messages" :key="message.id">
<span class="italic">- {{ message.text }}</span>
</p>
</div>
</section>
</div>
</template>
<script>
// ES version of lodash, lighter overall
import { cloneDeep } from 'lodash-es'
export default {
name: 'Index',
data() {
return {
messages: [
{
id: 1,
text: 'Hello world',
userId: 1,
},
{
id: 2,
text: 'Nice cool message',
userId: 1,
},
{
id: 3,
text: 'Still for the first user?',
userId: 1,
},
{
id: 4,
text: 'Yep, apparently...',
userId: 1,
},
{
id: 5,
text: "Eh, surprise, I'm a sneaky one...",
userId: 3,
},
{
id: 6,
text: 'Oh, a second one.',
userId: 2,
},
{
id: 7,
text: "You're damn right!!",
userId: 2,
},
],
users: [
{
name: 'Patrick',
id: 1,
messages: [],
},
{
name: 'Pablo',
id: 2,
messages: [],
},
{
name: 'Unkown author',
id: 5,
messages: [],
},
{
name: 'Escobar',
id: 3,
messages: [],
},
],
}
},
computed: {
groupedMessages() {
// we use that to avoid any kind of further mutation to the initial `users` array
const clonedUsers = cloneDeep(this.users)
// we do loop on each message and find a corresponding user for it
this.messages.forEach((message) =>
clonedUsers.forEach((user) => {
if (user.id === message.userId) {
user.messages.push(message)
}
})
)
return clonedUsers
},
},
}
</script>
github repo is available中的无关名称请不要关注
这是它的样子 on Netlify。