先从目录结构上介绍

1 layout文件夹

放的是布局组件,理解成一个.vue文件,里面有slot,页面用的时候嵌套
但是nuxt使用就不用,只要在页面那里配置一个layout:'这个名字是vue文件的名字,不是name'

例子
image.png
page在用的时候

<template>
  <div>
    <div>这里输出中间内容部分</div>
    <gaogezujian></gaogezujian>
  </div>
</template>

<script>
export default {
  name: 'home',
  layout: 'demo', // 这个是vue文件名,不是name值
  data() {
    return {
      
    };
  },

  mounted() {
    
  },

  methods: {
    
  },
};
</script>

<style lang="scss" scoped>

</style>

2 components文件夹

里面是组件,就是vue的那种,自动全局注册了,在nuxt.config配置,components:true
用的时候
image.png
注意也是文件名,不是name的值

3 middleware文件夹

里面是放一些会全局作用的js方法之类,可以类比为router路由的before,after那些钩子,它是有一个执行顺序
也可以作用页面,组件,在里面写一个属性

export default {
  name: 'MynuxtssrFa',
  middleware: 'fa',
  data() {
    return {
      
    };
  },

1 nuxt.config.js
2 匹配的布局
3 匹配的页面

export default () => {
  return new Promise((res,rej) => {
    console.log('请求接口中')
    
    setTimeout(() => {
      console.log('5秒后')
      res()
    },5000)
  })
}

导出一个函数,里面请求接口,res之后才会进入页面,跟vue的路由拦截是一摸一样的

写了后还要配置,在nuxt.config

router: {
    middleware: 'auth',
  },

然后它函数参数那里有几个值,比如

export default ({ app, $axios, store, error, redirect, req }) => {
  return new Promise((res,rej) => {
    console.log('请求接口中')
    
    setTimeout(() => {
      console.log('5秒后')
      res()
    },5000)
  })
}

这个值的参考,网上查了下,要看.nuxt文件夹(这个后面再说这个是啥,现在看起来像打包后的文件,也就是说,它的run dev开发模式是每更新代码,它都会打包一次)的indexjs

await setContext(app, {
    route,
    next,
    error: app.nuxt.error.bind(app),
    payload: ssrContext ? ssrContext.payload : undefined,
    req: ssrContext ? ssrContext.req : undefined,
    res: ssrContext ? ssrContext.res : undefined,
    beforeRenderFns: ssrContext ? ssrContext.beforeRenderFns : undefined,
    ssrContext
  })

还有一些没加在这里的,都是在某些的地方加上去,所以这里没有一个全的,比如$axios,redirect

4 pages

顾名思义,页面,nuxt机制会自动帮你把文件夹下面的文件都写进router里面, 可以在.nuxt文件夹看的出来,下面说一下某些写法

嵌套路由

如何搞一个有children那种的,要这样
image.png
要用一个跟文件夹同名的vue文件,比如截图那个fa,这样生成出来的router长这样
image.png
然后就正常在父组件写一个出口,用他封装的<nuxt-child></nuxt-child>,跟vue的router-view一样

<template>
  <div>
    <p>嵌套路由父</p>
    <nuxt-child></nuxt-child>
  </div>
</template>

但是可以看到,router那里没有redirect,网上找了下,建议这样写

export default {
  name: 'MynuxtssrFa',
  middleware: 'fa',
  asyncData({ redirect,route }) {
    if(route.fullPath  === '/fa'){
      redirect('/fa/child1')
    }
  },
  data() {
    return {
      
    };
  },

这个asyncDatap优先级在中间件后面,注意,一定要加个路由的判断,不然你跳不到其他子路由
你也可以用中间件来实现,效果一样

5 plugins

6 生命周期

asyncData 和 Fetch 的区别

asyncData

async asyncData() {
    console.log('2秒开始')
    await new Promise((resolve, reject) => {
      const tt = 2000
      // eslint-disable-next-line nuxt/no-timing-in-fetch-data
      setTimeout(() => {
        resolve()
      }, tt)
    })
    console.log('2秒结束')
    // 注意这里,会合并到data里面
    return { myName: '用asyncData的名字' }
  },

无论是用a标签,还是router.push,它的执行顺序都是这样
image.png

注意点:

  1. 只能在page页面里面用,components不行
  2. 从执行顺序可以看出,它是组件实例化之前就调用了
  3. 通过return合并到组件的data属性

fetch

async fetch() {
    console.log('2秒开始')
    await new Promise((resolve, reject) => {
      const tt = 2000
      // eslint-disable-next-line nuxt/no-timing-in-fetch-data
      setTimeout(() => {
        resolve()
      }, tt)
    })
    console.log('2秒结束.')
    this.myName = '用fetch的名字'
  },

这个顺序有不同,如果是服务端渲染
image.png

如果是客户端渲染
image.png

这里看清楚,fetch如果是客户端渲染,mounted是不会等它的,所以如果你有逻辑是一定要拿到数据后,再初始化mounted,要自己额外处理

注意点:

  1. 都能用,无论是page,还是components
  2. 它在created后才执行,所以能拿this
  3. 直接this.data改属性,这说明你也需要先在data里声明

最后再说一句,个人对服务端,客户端渲染的时机理解
如果是第一次在浏览器的url输入地址,或者是新打开窗口,那一定是服务端渲染,就是network那里能看到doc的资源请求
如果已经进来了,无论你再用什么方式跳转,都是走的客户端渲染模式,就是network看不到doc资源请求
或者根本不是,是因为现在项目是单页的性质?


bug之所措
406 声望13 粉丝