_小生_

使用Nuxt.js简单的服务器端渲染,路由和页面转换CSS-Tricks

原文链接: css-tricks.com

有点罗嗦的标题,是吧?什么是服务器端渲染?它与路由和页面转换有什么关系?什么是Nuxt.js?有趣的是,尽管听起来很复杂,但使用Nuxt.js并探索其好处并不困难。让我们开始吧!

服务器端渲染

最近你可能听说过人们在谈论服务器端渲染。我们研究了最近用React做的一种方法 。一个特别引人注目的方面是性能优势。当我们在服务器上呈现我们的HTML,CSS和JavaScript时,我们通常使用较少的JavaScript来解析最初和随后的更新。本文 很好地深入讨论了这个问题。我最喜欢的是:

通过在服务器上渲染,您可以缓存数据的最终形状。

不用从服务器获取JSON或其他信息,解析它,然后使用JavaScript创建这些信息的布局,我们在前期做了大量计算,只发送了我们需要的实际HTML,CSS和JavaScript 。这可以通过缓存,搜索引擎优化以及加速我们的应用程序和网站获得很多好处。

什么是 Nuxt.js?

服务器端渲染听起来很不错,但你可能想知道是否难以设置。我最近一直在为我的Vue应用程序使用Nuxt.js ,并发现使用它非常简单。要清楚:你不需要特别使用Nuxt.js来做服务器端渲染。我只是这个工具的粉丝,原因很多。我上个月跑了一些测试,发现Nuxt.js比Vue的PWA模板有更高的灯塔分数,我认为这是令人印象深刻的。

Nuxt.js是一个更高级的框架,您可以使用CLI命令来创建通用的Vue应用程序。以下是它的一些好处:

  • 服务器端渲染
  • 自动代码分割
  • 强大的路由系统
  • Great lighthouse scores out of the gate 🐎
  • 静态文件服务
  • ES6/ES7 支持
  • 在开发中热重新加载
  • 预处理: SASS, LESS, Stylus, etc
  • 编写Vue文件来创建您的页面和布局!
  • 我个人最喜欢的:轻松添加转换到您的网页

让我们用一些路由设置一个基本的应用程序来看看我们自己的好处。

设置

我们需要做的第一件事情就是下载Vue的CLI。您可以使用以下命令全局执行此操作:

npm install -g vue-cli

# ... or ...

yarn add global vue-cli

你只需要做一次,而不是每次使用它。

接下来,我们将使用CLI搭建一个新项目,但我们将使用Nuxt.js作为模板:

vue init nuxt/starter my-project
cd my-project
yarn  # or...  npm install
npm run dev

您将看到正在构建的应用程序的进度,它会为您提供专用的开发服务器以检查:http://127.0.0.1:3000/。这就是你马上会看到的(用一个非常酷的小动画):

Screenshot of Nuxt starting screen

我们来看看这个时候创建​​应用程序的初始视图是什么。我们可以进入\ pages \目录,在里面看到我们有一个\ index.vue \页面。如果我们打开它,我们会看到创建该页面所需的所有标记。我们还会看到它是一个.vue文件,使用单个文件组件就像任何普通的\ vue \文件一样,具有HTML的模板标签,脚本的脚本标签,我们导入组件的位置以及一些样式标签中的样式。 (如果你不熟悉这些,那么这里有更多的信息。)整个事情最酷的部分是这个.vue文件不需要任何特殊的设置。它被放置在\ pages \目录下,Nuxt.js会自动生成这个服务器端的渲染页面!

我们创建一个新页面并在它们之间建立一些路由。在\ pages / index.vue \中,转储已存在的内容,并将其替换为:

<template>
  <div>
    <h1>Welcome!</h1>
    <p><nuxt-link to="/product">Product page</nuxt-link></p>
  </div>
</template>

<style>
.container {
  font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
  padding: 60px;
}
</style>

然后让我们在pages目录中创建另一个页面,我们将其称为\ product.vue \并将其放入其中:

<template>
  <div>
    <h1>This is the product page</h1>
    <p><nuxt-link to="/">Home page</nuxt-link></p>
  </div>
</template>

马上,你会看到这个:

当当! 🏆立即,我们有服务器端渲染,页面之间的路由(如果您检查URL,您可以看到它在索引页面和产品页面之间进行),并且我们甚至有一个可爱的小绿色加载器,可以跨越顶部。为了实现这一目标,我们并不需要做太多的工作。

你可能在这里注意到,有一个特殊的小元素:<nuxt-link to="/">这个可以像一个标签一样使用,在标签中包含一些内容,它将在我们的页面之间建立一个内部路由链接。我们将使用to =“/ page-title-here”而不是href。

