manbetxapp
拍摄者帕特里克穆勒

让我们使用Nuxt和DEV API构建一个快速的文章和教程应用,使用惰性加载、占位符、缓存和流行的新设计UI。

视图演示/来源

本文旨在演示新next的用例和惊人之处拿来功能在版本v2.12中引入,并告诉您如何在您自己的项目中应用其权力。用于深入的技术分析和新的新技术拿来你可以检查Krutie Patel的文章

以下是我们将如何构建我们的dev.to克隆使用的高级大纲拿来钩。我们将:

  • 使用fetchState美元在数据在客户端取出数据时显示漂亮的占位符
  • 使用维生激活在已经访问过的页面上有效地缓存API请求
  • 重用拿来fetch()美元这个。
  • fetchonserver值来控制何时需要在服务器端呈现数据
  • 找到处理错误的方法拿来钩。

目录

DEV API

2019年9月开发打开它们的公共API,我们现在可以使用它来访问文章、用户和其他资源数据。请注意,它仍然是测试版,所以它可能会改变在未来或一些事情可能不会工作如预期。

对于创建我们的DEV克隆,我们感兴趣的API端点:

要保持简单,请与DED API通信,我们将使用本机JavaScript获取API.

设置项目

如果你是一个有经验的开发人员,你可以跳过这一部分和开门见山

确保你安装了Node和npm。我们将使用create-nuxt-app初始化该项目,因此只在终端中键入以下命令:

NPX create-nuxt-app nuxt-dev-to clone #保留每个问题的默认答案

现在cd nuxt-dev-to-clone /和运行npm运行dev..恭喜,你的Nuxt应用程序正在运行http://localhost:3000

让我们安装必要的软件包,并讨论如何构建我们的应用程序。

CSS样式

用于造型,我们将使用最常见的CSS预处理器SASS / SCS和Levemage Vue.js作用域的CSS功能,以保持我们的组件样式封装。来在next中使用Sass/SCSS跑步:

<跨度类="来ken function" data-v-50c2f4bb>添加sass sass-loader@10 - d
NPM.<跨度类="来ken function" data-v-50c2f4bb>安装sass sass-loader@10——save-dev

我们还将使用@nuxtjs / style-resources模块,它将帮助我们在任何Vue文件中使用定义在SCSS变量中的设计令牌,而不需要使用@ import每个文件中的语句。

<跨度类="来ken function" data-v-50c2f4bb>添加@nuxtjs / style-resources
NPM.<跨度类="来ken function" data-v-50c2f4bb>安装@nuxtjs / style-resources

现在通过向其中添加这段代码来告诉next使用它nuxt.config.js

nuxt.config.js
buildModules<跨度类="来ken operator">:<跨度类="来ken punctuation">[<跨度类="来ken string">'@ nuxtjs / style-resources'<跨度类="来ken punctuation">]

阅读更多关于这个模块的内容这里,对于buildModules,你可以在模块vs buildModules文件的一部分。

让我们将设计标记定义为SCSS变量,并将它们放入〜/资产/样式/令牌.SCS并告诉@nuxtjs / style-resources通过添加来加载它们nuxt.config.js

nuxt.config.js
styleResources<跨度类="来ken operator">:<跨度类="来ken punctuation">{scss<跨度类="来ken operator">:<跨度类="来ken punctuation">[<跨度类="来ken string">“~ / /风格/ tokens.scss资产”<跨度类="来ken punctuation">]<跨度类="来ken punctuation">}

我们的设计令牌现在可以通过每个VUE组件中的SCSS变量提供。

用户界面设计

它将有点无聊只是为了复制现有的开发设计和布局,所以为什么我们不尝试一下。您可能已经听说过新的UI趋势 - 内窥镜。如果你错过了它,请阅读更多关于它的信息这里

我们可以找到很多Dribbble照片(这一趋势的来源),但仍然只有少数真实世界的web应用程序构建的neumorphism风格的界面,所以我们只是不万博体育app彩票平台票能错过用CSS和Vue.js重新创建它的机会。它简单、干净、新鲜。

我不打算详细描述这个应用程序的样式方面,但是如果您感兴趣,可以查看来自CSS技巧和CSS。

