Nuxt快速入门

目录

1.概述

什么是 CSR ?

什么是 SSR ?

2.项目结构

3.生命周期

nuxtServerInit

middleware

validate

asyncData & fetch

render

beforeCreate & created

mounted & updated

没有keep-alive

不存在Window

4.路由

4.1约定式路由

4.2扩展路由

4.3路由守卫

4.4插件全局守卫

5.数据交互

6.全局请求拦截器


1.概述

nuxt是一个SSR服务器端渲染技术。

什么是 CSR ?

CSR => client-side-render,即客户端渲染。具体过程如下:

  • 用户请求页面,返回页面。此时页面只是模版页面
  • 浏览器解析页面代码,读到js代码时,会根据我们所写的接口去请求数据
  • 得到返回数据后使用模版(vue/react/ng/art-template)进行渲染

什么是 SSR ?

SSR => server-side-render,即服务器端渲染。具体过程如下:

  • 用户请求页面
  • 后端取到准备好的数据,渲染到我们自己写的服务器模版(next/nuxt/ejs)中,准备好html结构与相应数据后返回给浏览器

2.项目结构

  • assets: 资源文件。放置需要经过 webpack 打包处理的资源文件,如 scss,图片,字体等。
  • components: vue组件。这里存放在页面中,可以复用的组件,不支持服务器端的钩子。
  • layouts: 布局。页面都需要有一个布局,默认为 default。它规定了一个页面如何布局页面。所有页面都会加载在布局页面中的 <nuxt /> 标签中。如果需要在普通页面中使用下级路由,则需要在页面中添加 <nuxt-child />。该目录名为Nuxt.js保留的,不可更改。在 layout 中我们可以放入一些每个页面都会以用到的组件,比如 header & footer。当然如果你不想使用已生成的 layout 组件,你可以重新创建一个,比如 blank.vue 一般不需要引入 header&footer 的页面可以使用 blank.vue 这个 layout 组件。代码如下:
  • layout: 'blank'
  • middleware: 中间件。存放中间件。可以在页面中调用: middleware: 'middlewareName' 。
  • pages: 页面。一个 vue 文件即为一个页面。index.vue 为根页面。
    • 若需要二级页面,则添加文件夹即可。
    • 如果页面的名称类似于 _id.vue (以 _ 开头),则为动态路由页面,_ 后为匹配的变量(params)。
    • 若变量是必须的,则在文件夹下建立空文件 index.vue。更多的配置请移步至 官网
  • plugin: 插件。用于组织和配置,那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件,需要配合nuxt.config.js
  • static: 静态文件。放置不需要经过 webpack 打包的静态资源。如一些 js, css 库。
  • store: Nuxt.js 框架集成了 Vuex 状态树 的相关功能配置,在 store 目录下创建一个 index.js 文件可激活这些配置。
  • nuxt.config.js: nuxt.config.js 文件用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置。

3.生命周期

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

红框内的是Nuxt的生命周期首次运行在服务端,之后运行在vue组件创建之前,黄框内同时运行在服务端&&客户端上,绿框内则运行在客户端 .

nuxtServerInit

请求先到达 nuxtServerInit 方法,图中也表明了适用场景是对 store 操作,函数仅在每个服务器端渲染中运行 且运行一次,只能定义在store的主模板当中

// store/index.js

export const actions = {
  nuxtServerInit(store, {app:{$cookies},route,$axios,req,res,redirect}) {

    let user = $cookies.get('user') ? $cookies.get('user') : {err:2,msg:'未登录',token:''};
    // store.dispatch('user/A_UPDATE_USER',user)  user== store/user.js
    store.commit('user/M_UPDATE_USER',user)
  }
}

middleware

下来请求到达 middleware ,允许您定义一个自定义函数运行在一个页面或一组页面渲染之前。可以运行在全局,或者某个页面组件之前,不会在components组件内部运行

//middleware/auth.js
export default ({app:{$cookies},store,redirect,route,$axios,params,query,req,res})=>{

}

//nuxt.conig.js
router: {
  middleware: 'auth' //全局守卫 运行一组页面渲染之前
}

//layouts/a.vue  运行在一个布局之前
middleware(){..}, //定义在内部
middleware:'auth', //定义在外部

  //pages/a.vue  运行在一个页面之前
  middleware(){..}, //定义在内部
middleware:'auth', //定义在外部

  //中间件执行流程顺序:
  //nuxt.config.js->匹配布局->匹配页面

validate

下来请求到达 validate 方法,在这里可以对 page 组件 component 组件 进行动态路参数的有效性。返回 true 说明路由有效,则进入路由页面。返回不是 true 则显示 404 页面。

只能在页面组件使用(pages/xx.vue)

validate({ params, query }) {//参数校验,校验失败,则自动跳转到错误页面
  // return /^d+$/.test(params.id) // must be number
  return true;//true、false跳转方向
}

asyncData & fetch

接下来达到 asyncData & fetch 方法,asyncData() 适用于在渲染组件前获取异步数据,返回数据后合并到data选项内部,fetch() 适用于在渲染页面前填充 vuex 中维护的数据。会在组件每次加载前被调用(在服务端或切换至目标路由之前),由于是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。

只能在页面组件使用

