浅聊NUXT

1,922 阅读4分钟

NUXT是什么

  • Nuxt.js 是一个基于 Vue.js 的通用应用框架,想了解NUXT就需要我们先了解一下客户端渲染和服务器端渲染的区别。

服务器端渲染

  • 客户端 ---> 访问url(请求)---> 服务器 ---> 查询数据库,拼接html字符串(模版)---> 返回客户端html

客户端渲染

  • 客户端 ---> 访问url(请求)---> 服务器 ---> 返回html(没有dom结构)---> 渲染html,js(vues),template ---> 向服务器要数据 ---> 返回json给客户端

生命周期概括

  • 众所周知,Vue的生命周期全都跑在客户端(浏览器),而Nuxt的生命周期有些在服务端(Node),客户端,甚至两边都在:

  • 生命周期流程图,红框内的是Nuxt的生命周期(运行在服务端),黄框内同时运行在服务端&&客户端上,绿框内则运行在客户端

各个生命周期应用

  • nuxtServerInit
    • 第一次进入页面会执行,可以把服务器获取到的信息(cookie/session)直接传给客户端
    • 其余生命周期,每次跳转页面都会执行
  • middleware
    • 看到页面之前,会先进入中间件中,这里面可以做一些鉴权和路由守卫
  • validate
    • 做校验,比如从页面A到页面B中,这里面可以校验A给B传过来的参数,如果不合法,就跳转到其他页面
  • asyncData() & fetch()
    • asyncData从后端获取数据之后进行渲染,fetch从后端获取数据之后往vuex里面填充
  • Render
    • 页面渲染出来,执行vue其他的生命周期。

创建项目

  • 运行create-nuxt-app
    npx create-nuxt-app <项目名>
    
  • 选择服务器:Koa
  • 运行项目:npm run dev

目录结构

  • assets:资源目录assets用于组织未编译的静态资源如:LESS,SASS,JavaScript
  • components:组件目录components用于组织应用的Vue.js组件。Nuxt.js不会扩展增强该目录下Vue.js组件,即这些组件不会像页面组件那样有asyncData方法的特性
  • layouts:布局目录layouts用于组织应用的布局组件
  • middleware:middleware目录用于存放应用的中间件
  • pages:页面目录pages用于组织应用的路由及视图。Nuxt.js框架读取该目录下所有的.vue文件并自动生成对应的路由配置
  • plugins:插件目录plugins用于组织那些需要在根vue.js应用实例化之前需要运行一次的JavaScript插件
  • static:静态文件目录static用于存放应用的静态文件,此类文件不会被Nuxt.js调用Webpack进行构建
  • Store:store目录用于组织应用的Vuex状态树文件,Nuxt.js框架集成了Vuex状态树的相关功能配置,在store目录下创建一个index.js文件可激活这些配置
  • nuxt.config.js:nuxt.config.js文件用于组织Nuxt.js应用的个性化配置,以便覆盖默认配置

路由

  • 路由生成

    • pages目录中所有 *.vue 文件自动生成应用的路由配置
    • 生成的路由通过.nuxt/router.js验证
  • 导航

    • 添加路由导航,layouts/default.vue
    <nav>
      <nuxt-link to="/">首页</nuxt-link>
      <!--别名:n-link,NLink,NuxtLink-->
      <NLink to="/admin">管理</NLink>
      <n-link to="/cart">购物车</n-link>
    </nav>
    
    • 禁用预加载: page not pre-fetched
  • 动态路由

    • 以下划线作为前缀的 .vue文件 或 目录会被定义为动态路由,如下面文件结构

    • 文件夹也可以加下划线去进行多个参数的匹配

      pages/
      --| detail/
      ----| _id.vue
      
    • 会生成如下路由配置:

      {
          path: '/detail/:id?',
          component: _9c2233e,
          name: 'detail-id'
      }
      
    • 如果detail/里面不存在index.vue,:id将被作为可选参数

  • 嵌套路由

    • 创建内嵌子路由,你需要添加一个 .vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
    • 构造文件结构如下
      pages/
      --| index/
      ----| _id.vue
      --| index.vue
      
    • 生成的路由配置如下:
      {
          path: '/index',
          component: 'pages/main.vue',
          children: [...]
      }
      
  • 视图

中间件

  • 中间件会在一个页面或一组页面渲染之前运行我们定义的函数,常用于权限控制、校验等任务。
  • 范例代码:管理员页面保护,创建middleware/auth.js
export default function({ route, redirect, store }) {
    // 上下文中通过store访问vuex中的全局状态
    // 通过vuex中令牌存在与否判断是否登录,没登录重定向到login页面
    if (!store.state.user.token) {
        redirect("/login?redirect="+route.path);
    }
}
  • 注册中间件,admin.vue
  <script>
    export default {
       middleware: ['auth']
    }
  </script>

vuex

  • 应用根目录下如果存在store目录,Nuxt.js将启用vuex状态树。定义各状态树时具名导出state, mutations, getters, actions即可。

插件

  • Nuxt.js会在运行应用之前执行插件函数,需要引入或设置Vue插件、自定义模块和第三方模块时特别有用。

  • 代码

    import Vue from 'vue'
    import VueLazyload from 'vue-lazyload'
    
    Vue.use(VueLazyload)
    
  • 注册插件,nuxt.config.js

    • 不支持ssr的系统,插件只在浏览器里使用,这种情况下下,你可以用 ssr: false ,使得插件只会在客户端运行。
    plugins: [
      { src: '~plugins/vue-lazyload', ssr: true }
    ]
    

    nuxtServerInit

    • 通过在store的根模块中定义 nuxtServerInit 方法,将服务端的一些数据传到客户端。
    • 登录代码
      export const actions = {
          // nuxtServerInit必须声明在根模块
          nuxtServerInit({ commit }, { app }) {
              const token = app.$cookies.get("token");
              if (token) {
                  console.log("nuxtServerInit: token:"+token);
                  commit("user/SET_TOKEN", token);
              }
          }
      }