SVG的图标

对于SVG图标让使用@nuxt / svg.这个模块允许我们导入.svg.将SVG文件作为内联SVG文件,同时将SVG源代码保存在单一位置,并且不会用SVG代码负载污染Vue模板标记。

<跨度类="来ken function" data-v-50c2f4bb>添加@nuxtjs / svg - d
NPM.<跨度类="来ken function" data-v-50c2f4bb>安装@nuxtjs / svg - d
nuxt.config.js
buildModules<跨度类="来ken operator">:<跨度类="来ken punctuation">[<跨度类="来ken string">'@ nuxtjs / svg'<跨度类="来ken punctuation">,<跨度类="来ken string">'@ nuxtjs / style-resources'<跨度类="来ken punctuation">]

依赖关系

要快速简单地保持前端应用程序,我们将仅使用两个依赖性,vue.js核心成员:

让我们将它们添加为nuxt插件,通过创建两个文件。

vue-observe-visibility.client.js
进口<跨度类="来ken imports">Vue<跨度类="来ken keyword module">从<跨度类="来ken string">“vue”<跨度类="来ken keyword module">进口<跨度类="来ken imports">VueObserveVisibility<跨度类="来ken keyword module">从<跨度类="来ken string">“vue-observe-visibility”<跨度类="来ken maybe-class-name">Vue<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">使用<跨度类="来ken punctuation">(<跨度类="来ken maybe-class-name">VueObserveVisibility<跨度类="来ken punctuation">)
Vue-placeholders.js.
进口<跨度类="来ken imports">Vue<跨度类="来ken keyword module">从<跨度类="来ken string">“vue”<跨度类="来ken keyword module">进口<跨度类="来ken imports">VueContentPlaceholders<跨度类="来ken keyword module">从<跨度类="来ken string">“vue-content-placeholders”<跨度类="来ken maybe-class-name">Vue<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">使用<跨度类="来ken punctuation">(<跨度类="来ken maybe-class-name">VueContentPlaceholders<跨度类="来ken punctuation">)

然后把它们加到' '中

nuxt.config.js
插件<跨度类="来ken operator">:<跨度类="来ken punctuation">[<跨度类="来ken string">'〜/ plugins / vue-placeholders.js'<跨度类="来ken punctuation">,<跨度类="来ken string">'〜/ plugins / Vue-Occeative-Visibility.Client.js'<跨度类="来ken punctuation">]

开发应用程序

现在我们终于可以开始开发由Nuxt和新获取

URL结构

让我们为这个简单的应用程序模拟DEV URL结构页面文件夹应该是这样的:

├──指数。│├─rammstein - du hast(2)──cat sound效果器整理www.catsound._tag。vue├──。├─生物信息学,├─生物信息学,├─生物信息学。vue└──index.vue

我们将有2个静态页面

对于应用程序URL的其余部分,我们将使用方便的Nuxt文件为基础动态路线通过创建这样的文件结构来脚手架必要的页面:

这是所有。很简单,对吧?

缓存请求维生激活

新的最酷的实际特征之一拿来它的工作能力维生指令保存拿来访问您已经访问过的页面。让我们把这个特性应用到布局/ default.vue像这样的布局。

布局/ default.vue
<模板<跨度类="来ken punctuation">><跨度类="来ken tag"><nuxt..<跨度类="来ken attr-name">维生<跨度类="来ken punctuation">/><跨度类="来ken tag">模板<跨度类="来ken punctuation">>

用这个指令拿来将仅触发第一个页面访问,之后Nuxt将在内存中保存呈现的组件,并且在每次后续访问时,它将从缓存中重用。它比这更简单吗?

此外,next给了我们细粒度的控制维生keep属性,您可以在其中设置要缓存的组件数量,以及激活钩子,在那里你可以控制缓存的生存时间。在下一节中,我们将在应用程序中使用最新的一个。

使用拿来在页面组件

让我们潜入拿来本身的特性。

目前你可以从中看到最终结果我们有3页组件基本上重复使用相同的代码 - 它是index.vuetop.vuet / _tag.vue页面组件。他们只是渲染一个文章预览卡的列表。