现在,我们添加一些转换。我们将在几个阶段做到这一点:从简单到复杂。

创建页面转换

我们已经有了一个非常酷的进度条,当我们进行路由选择时,它将贯穿屏幕的顶部,并使整个事情变得非常快乐。 (这是一个技术术语)。尽管我非常喜欢它,但它并不能真正适合我们前进的方向,所以现在就让我们摆脱它。

我们将进入我们的\ nuxt.config.js \文件并更改行:

/*
** Customize the progress-bar color
*/
loading: { color: '#3B8070' },

to

loading: false,

您还会注意到nuxt.config.js文件中的其他一些内容。您会看到我们的meta和head标签以及将在其中呈现的内容。这是因为我们不会像我们在常规CLI构建中那样有一个传统的\ index.html \文件,Nuxt.js将解析并构建我们的\ index.vue \文件以及这些标记,然后将内容呈现给我们,在服务器上。如果您需要添加CSS文件,字体或类似内容,我们将使用此Nuxt.js配置文件来执行此操作。

现在我们已经完成了所有工作,让我们了解可用于创建页面转换的内容。为了解我们插入的页面上发生了什么,我们需要回顾Vue中的转换组件的工作原理。我在这里写了一篇关于这方面的文章,所以如果你想深入了解这个主题,你可以检查一下。但是你真正需要知道的是:Nuxt.js将插入到Vue转换组件的功能中,并为我们提供一些默认值和钩子:

transition component hooks

你可以在这里看到,我们在动画开始输入前,动画/转换输入活动期间以及结束时我们有一个钩子。我们对于什么时候离开时有这些相同的挂钩,而不是预留。我们可以在状态之间插入简单的转换,或者将完整的CSS或JavaScript动画插入到它们中。

通常在Vue应用程序中,我们会在<transition>中包装一个组件或元素,以便使用这种漂亮的小功能,但是Nuxt.js会在我们开始时为我们提供此功能。我们的页面钩子将开始,thankfully- page。我们在页面之间创建动画所需做的只是添加一些插入钩子的CSS:

.page-enter-active, .page-leave-active {
  transition: all .25s ease-out;
}
.page-enter, .page-leave-active {
  opacity: 0;
  transform-origin: 50% 50%;
}

我也会在这里添加一些额外的样式,以便您可以更轻松地看到页面转换:

html, body {
  font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
  background: #222;
  color: white;
  width: 100vw;
  height: 100vh;
}

a, a:visited {
  color: #3edada;
  text-decoration: none;
}

.container {
  padding: 60px;
  width: 100vw;
  height: 100vh;
  background: #444;
}

现在我们正在使用CSS转换。这只能让我们有能力指定在两个州的中间做些什么。我们可以做一些更有趣的动画,调整动画的方式可以表明某些东西来自哪里以及哪些东西来自哪里。为了实现这一点,我们可以分离出页面输入和页面离开活动类的转换,但是使用CSS动画并指定事物来自哪里并将其插入到每个类中会更加干燥。页面输入活动和.page-leave-active:

.page-enter-active {
  animation: acrossIn .45s ease-out both;
} 

.page-leave-active {
  animation: acrossOut .65s ease-in both;
} 

