介绍

Nuxt.js 是一个基于 Vue.js 的通用应用框架。

通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染。

我们的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js。

Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。

除此之外,对我来说,其还内置了Element UI,以及可以自动配置路由,十分的方便。

使用

使用命令

  • npx create-nuxt-app 【项目名】使用 npm 创建

  • yarn create nuxt-app 【项目名】使用 yarn 创建

在创建过程中,使用 npm 一直无法成功创建,使用 yarn 可以成功创建

创建过程中,nuxt 会让我们在一些内容进行选择,按照自己喜好选择就好,生成项目结构如下:

这是最开始为我们创建的,除此之外,一些其他的内容:

  • assets:less、scss、JavaScript

  • layout:布局(相当于写一段内容,固定死)

路由

pages中index.vue就是页面总目录,就是当用户访问空的时候访问的页面。

在 pages 下新建user/index.vue,此时,当我们访问http://localhost:3000/user时,就会进入到当前页面,这是因为 nuxt 已经为我们配置好了这个路由,可以直接用。

路由传参

那如果是动态路由并且我们想进行传参呢?该如何做?

  • 如果我们想要进行传递参数,创建的文件以 _ 开头即可,如:我想创建商品详情页,并且以 商品id 作为params 传入,那么我只需要

  • 创建 goods/_id.vue即可

  • 使用<nuxt-link to="/goods/[商品id]">商品</nuxt-link>即可进行跳转

  • _id.vue中使用this.$route.params.id即可获取到当前id

模板

所谓模板,就是一个组件,在其中写死一些东西,emmm,不太直观,那看个例子,对于一个管理系统来说,左边的菜单组件,上方的title组件,这些是固定死的,不管在哪个页面都不会轻易改变。

这样,我们完全可以写一个模板,包含 tabbar 以及 menu,在原来我们的做法是,把这一切都写在vue的index.vue中,现在我们可以这样做:

  • 新建layouts文件夹,在此文件下新建manager.vue文件,在这个文件中,我们可以编写大的框架,想要在不同页面展示不同的内容,在这里我们使用<nuxt/>,这就相当于平时的<router-view/>

<template>
  <div class="manager">
    <!-- 这是头部导航栏 -->
    <div class="tabbar">
      <div id="logo">后台管理系统</div>
      <div class="icon-setting">
        <el-button icon="el-icon-search" circle type="primary" size="mini"></el-button>
        <el-button icon="el-icon-setting" circle type="primary" size="mini"></el-button>
      </div>
    </div>
    <div class="context">
      <div class="menu">
        <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
          :collapse="isCollapse">
          <el-submenu index="1">
            <template slot="title">
              <i class="el-icon-location"></i>
              <span slot="title">用户管理</span>
            </template>
            <el-menu-item-group>
              <span slot="title">商品管理</span>
              <el-menu-item index="1-1">选项1</el-menu-item>
              <el-menu-item index="1-2">选项2</el-menu-item>
            </el-menu-item-group>
            <el-menu-item-group title="分组2">
              <el-menu-item index="1-3">选项3</el-menu-item>
            </el-menu-item-group>
            <el-submenu index="1-4">
              <span slot="title">选项4</span>
              <el-menu-item index="1-4-1">选项1</el-menu-item>
            </el-submenu>
          </el-submenu>
          <el-menu-item index="2">
            <i class="el-icon-menu"></i>
            <span slot="title">订单管理</span>
          </el-menu-item>
          <el-menu-item index="4">
            <i class="el-icon-setting"></i>
            <span slot="title">设置</span>
          </el-menu-item>
        </el-menu>
      </div>
      <nuxt />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isCollapse: false
    };
  },
  methods: {
    handleOpen(key, keyPath) {
      console.log(key, keyPath);
    },
    handleClose(key, keyPath) {
      console.log(key, keyPath);
    }
  }
}
</script>
<style lang="less">
.tabbar {
  width: 100vw;
  height: @tabbar-height;
  padding: 5px 10px;
  display: flex;
  line-height: calc(@tabbar-height - 10px);
  font-size: @font-size-small;
  font-weight: 800;
  justify-content: space-between;
  background-color: rgb(0, 200, 255);
  .icon-setting {
    display: flex;
    justify-content: center;
    align-items: center;
  }
}

.manager {
  width: 100%;
  height: calc(100vh - @tabbar-height);
}

.menu {
  width: @menu-width;
  height: calc(100vh - @tabbar-height);
}

.context {
  display: flex
}
</style>
  • 然后只需要在使用这个模板的页面中export default中加上:layout: 'manager,这样这个模板应用于当前页面,在当前页面中写的所有内容都会被替换到上一点的<nuxt/>

全局错误模板

在页面中,当用户访问了一个不存在的路径,我们应当返回用户一个 404 字样,在 vue 中,我们在路由配置中设置一个全局重定向到404,在 nuxt 中,我们可以更简单的定义全局错误模板:

注意:虽然此文件放在 layouts 文件夹中,但应该把它看作为一个页面

  • layouts文件夹下新建error.vue文件,并在export default中使用props接受一个 error属性,这表明这个模板是一个全局错误模板,这个属性为 nuxt 内部进行传递,打印出来 error大概长这样:

{
    "statusCode": 404,
    "path": "/123",
    "message": "This page could not be found"
}
  • 所以我们可以通过 error.statusCode来判断当前的错误类型从而显示不同的内容

<template>
  <div class="container">
    <h1 v-if="error.statusCode === 404">
    </h1>
    <div class="notfind">
      <svg-icon svgName="404" width="400px" height="400px"></svg-icon>
      <h4>您访问的页面不存在!</h4>
    </div>
  </div>
</template>
  • 全局错误模板也是可以使用我们写好的额模板的,用法如上

样式

在 nuxt 中,可以使用less、scss等,在这里使用 less

  1. 安装 less:yarn add less less-loader

  2. 之后在项目中就可以使用 less 了

注意:

如果直接安装运行后可能会出现 this.getOption 错误之类的问题,这个问题是因为 less 版本高,不兼容,需要卸载重新安装,这里给一个参考:

在 less 中使用全局便令

如果想要在 less 使用全局变量,步骤如下:

  1. assets/css(没有则新建)下新建variables.less,这个文件用来放置全局样式变量

  2. nuxt.config.js中修改:

...
build: {
  ...
  styleResources: {
    less: './assets/css/variables.less'
  }
},
...
  1. 之后再less文件中使用即可

组件

在 nuxt 中,components组件即为全局组件,我们所有的全局组件都可以写在这里,同时 nuxt 将会自动为我们注册成全局组件,我们只需要使用即可。

<template>
  <div>
    <img :src="require(`~/assets/svg/${svgName}.svg`)" :style="{ width, height }" />
  </div>
</template>

<script lang='ts'>
import Vue from 'vue'
export default Vue.extend({
  name: 'SvgIcon',
  props: {
    width: {
      default: '200px',
      type: String
    },
    height: {
      default: "200px",
      type: String
    },
    svgName: {
      required: false,
      type: String,
    },
  }
})
</script>

使用:

<template>
  <div class="container">
    <h1 v-if="error.statusCode === 404">
    </h1>
    <div class="notfind">
      <!-- 直接使用即可 -->
      <svg-icon svgName="404" width="400px" height="400px"></svg-icon>
      <h4>您访问的页面不存在!</h4>
    </div>
  </div>
</template>

<script lang='ts'>
export default {
  props: ['error'],
  layout: 'manager',
}
</script>