index.vue
<模板<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"页面包装器<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-cards-wrapper<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><article-card-block<跨度类="来ken attr-name">v代表<跨度类="来ken attr-value"><跨度类="来ken punctuation">"(文章,i)在文章中<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:关键<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article.id<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:文章<跨度类="来ken attr-value"><跨度类="来ken punctuation">"文章<跨度类="来ken punctuation">"<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-card-block<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><跨度类="来ken tag"><脚本<跨度类="来ken punctuation">><跨度类="来ken script">进口<跨度类="来ken imports">articlecardblock.<跨度类="来ken keyword module">从<跨度类="来ken string">“@ /组件/模块/ ArticleCardBlock”<跨度类="来ken keyword module">出口<跨度类="来ken keyword module">默认的<跨度类="来ken punctuation">{组件<跨度类="来ken operator">:<跨度类="来ken punctuation">{<跨度类="来ken maybe-class-name">articlecardblock.<跨度类="来ken punctuation">}<跨度类="来ken punctuation">,<跨度类="来ken function">数据<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword control-flow">返回<跨度类="来ken punctuation">{当前页<跨度类="来ken operator">:<跨度类="来ken number">1<跨度类="来ken punctuation">,文章<跨度类="来ken operator">:<跨度类="来ken punctuation">[<跨度类="来ken punctuation">]<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}<跨度类="来ken punctuation">,<跨度类="来ken keyword">异步<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">const文章<跨度类="来ken operator">=<跨度类="来ken keyword control-flow">等待<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken template-string"><跨度类="来ken string">https://dev.to/api/articles?tag=nuxt&state=rising&page=<跨度类="来ken interpolation">$ {<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">当前页<跨度类="来ken interpolation-punctuation punctuation">}<跨度类="来ken template-punctuation string">`<跨度类="来ken punctuation">)<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">然后<跨度类="来ken punctuation">(<跨度类="来ken parameter">res<跨度类="来ken arrow operator">=>res<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">json<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">)<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken operator">=<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">concat<跨度类="来ken punctuation">(文章<跨度类="来ken punctuation">)<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}<跨度类="token tag">脚本<跨度类="来ken punctuation">>

请注意以下代码块:

index.vue
异步<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">const文章<跨度类="来ken operator">=<跨度类="来ken keyword control-flow">等待<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken template-string"><跨度类="来ken string">https://dev.to/api/articles?tag=nuxt&state=rising&page=<跨度类="来ken interpolation">$ {<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">当前页<跨度类="来ken interpolation-punctuation punctuation">}<跨度类="来ken template-punctuation string">`<跨度类="来ken punctuation">)<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">然后<跨度类="来ken punctuation">(<跨度类="来ken punctuation">(<跨度类="来ken parameter">res<跨度类="来ken punctuation">)<跨度类="来ken arrow operator">=>res<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">json<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">)<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken operator">=<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">concat<跨度类="来ken punctuation">(文章<跨度类="来ken punctuation">)<跨度类="来ken punctuation">}

在这里,我们正在向DEV提出要求/文章端点,具有API的查询参数。不要混淆拿来挂钩JavaScript拿来接口帮助我们发送请求到DEV API,然后解析响应res.json ()

还要注意新拿来钩子不仅仅用于调度Vuex存储操作或提交突变来设置状态,现在它可以访问上下文,并能够直接突变组件的数据。这是一个非常重要的新功能,你可以阅读更多关于它在前一篇文章中拿来

现在让我们标记<文章卡块>组件的接收文章Prop和渲染它的数据很好。