@keyframes acrossIn {
  0% {
    transform: translate3d(-100%, 0, 0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

@keyframes acrossOut {
  0% {
    transform: translate3d(0, 0, 0);
  }
  100% {
    transform: translate3d(100%, 0, 0);
  }
}

我们还在产品页面上添加一些特殊的样式,以便我们看到这两个页面之间的区别:

<style scoped>
  .container {
    background: #222;
  }
</style>

这个范围标记非常酷,因为它只会应用这个页面/ vue文件的样式。如果你听说过CSS模块,你会熟悉这个概念。

我们会看到这个(这个页面仅用于演示目的,这对于典型的页面转换来说可能太多了):

现在,假设我们有一个完全不同的交互页面。对于这个页面,上下移动太多了,我们只是想要一个简单的淡入淡出。对于这种情况,我们需要重命名我们的转换钩以将其分开。

我们创建另一个页面,我们将其称为联系页面并在页面目录中创建它。

<template>
  <div>
    <h1>This is the contact page</h1>
    <p><nuxt-link to="/">Home page</nuxt-link></p>
  </div>
</template>

<script>
export default {
  transition: 'fadeOpacity'
}
</script>

<style>
.fadeOpacity-enter-active, .fadeOpacity-leave-active {
  transition: opacity .35s ease-out;
}

.fadeOpacity-enter, .fadeOpacity-leave-active {
  opacity: 0;
}
</style>

现在我们可以开始进行两个页面的切换了。

您可以看到我们如何在这些基础上进一步构建,并为每个页面创建更多更精简的CSS动画。但是从这里开始,我们将深入我最喜爱的JavaScript动画,并创建更多马力的页面转换。

Javascript Hooks

Vue的<transition>组件提供了一些使用JavaScript动画代替CSS的钩子。他们如下,每个钩子是可选的。 css =“false”绑定让Vue知道我们要为这个动画使用JS:

<transition 
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @enter-cancelled="enterCancelled"

  @before-Leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  @leave-cancelled="leaveCancelled"
  :css="false">

 </transition>

我们可以获得的另一件事是转换模式。我非常喜欢这些,因为您可以声明一个动画会等待另一个动画在转换之前完成转换。我们将使用的转换模式将被称为out-in。

我们可以用JavaScript和过渡模式做一些非常狂野的事情,再次,我们为了演示的目的而在这里稍微坚持一点,我们通常会做一些更加微妙的事情:

为了做这样的事情,我已经运行了纱线添加gsap,因为我正在使用GreenSock进行这个动画。在我的\ index.vue \页面中,我可以删除现有的CSS动画并将其添加到<script>标记中:

import { TweenMax, Back } from 'gsap'

export default {
  transition: {
    mode: 'out-in',
    css: false,
    beforeEnter (el) {
      TweenMax.set(el, {
        transformPerspective: 600,
        perspective: 300,
        transformStyle: 'preserve-3d'
      })
    },
    enter (el, done) {
      TweenMax.to(el, 1, {
        rotationY: 360,
        transformOrigin: '50% 50%',
        ease: Back.easeOut
      })
      done()
    },
    leave (el, done) {
      TweenMax.to(el, 1, {
        rotationY: 0,
        transformOrigin: '50% 50%',
        ease: Back.easeIn
      })
      done()
    }
  }
}

所有这些演示代码都存在于我的Intro to Vue repo初学者材料中,如果你正在学习Vue的话。

我想在这里调出的一件事是,目前Nuxt.js中的转换模式存在一个错误。这个bug已经修复,但是这个版本还没有出来。它应该在即将到来的1.0版本中都是固定的和最新的,但同时,这里是一个工作简单示例演示,以及追踪问题

通过这个工作代码和JavaScript钩子,我们可以开始变得更加奇特并创建独特的效果,并在每个页面上进行不同的转换:

以下是演示部署到的网站,如果您希望看到它:https://nuxt-type.now.sh/ 以及回收代码: https://github.com/sdras/nuxt-type

导航

在最后一个演示中,您可能已经注意到我们在所有页面中都有一个通用导航,我们路由了该页面。为了创建它,我们可以进入\ layouts \目录,我们将看到一个名为\ default.vue的文件。这个目录将包含我们所有页面的基本布局。

Right away you'll see this:

<template>
  <div>
    <nuxt/>
  </div>
</template>

这个特殊<nuxt/>将会放在我们的.vue页面文件将被插入的地方,所以为了创建一个导航,我们可以像这样插入一个导航组件:

<template>
  <div>
    <img src />
    <Navigation />
    <nuxt/>
  </div>
</template>

<script>
import Navigation from '~components/Navigation.vue'

export default {
  components: {
    Navigation
  }
}
</script>

我喜欢这一点,因为一切都保持良好,并在我们的全球和当地需求之间组织。

然后我在名为\ components \的目录中有一个名为Navigation的组件(这是Vue应用程序的标准票价)。在这个文件中,你会看到一堆指向不同页面的链接:

<nav>
  <div>
    <nuxt-link to="/rufina">Rufina</nuxt-link>
    <nuxt-link to="/prata">Prata</nuxt-link>
    <nuxt-link exact to="/">Playfair</nuxt-link>
  </div>
</nav>

你会注意到我再次使用<nuxt-link>标签,即使它在另一个目录中,路由仍然可以工作。但最后一页有一个额外的属性,确切的属性:<nuxt-link exact to="/">Playfair</nuxt-link>这是因为有许多路由只匹配/目录,实际上它们都是。所以如果我们指定确切的话,Nuxt会知道我们只是特别指的是索引页。

更多资源

如果您想了解更多关于Nuxt的信息,Nuxt的文档非常甜蜜,并且有很多示例可供您使用。如果您想了解更多关于Vue的信息,我刚刚在Frontend Masters上发了一个课程,所有材料都是开源的,或者你可以查看我们的Guide for Vue,或者你可以去docs,写得非常好。快乐的编码!