//pages/a.vue
async asyncData(context){//页面组件数据预载 需要return 之后会和页面data合并
  let res = await context.$axios({url:'/api/goods/home'})
  return {msg2:'oo',data:res.data}//组件数据 异步的,初始的都在这里生成
}

asyncData ({ params }) {
  return axios.get(`https://my-api/posts/${params.id}`)
    .then((res) => {
      return { title: res.data.title }
    })
}

//将数据提交给vuex
async fetch(context){
  let res = await context.$axios({url:'/api/goods/home'})
  context.store.commit('XXX',res.data);//状态操作
}

render

最后进行渲染。将渲染后的页面返回给浏览器,用户在页面进行操作,如果再次请求新的页面,此时只会回到生命周期中的 middlerware 中,而非 nuxtServerInit ,所以如果不同页面间需要操作相同的数据请用 vuex 来维护,render钩子只能定义渲染时的配置,render内部不可以有业务逻辑,也不执行

beforeCreate & created

运行在服务端 & 客户端,可以获取到组件this,

mounted & updated

运行在客户端,没有keep-alive 那自然activated、deactivated这两个生命周期也没了

没有keep-alive

由于是服务端渲染,所以不支持组件的keep-alive,那自然activated、deactivated这两个生命周期也没了

不存在Window

<script>
export default {
  asyncData() {
    console.log(window) // 服务端报错
  },
  fetch() {
    console.log(window) // 服务端报错
  },
  created () {
    console.log(window) // undefined
  },
  mounted () {
    console.log(window) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
  }
}
</script>

4.路由

4.1约定式路由

展示区: <nuxt></nuxt>

声明式跳转

<li><nuxt-link :to="{name:'shop-comment-uid',query:{a:2,b:3},params:{uid:2}}">评论2</nuxt-link></li>
  • name(路由名):目录名-其他目录-文件名
  • params(路由参数):要对等文件名
  • query(参数):携带的参数

子路由:目录代表子路由,子路由内部同级的文件,代表是同级一级路由

4.2扩展路由

在nuxt.config.js中的router配置中添加extendRoutes函数

  router:{
    middleware:'auth',
    //扩展路由,访问/index时访问pages/index.vue
    //__dirname魔术变量:表示当前文件位置
    extendRoutes(routes,resolve){
      routes.push({
        name:'root',
        path:'/index',
        component:resolve(__dirname,'pages/index.vue')
      })
    }
  },

4.3路由守卫

前置:依赖中间件middleware插件

  • 全局守卫:nuxt.config指向middleware
  • 组件独享守卫:middleware,插件全局守卫

后置:使用Vue的beforeRouteLeave钩子

export default ({store,route,redirect,params,query,req,res})=>{
  //context 服务端上下文
  //全局守卫业务
  //store状态树信息
  //route 当前路由信息
  //redirect 强制跳转
  //params ,query校验参数合理性
  console.log('middleware nuxt.config outside')
}

<template>
  <div class="container">
    <h1>首页</h1>
  </div>
</template>

<script>

export default {

  // SSR
  // middleware:'auth'
  middleware({store,route,redirect,params,query,req,res}){
     //context 服务端上下文
  //组件独享守卫业务
  //store状态树信息
  //route 当前路由信息
  //redirect 强制跳转
  //params ,query校验参数合理性
  console.log('middleware nuxt.config outside')
  },

4.4插件全局守卫

配置全局:通过在nuxt.config中plugins去定义一个插件,nuxt会自动调用指定文件函数

export default ({ app, redirect,store,params,query, }) => {
  //ap//redirect 强制跳转p=vue实例
  //redirect 强制跳转
  app.router.beforEach(to,from,next)=>{
    //全局前置的守卫,插件
    //next()
  }
  
//配置全局后置守卫
  app.router.afterEach(to,from)=>{
    
  }
};

配置组件独享后置守卫:在组件中配置

<template>
  <div class="container">
    <h1>祖册</h1>
  </div>
</template>

<script>

export default {
  beforeRouteLeave(to,from,netx){
    let bl =window.confirm('是否要离开');
    next(bl);
  }

  },

5.数据交互

安装:@nuxtjs/axios,@nuxt/proxy

next.config配置

modules:['@nuxtjs/axios']
//跨域配置
axios:{
    proxy:true,//开启axios跨域
    prefix: 'api', //beaseUrl
},
proxy:{
  '/api/':{
    target: 'http:/xxx', //代理地址
    changeOrigin: true,
    pathRewritte:{
      ^/api: ''
    }
  }
}

6.全局请求拦截器

在nuxt.config的plugins中添加配置文件

export default function ({ $axios, redirect }) {
  /**
   * --------------------------------------------
   * 应用程序请求拦截
   * --------------------------------------------
   */
  $axios.onRequest((config) => {
    return config;
  });
 /**
   * --------------------------------------------
   * 应用程序响应拦截
   * --------------------------------------------
   */
  $axios.onResponse((response) => {
    return (response = response.data);
  });

  /**
   * --------------------------------------------
   * 拦截未登录错误
   * --------------------------------------------
   */
  $axios.onError((error) => {
    const code = parseInt(error.response && error.response.status);
    if (code === 401) {
      // redirect("/login");
    }
  });
}
  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值