ArticleCardBlock.vue
<模板<跨度类="来ken punctuation">><跨度类="来ken tag"><NUXT-LINK.<跨度类="来ken attr-name">:<跨度类="来ken attr-value"><跨度类="来ken punctuation">"{名称:<跨度类="来ken punctuation">'username-article<跨度类="来ken punctuation">',params:{username:temart.user.username,文章:文章.ID}}<跨度类="来ken punctuation">"<跨度类="来ken attr-name">标签<跨度类="来ken attr-value"><跨度类="来ken punctuation">"文章<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"image-wrapper<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><IMG.<跨度类="来ken attr-name">v<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article.cover_image<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:SRC.<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article.cover_image<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:ALT.<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article.title<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/><跨度类="来ken tag"><IMG.<跨度类="来ken attr-name">v-else<跨度类="来ken attr-name">:SRC.<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article.social_image<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:ALT.<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article.title<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"内容<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><NUXT-LINK.<跨度类="来ken attr-name">:<跨度类="来ken attr-value"><跨度类="来ken punctuation">"{名称:<跨度类="来ken punctuation">'username-article<跨度类="来ken punctuation">',params:{username:temart.user.username,文章:文章.ID}}<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><h1<跨度类="来ken punctuation">>{{文章。标题}}<跨度类="来ken tag">h1<跨度类="来ken punctuation">><跨度类="来ken tag">NUXT-LINK.<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"标签<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><NUXT-LINK.<跨度类="来ken attr-name">v代表<跨度类="来ken attr-value"><跨度类="来ken punctuation">"标签article.tag_list<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:关键<跨度类="来ken attr-value"><跨度类="来ken punctuation">"标签<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:<跨度类="来ken attr-value"><跨度类="来ken punctuation">"{名称:<跨度类="来ken punctuation">'t-tag<跨度类="来ken punctuation">',params:{tag}}<跨度类="来ken punctuation">"<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"标签<跨度类="来ken punctuation">"<跨度类="来ken punctuation">>#{{标签}}<跨度类="来ken tag">NUXT-LINK.<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"元<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"sci<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><跨度<跨度类="来ken punctuation">><跨度类="来ken tag"><心脏图标这部分给<跨度类="来ken punctuation">/>{{文章。positive_reactions_count }}<跨度类="来ken tag">跨度<跨度类="来ken punctuation">><跨度类="来ken tag"><跨度<跨度类="来ken punctuation">><跨度类="来ken tag"><comments-icon<跨度类="来ken punctuation">/>{{文章.评论_count}}<跨度类="来ken tag">跨度<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag"><时间<跨度类="来ken punctuation">>{{文章.readable_publish_date}}<跨度类="来ken tag">时间<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">NUXT-LINK.<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><跨度类="来ken tag"><脚本<跨度类="来ken punctuation">><跨度类="来ken script">进口<跨度类="来ken imports">心脏<跨度类="来ken keyword module">从<跨度类="来ken string">@ /资产/图标/ heart.svg吗?内嵌的<跨度类="来ken keyword module">进口<跨度类="来ken imports">CommentsIcon<跨度类="来ken keyword module">从<跨度类="来ken string">'@ /资产/图标/评论.svg?内联'<跨度类="来ken keyword module">出口<跨度类="来ken keyword module">默认的<跨度类="来ken punctuation">{组件<跨度类="来ken operator">:<跨度类="来ken punctuation">{<跨度类="来ken maybe-class-name">心脏<跨度类="来ken punctuation">,<跨度类="来ken maybe-class-name">CommentsIcon<跨度类="来ken punctuation">}<跨度类="来ken punctuation">,道具<跨度类="来ken operator">:<跨度类="来ken punctuation">{文章<跨度类="来ken operator">:<跨度类="来ken punctuation">{类型<跨度类="来ken operator">:<跨度类="来ken known-class-name class-name">目的<跨度类="来ken punctuation">,<跨度类="来ken keyword module">默认的<跨度类="来ken operator">:<跨度类="来ken keyword null nil">零<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}<跨度类="token tag">脚本<跨度类="来ken punctuation">>

重复使用拿来fetch()美元这个。

它应该已经显示了从DEV获取的文章列表-但感觉我们没有充分利用这个API。让我们将延迟加载添加到文章列表中,并使用此API提供的分页参数。所以当我们滚动到页面的底部,一个新的文章块将被获取和渲染。

为了有效地检测何时获取下一页,最好使用它交叉观察者API..为此,我们将使用之前安装的Vue插件vue-observe-visibility这基本上是该API周围的包装器,它将检测到元素变得可见或隐藏在页面上。此插件为我们提供了使用的可能性v-observe-visibility指令,把它加到最后<文章卡块>成分:

index.vue
<article-card-block<跨度类="来ken attr-name">v代表<跨度类="来ken attr-value"><跨度类="来ken punctuation">"(文章,i)在文章中<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:关键<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article.id<跨度类="来ken punctuation">"<跨度类="来ken attr-name">v-observe-visibility<跨度类="来ken attr-value"><跨度类="来ken punctuation">"我= = =的文章。长度- 1 ?lazyLoadArticles:假<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:文章<跨度类="来ken attr-value"><跨度类="来ken punctuation">"文章<跨度类="来ken punctuation">"<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-card-block<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/>

正如你可以从上面的代码猜,当最后<文章卡块>出现在视口中lazyLoadArticles将被解雇。让我们看看:

lazyLoadArticles<跨度类="来ken punctuation">(<跨度类="来ken parameter">isVisible<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword control-flow">如果<跨度类="来ken punctuation">(isVisible<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword control-flow">如果<跨度类="来ken punctuation">(<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">当前页<跨度类="来ken operator"><<跨度类="来ken number">5<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">当前页<跨度类="来ken operator">++<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">取美元<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}

这里我们看到了新事物的力量拿来钩。我们可以重复使用取美元作为一个方法,并在触发延迟加载时获取下一页。

应用占位符fetchState美元

如果您已经应用了前一节中的代码并尝试了客户端导航index.vuetop.vuet / _tag.vue您可能注意到,在等待API请求完成时,它暂时显示一个空页面。这是有意为之的行为,与过去不同拿来asyncData在页面导航之前触发的钩子。

多亏了fetchState.pending美元拿来当在客户端调用fetch时,我们可以使用这个标志来显示占位符。vue-content-placeholders插件将被用作占位符。

index.vue
<模板<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"页面包装器<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><模板<跨度类="来ken attr-name">v<跨度类="来ken attr-value"><跨度类="来ken punctuation">"拿来State.pending美元<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-cards-wrapper<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><content-placeholders<跨度类="来ken attr-name">v代表<跨度类="来ken attr-value"><跨度类="来ken punctuation">"P 30<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:关键<跨度类="来ken attr-value"><跨度类="来ken punctuation">"p<跨度类="来ken punctuation">"<跨度类="来ken attr-name">圆形的<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-card-block<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><content-placeholders-img<跨度类="来ken punctuation">/><跨度类="来ken tag"><content-placeholders-text<跨度类="来ken attr-name">:行<跨度类="来ken attr-value"><跨度类="来ken punctuation">"3.。<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/><跨度类="来ken tag">content-placeholders<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><跨度类="来ken tag"><模板<跨度类="来ken attr-name">v-else-if<跨度类="来ken attr-value"><跨度类="来ken punctuation">"拿来State.error美元<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><p<跨度类="来ken punctuation">>{{拿来State.error美元。消息}}<跨度类="来ken tag">p<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><跨度类="来ken tag"><模板<跨度类="来ken attr-name">v-else<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-cards-wrapper<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><article-card-block<跨度类="来ken attr-name">v代表<跨度类="来ken attr-value"><跨度类="来ken punctuation">"(文章,i)在文章中<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:关键<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article.id<跨度类="来ken punctuation">"<跨度类="来ken attr-name">v-observe-visibility<跨度类="来ken attr-value"><跨度类="来ken punctuation">"我= = =的文章。长度- 1 ?lazyLoadArticles:假<跨度类="来ken punctuation">"<跨度类="来ken attr-name">:文章<跨度类="来ken attr-value"><跨度类="来ken punctuation">"文章<跨度类="来ken punctuation">"<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-card-block<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">>

我们模仿了<文章卡块>看起来与vue-content-placeholders组件,并且正如您在源代码中看到的那样,它将在几乎所有使用拿来挂钩,因此让我们不再关注代码的那些部分(它们在每个组件中基本相同)。

使用拿来在任何其他组件中

这可能是新功能中最有趣的特性拿来钩。我们现在可以使用拿来在任何VUE组件中挂钩而不担心打破SSR!这意味着如何构建Async API调用和组件的头痛得多。

为了探索这个伟大的功能,让我们继续_username / _article.vue页面组件。

_username / _article.vue
<模板<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"页面包装器<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-content-wrapper<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><article-block<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"article-block<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"旁边用户名包装器<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><aside-username-block<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"aside-username-block<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag"><comments-block<跨度类="来ken attr-name">类<跨度类="来ken attr-value"><跨度类="来ken punctuation">"comments-block<跨度类="来ken punctuation">"<跨度类="来ken punctuation">/><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><跨度类="来ken tag"><脚本<跨度类="来ken punctuation">><跨度类="来ken script">进口<跨度类="来ken imports">ArticleBlock<跨度类="来ken keyword module">从<跨度类="来ken string">“@ /组件/模块/ ArticleBlock”<跨度类="来ken keyword module">进口<跨度类="来ken imports">意见博弈<跨度类="来ken keyword module">从<跨度类="来ken string">“@ /组件/模块/ CommentsBlock”<跨度类="来ken keyword module">进口<跨度类="来ken imports">AsideUsernameBlock<跨度类="来ken keyword module">从<跨度类="来ken string">“@ /组件/模块/ AsideUsernameBlock”<跨度类="来ken keyword module">出口<跨度类="来ken keyword module">默认的<跨度类="来ken punctuation">{组件<跨度类="来ken operator">:<跨度类="来ken punctuation">{<跨度类="来ken maybe-class-name">ArticleBlock<跨度类="来ken punctuation">,<跨度类="来ken maybe-class-name">意见博弈<跨度类="来ken punctuation">,<跨度类="来ken maybe-class-name">AsideUsernameBlock<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}<跨度类="token tag">脚本<跨度类="来ken punctuation">>

在这里,我们根本没有提出数据,只有由3个组件组成的模板布局:<物品块/>< aside-username-block / >< comments-block / >.每个组件都有自己的拿来钩。旧拿来或当前asyncData早些时候我们必须将所有三个请求提交到三个不同的DEV端点,然后将其传递给每个组件作为一个道具。但现在这些组件完全封装。

<物品块/>我们使用拿来就像在页面组件中使用它一样。

异步<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">const文章<跨度类="来ken operator">=<跨度类="来ken keyword control-flow">等待<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken template-string"><跨度类="来ken string">https://dev.to/api/articles/<跨度类="来ken interpolation">$ {<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">$途中<跨度类="来ken punctuation">.<跨度类="来ken property-access">参数个数<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken interpolation-punctuation punctuation">}<跨度类="来ken template-punctuation string">`<跨度类="来ken punctuation">)<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">然后<跨度类="来ken punctuation">(<跨度类="来ken punctuation">(<跨度类="来ken parameter">res<跨度类="来ken punctuation">)<跨度类="来ken arrow operator">=>res<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">json<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">)<跨度类="来ken keyword control-flow">如果<跨度类="来ken punctuation">(文章<跨度类="来ken punctuation">.<跨度类="来ken property-access">id<跨度类="来ken operator">& &文章<跨度类="来ken punctuation">.<跨度类="来ken property-access">用户<跨度类="来ken punctuation">.<跨度类="来ken property-access">用户名<跨度类="来ken operator">===<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">$途中<跨度类="来ken punctuation">.<跨度类="来ken property-access">参数个数<跨度类="来ken punctuation">.<跨度类="来ken property-access">用户名<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken operator">=文章<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">美元商店<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">提交<跨度类="来ken punctuation">(<跨度类="来ken string">'set_current_article'<跨度类="来ken punctuation">,<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken punctuation">)<跨度类="来ken punctuation">}<跨度类="来ken keyword control-flow">其他的<跨度类="来ken punctuation">{<跨度类="来ken comment">//在服务器上设置状态代码<跨度类="来ken keyword control-flow">如果<跨度类="来ken punctuation">(过程<跨度类="来ken punctuation">.<跨度类="来ken property-access">服务器<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">$ nuxt.<跨度类="来ken punctuation">.<跨度类="来ken property-access">上下文<跨度类="来ken punctuation">.<跨度类="来ken property-access">res<跨度类="来ken punctuation">.<跨度类="来ken property-access">statusCode<跨度类="来ken operator">=<跨度类="来ken number">404<跨度类="来ken punctuation">}<跨度类="来ken comment">//抛出一个错误将设置$fetchState.error<跨度类="来ken keyword control-flow">扔<跨度类="来ken keyword">新<跨度类="来ken class-name">错误<跨度类="来ken punctuation">(<跨度类="来ken string">文章没有找到的<跨度类="来ken punctuation">)<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}

记住,在关于缓存的部分中我提到过激活用于管理TTL的拿来?这是这种用法的一个例子:

激活<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword control-flow">如果<跨度类="来ken punctuation">(<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">fetchState美元<跨度类="来ken punctuation">.<跨度类="来ken property-access">时间戳<跨度类="来ken operator"><=<跨度类="来ken known-class-name class-name">日期<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">现在<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken operator">-<跨度类="来ken number">60000<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">取美元<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}

有了这段代码,如果上次取回的时间超过60秒,我们将再次调用fetch。这段时间内的所有其他请求都将被缓存。

还有一个有趣的使用拿来功能调用fetchonserver在里面< comments-block >成分。我们真的不想在服务器端呈现此内容,因为注释是用户生成的,可能是无关紧要的或垃圾。我们不需要任何SEO来此内容块。现在,在提到的帮助下fetchonserver我们有这样的控制:

异步<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">评论<跨度类="来ken operator">=<跨度类="来ken keyword control-flow">等待<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken template-string"><跨度类="来ken string">https://dev.to/api/comments?a_id=.<跨度类="来ken interpolation">$ {<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">$途中<跨度类="来ken punctuation">.<跨度类="来ken property-access">参数个数<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken interpolation-punctuation punctuation">}<跨度类="来ken template-punctuation string">`<跨度类="来ken punctuation">)<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">然后<跨度类="来ken punctuation">(<跨度类="来ken punctuation">(<跨度类="来ken parameter">res<跨度类="来ken punctuation">)<跨度类="来ken arrow operator">=>res<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">json<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">)<跨度类="来ken punctuation">}<跨度类="来ken punctuation">,拿来onserver<跨度类="来ken operator">:<跨度类="来ken boolean">假

错误处理

最后应该提到的是错误处理。您可能已经看到我们在上面使用了错误处理,但是让我们更加关注这个重要的主题。

如你所知,拿来被处理在组件级别,当执行服务器端呈现时,父(虚拟)dom树已经在呈现组件时呈现了,所以我们不能通过调用来改变它美元nuxt.error(…)相反,我们必须这样做处理组件级别的错误

fetchState.error美元控件中抛出错误时,设置拿来钩子,所以我们可以在模板中使用它来显示错误消息:

<模板<跨度类="来ken punctuation">><跨度类="来ken tag"><div<跨度类="来ken attr-name">类<跨度类="来ken attr-value">“页面包装器”<跨度类="来ken punctuation">><跨度类="来ken tag"><模板<跨度类="来ken attr-name">v<跨度类="来ken attr-value"><跨度类="来ken punctuation">"拿来State.pending美元<跨度类="来ken punctuation">"<跨度类="来ken punctuation">><跨度类="来ken tag"><<跨度类="来ken attr-name">占位符<跨度类="来ken attr-name">去<跨度类="来ken attr-name">这里<跨度类="来ken attr-name">- - - - - -<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><模板v-else-if = " $ fetchState.error " ><跨度类="来ken tag"><p<跨度类="来ken punctuation">>{{拿来State.error美元。消息}}<跨度类="来ken tag">p<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><跨度类="来ken tag"><模板<跨度类="来ken attr-name">v-else<跨度类="来ken punctuation">><跨度类="来ken tag"><<跨度类="来ken attr-name">获取<跨度类="来ken attr-name">内容<跨度类="来ken attr-name">去<跨度类="来ken attr-name">这里<跨度类="来ken attr-name">- - - - - -<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">><跨度类="来ken tag">div<跨度类="来ken punctuation">><跨度类="来ken tag">模板<跨度类="来ken punctuation">>

然后,在我们的拿来如果没有找到定义的作者对应的文章,就会抛出错误:

异步<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">const文章<跨度类="来ken operator">=<跨度类="来ken keyword control-flow">等待<跨度类="来ken function">拿来<跨度类="来ken punctuation">(<跨度类="来ken template-string"><跨度类="来ken string">https://dev.to/api/articles/<跨度类="来ken interpolation">$ {<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">$途中<跨度类="来ken punctuation">.<跨度类="来ken property-access">参数个数<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken interpolation-punctuation punctuation">}<跨度类="来ken template-punctuation string">`<跨度类="来ken punctuation">)<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">然后<跨度类="来ken punctuation">(<跨度类="来ken punctuation">(<跨度类="来ken parameter">res<跨度类="来ken punctuation">)<跨度类="来ken arrow operator">=>res<跨度类="来ken punctuation">.<跨度类="来ken method function property-access">json<跨度类="来ken punctuation">(<跨度类="来ken punctuation">)<跨度类="来ken punctuation">)<跨度类="来ken keyword control-flow">如果<跨度类="来ken punctuation">(文章<跨度类="来ken punctuation">.<跨度类="来ken property-access">id<跨度类="来ken operator">& &文章<跨度类="来ken punctuation">.<跨度类="来ken property-access">用户<跨度类="来ken punctuation">.<跨度类="来ken property-access">用户名<跨度类="来ken operator">===<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">$途中<跨度类="来ken punctuation">.<跨度类="来ken property-access">参数个数<跨度类="来ken punctuation">.<跨度类="来ken property-access">用户名<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">文章<跨度类="来ken operator">=文章<跨度类="来ken punctuation">}<跨度类="来ken keyword control-flow">其他的<跨度类="来ken punctuation">{<跨度类="来ken comment">//在服务器上设置状态代码<跨度类="来ken keyword control-flow">如果<跨度类="来ken punctuation">(过程<跨度类="来ken punctuation">.<跨度类="来ken property-access">服务器<跨度类="来ken punctuation">)<跨度类="来ken punctuation">{<跨度类="来ken keyword">这<跨度类="来ken punctuation">.<跨度类="来ken property-access">$ nuxt.<跨度类="来ken punctuation">.<跨度类="来ken property-access">上下文<跨度类="来ken punctuation">.<跨度类="来ken property-access">res<跨度类="来ken punctuation">.<跨度类="来ken property-access">statusCode<跨度类="来ken operator">=<跨度类="来ken number">404<跨度类="来ken punctuation">}<跨度类="来ken keyword control-flow">扔<跨度类="来ken keyword">新<跨度类="来ken class-name">错误<跨度类="来ken punctuation">(<跨度类="来ken string">文章没有找到的<跨度类="来ken punctuation">)<跨度类="来ken punctuation">}<跨度类="来ken punctuation">}

注意,我们在这里包装nuxt.context.res美元。statusCode = 404周围process.server,这用于在服务器端上设置正确的SEO的HTTP状态代码。

结论

在本文中,我们探索了Nuxt.js new拿来并建立了一个应用程序,只使用基本开发的内容功能和结构拿来钩。我希望你能够获得一些灵感去创造自己版本的DEV.TO。别忘了去看看源代码有关更完整的示例和功能。

接下来要做什么:

  • Krutie Patel文章与深入分析如何新拿来钩的作品
  • 查看Nuxt-Hackernews.的类似用法Hacker News API
  • 订阅对于NewSletter来说,不要错过即将到来的文章和资源,我计划编写文章有关如何使用NUXT创建个人博客的文章,并使用DEV作为CMS。万博全站客户端app
nuxt.<跨度类="px-2 py-1 mb-2 mr-2 font-medium tracking-wider uppercase truncate transition-colors duration-300 ease-linear border rounded-full text-ss border-light-border dark:border-dark-border">获取<跨度类="px-2 py-1 mb-2 mr-2 font-medium tracking-wider uppercase truncate transition-colors duration-300 ease-linear border rounded-full text-ss border-light-border dark:border-dark-border">异步数据获取<跨度类="px-2 py-1 mb-2 mr-2 font-medium tracking-wider uppercase truncate transition-colors duration-300 ease-linear border rounded-full text-ss border-light-border dark:border-dark-border">API