服务端预衬着之Nuxt(路由篇)

效劳端预衬着之Nuxt – 运用

如今大多数开辟都是基于Vue或许React开辟的,能够到达疾速开辟的效果,也有一些不足的处所,Nuxt能够在效劳端做出衬着,然后让搜索引擎在爬取数据的时刻能够读到当前页面。

起首要申明一点,我们能够以为我们所编写的Vue项目是一个效劳端的项目,虽然编写的照样Vue项目,然则Nuxt是基于效劳器环境的。

就简朴的说一下Nuxt运用。基本只是照样以官方文档为主,假如博客中那里有题目,迎接留言斧正。

说了这么多,进入正题。

路由

与传统的Vue项目差别的是,我们在运用Vue的时刻须要设置Vue-Router信息,在Nuxt有很症结的一点就是商定优于设置page目次下的一切*.vue文件会自动天生路由设置。

在项目初始化以后,在pages下面默许有一个index.vue文件,所以当我们运用npm run dev启动项目,而且运用http://localhost:3000/接见的时刻能够一般接见路由。

为了证明上面这一点,在pages下面建立一个信息about.vue文件,而且http://localhost:3000/about去接见方才写的页面。我们能够依据一般的Vue页面去开辟就好了。

page目次

├─page
│   ├─index.vue
└───└─about.vue

about.vue

<template>
  <div>
      <h2>This About</h2>
  </div>
</template>

建立完成以后运用http://localhost:3000/about接见该页面,页面能够一般的衬着出来了。就会看到This About显现在页面中。

做到这一步以后就应当完成路由之间的跳转了。Vue开辟历程当中,都是运用router-link标签完成路由之间的跳转,在Nuxt也一样能够运用router-link,然则Nuxt依旧引荐运用nuxt-link,nuxt-linkrouter-link的功用是等效的。

能够会有一些疑问,既然是等效的,为何要运用nuxt-link呢?官方文档中是如许说的:未来我们会为nuxt-link组件增添更多的功用特征,比方资本预加载,用于提拔nuxt.js运用的响应速度。显著嘛,官方不会平白无故的就做出这么一个东西来,肯定着实个中做了许多的优化事变的。

轻微的修改一下适才的about.vue在里面增加两个标签,一个运用nuxt-link,一个运用router-link看下可否一般完成跳转。

about.vue – 更改后

<template>
  <div>
      <h2>This About</h2>
      <nuxt-link to="/">首页</nuxt-link>
      <router-link to="/">首页</router-link>
  </div>
</template>

既然从路由最先那末就不得不说到子路由,全局路由守御这些都些在路由中经常用到的应当怎样处置惩罚?该怎样处理这些题目。

前面既然说到了Nuxt会把pages文件夹下面的一切*.vue文件编译成路由,那末子路由须要运用文件夹嵌套才行。

接下来就尝试一下。起首要更改一下pgeas目次构造。

page目次

├─page
│   ├─about
│   │  ├─detail.vue
│   │  └─index.vue
└───└─index.vue

注重上面的about目次,是index.vue而并不是about.vue,这里的index.vue指的是about路由下的首页,也就是最最先放在与index.vue同级的谁人about.vue是一样的效果。

about/index.vue

<template>
  <div>
      <h2>This About</h2>
      <nuxt-link to="/">首页</nuxt-link>
      <router-link to="/">首页</router-link>
  </div>
</template>

about/detail.vue

<template>
  <div>
    <h2>This Detail</h2>
  </div>
</template>

如今假如我们想要接见适才的那两个路由地点离别就是http://localhost:3000/abouthttp://localhost:3000/about/detail就可以看到适才编写的page页面了。

假如想要看路由天生究竟是什么模样的?能够在根目次下有一个.nuxt文件夹,在里面能够看到一个router.js,这个文件夹下面就是Nuex天生好的路由信息。

翻开文件后翻到末了会有一段如许的代码,是否是很眼熟?这是不就是在编写Vue项目的时刻设置的哪些路由文件么?

router.js

export function createRouter() {
  return new Router({
    mode: 'history',
    base: decodeURI('/'),
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,
    routes: [{
      path: "/about",
      component: _9ceb4424,
      name: "about"
    }, {
      path: "/about/detail",
      component: _18146f65,
      name: "about-detail"
    }, {
      path: "/",
      component: _d3bf5a4e,
      name: "index"
    }],
    fallback: false
  })
}

有了这个文件的话我们就可以够清晰的晓得,路由的构造了。不单单议如许,还能够运用name去完成路由的跳转了。

须要注重的是,假如你的路由是有文件夹嵌套的话,Nuxt是用运用-来拼接路由的name称号的(如:about-detail),然则文件夹内部的index.vue会直接已文件夹的名字作为name。一旦晓得了路由的name,如许我们就可以够运用敕令的体式格局跳转路由了。

再次更改一下about/index.vue

about/index.vue

<template>
  <div>
      <h2>This About</h2>
      <nuxt-link :to="{name:'about-detail'}">概况</nuxt-link>
      <router-link :to="{name:'index'}">首页</router-link>
      <button @click="onClick">跳转到概况</button>
  </div>
</template>
<script>
export default {
  methods: {
    onClick() {
      this.$router.push({name:"about-detail"})
    }
  }
}
</script>

运用路由接见http://localhost:3000/about地点,离别点击概况、首页与button,都是能够一般跳转的,与之前的Vue开辟是完整没有任何辨别的。在vue-router中有一个很主要的一个点就是动态路由的观点,假如想要完成动态路由应当怎样处置惩罚呢?

假如想要在Nuxt中运用动态路由的话,须要在对应的路由下面增加一个_参数名.vue的文件,在about文件下面增加一个_id.vue

page目次

├─page
│   ├─about
│   │  ├─detail.vue
│   │  ├─_id.vue
│   │  └─index.vue
└───└─index.vue

新建完成以后在去router.js中看一下更改后的路由构造

export function createRouter() {
  return new Router({
    mode: 'history',
    base: decodeURI('/'),
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,
    routes: [{
      path: "/about",
      component: _9ceb4424,
      name: "about"
    }, {
      path: "/about/detail",
      component: _18146f65,
      name: "about-detail"
    }, {
      path: "/about/:id",
      component: _6b59f854,
      name: "about-id"
    }, {
      path: "/",
      component: _d3bf5a4e,
      name: "index"
    }],
    fallback: false
  })
}

能够显著的看到在/about/:id这个路由,显著的变化不止这些更改的另有name: "about-id"不再是之前的name:about了。假如想要运用这个id的话必须在_id.vue中才猎取到。

_id.vue

<template>
  <div>
    {{$route.params.name}}
    {{$route.params.id}}
  </div>
</template>

_id.vue中编写以上代码并运用http://localhost:3000/about/ABC,能够看到在页面中已展现了当前的id值。

在现实开辟历程当中能够params能够会有多个参数,又应当怎样处置惩罚呢?

调解目次构造

//  id为可选参数
├─page
│   ├─about
│   │  ├─_name
|   |  |    └─_id
|   |  |        └─index.vue
│   │  └─index.vue
└───└─index.vue

about – _name – _id.vue

<template>
  <div>
    {{$route.params.name}}
    {{$route.params.id}}
  </div>
</template>

弄完以后看下router.js的变化

export function createRouter() {
  return new Router({
    mode: 'history',
    base: decodeURI('/'),
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,
    routes: [{
      path: "/about",
      component: _9ceb4424,
      name: "about"
    }, {
      path: "/about/detail",
      component: _18146f65,
      name: "about-detail"
    }, {
      path: "/about/:name",
      component: _2ec9f53c,
      name: "about-name"
    }, {
      path: "/about/:name/:id",
      component: _318c16a4,
      name: "about-name-id"
    }, {
      path: "/",
      component: _d3bf5a4e,
      name: "index"
    }],
    fallback: false
  })
}

这里展现的是第二种状况,id为必选参数的状况,路由被编译的效果。

虽然路由已增加了参数,然则id属性不是必填属性,如许的话不能满足项目需求又要怎样处置惩罚呢?很简朴的,在_id.vue文件同目次下增加一个index.vue文件就可以够了。

//  id为必选参数
├─page
│   ├─about
│   │  ├─_name
|   |  |    ├─_id.vue
|   |  |    └─index.vue
│   │  └─index.vue
└───└─index.vue

须要注重的是,肯定要在_id.vue文件中运用传入的参数,直接猎取在index.vue中是拿不到任何信息的。然则假如接见http://localhost:3000/about/ABC如许的路由的话,着实index.vue中是能够猎取到name参数的。

在适才的router.js文件中天生的一切的路由都是平级的,怎样完成路由的嵌套,假如想要完成嵌套路由的话,必须有和当前路由同名的文件夹存在,才完成路由的嵌套。

page目次

├─page
│   ├─about
|   |  ├─_id.vue
|   |  └─detaile.vue
│   ├─about.vue
└───└─index.vue

router.js

export function createRouter() {
  return new Router({
    mode: 'history',
    base: decodeURI('/'),
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,
    routes: [{
      path: "/about",
      component: _76687814,
      children: [{
        path: "",
        component: _9ceb4424,
        name: "about"
      }, {
        path: ":id",
        component: _6b59f854,
        name: "about-id"
      }]
    }, {
     path: "/",
      component: _d3bf5a4e,
      name: "index"
    }],
    fallback: false
  })
}

更改完目次构造,那我们嵌套的路由应当怎样展现?在vue.js中开辟的时刻运用router-view这个标签完成的。为了机能的优化Nuxt也供应了一个对应的标签nuxt-child

假如想完成嵌套路由传参须要轻微的修改一下目次构造,依据上面的要领完成就好了,下面是一个路由构造的例子。

page目次

├─page
│   ├─about
│   │  ├─detail
|   |  |    ├─_id.vue
|   |  |    └─index.vue
│   │  └─index.vue
└───└─index.vue

router.js

export function createRouter() {
  return new Router({
    mode: 'history',
    base: decodeURI('/'),
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,
    routes: [{
      path: "/about",
      component: _76687814,
      name: "about",
      children: [{
        path: "detail",
        component: _0a09b97d,
        name: "about-detail"
      }, {
        path: "detail/:id?",
        component: _fa7c11b6,
        name: "about-detail-id"
      }]
    }, {
      path: "/",
      component: _d3bf5a4e,
      name: "index"
    }],
    fallback: false
  })
}

_id.vue中则能够运用id这个参数了。接见路由http://localhost:3000/about/detail/123,依旧能够拿到传入的id123的这个参数。

说了这么多了,另有许多题目没得说完,关于路由的全局守御又应当怎样去运用?在Nuxt根目次下有个plugins文件夹。起首要做的是在里面建立一个名为router.js文件。

plugins-router.js

export default ({app}) => {
  app.router.beforeEach((to,form,next) => {
    console.log(to)
    next();
  });
}

导出了一个函数,在这个函数中能够经由过程构造拿到vue的实例对象名叫app。须要注重的是,这个beforeEach函数的实行,有能够会在效劳端也会有能够在客户端输出。客户端首次接见的页面会在效劳端做输出,一旦衬着完成以后,则不会再在效劳端输出,则会一直在客户端举行输出了。

说到这里做个小插曲,那末又该怎样辨别当前是在客户端环境照样效劳端环境呢?能够运用process.server猎取到当前的运转环境,其获得的是Boolean值,true效劳端,fasle客户端。

做了这些以后去接见路由,似乎没有任何输出,不管着实客户端照样在效劳端,都没有任何打印输出,中心缺少了步骤,须要在根目次下找到nuxt.config.js对插件举行设置。

nuxt.config.js

const pkg = require('./package')
module.exports = {
  plugins: [
    '@/plugins/element-ui',
    '@/plugins/router'
  ]
}

因为更改了Nuxt设置须要重启一下效劳,才一般实行方才写入的插件。然后接见方才写入的路由,会看在效劳端首次衬着的时刻,会输出我们想要的那些东西,举行路由跳转的话,会在客户端输出,这也就证明了Nuxt只会做首屏的效劳器衬着。

路由说了这么接下来须要说一下Nuxt是怎样为指定的路由设置数据做衬着的。实在Nuxt在做衬着的时刻包裹了许多层。起首有一个Document作为其模板,然后再去寻觅其规划的页面,找到对应的页面以后,再依据援用去找到相干的组件举行衬着,数据要求与数据挂载,一系列完成以后,把盈余的路由信息返还给客户端,衬着完成,这个就是Nuxt简朴的衬着流程。

在上面提到了一个规划页面,这个东西应当去那里找?又应当怎样做呢?它关于项目而言关于开辟又有什么优点?在Nuxt根目次下有一个layouts文件夹,下面有一个default.vue这个文件就是上面提到的衬着页面,也就同即是vue开辟中的App.vue,在这里能够做许多事变。比方增加一个全局的导航。

layouts文件夹增加一个about.vue文件写入以下内容,接下来须要在pages下面的about.vue中关照,对应pages运用哪一个规划页面,不写则运用默许,然后接见http://localhost:3000/about相干的页面,只如果和about相干的页面,都邑展现这个内容。

layouts – about.vue

<template>
  <div>
    <h2>Aaron 个人博客主页</h2>
    <nuxt></nuxt>
  </div>
</template>

pages – about.vue

<template>
  <div>
      <h2>About</h2>
      <nuxt-child></nuxt-child>
  </div>
</template>
<script>
export default {
  layout:"about"
}
</script>

接见一下一切与about页面有关的页面,都邑看到Aaron个人博客主页这个字样,若接见根路由则没法看到的。

假如做过mvc开辟的话,假如页面发作毛病解跳转到一个毛病页面的。Nuxt也是有默许的毛病页面的,然则满是英文而且款式也不太悦目,不能自定义款式。怎样自定义毛病页面呢?

layouts文件夹中新建一个error.vue文件。

layouts – error.vue

<template>
  <div>
    <h1>这里是毛病页面</h1>
    <h2 v-if="error.statusCode == 404">404 - 页面不存在</h2>
    <h2 v-else>500 - 效劳器毛病</h2>
    <ul>
        <li><nuxt-link to="/">HOME</nuxt-link></li>
    </ul>
  </div>
</template>

<script>
export default {
  props:["error"]
}
</script>

error.vue中能够经由过程props拿到一个error对象,猎取到error毛病信息以后能做任何想要做的事变。须要注重的一点是,自定意的毛病页面,只能在客户端接见失效的时刻才会响应到该页面,若在效劳端的话,是没法直接衬着这个页面的。

更改页面设置Nuxt中有些全局的设置,设置信息在nuxt.config.js更改其全局设置,pages文件夹中的*.vue文件也是能够设置的,页面私有的设置会覆蓋掉全局的设置。

举例:

export default {
  layout:"about",
  head: {
    title:"About"
  }
}

在这些全局设置中最主要的一个就是asyncData这个属性。asyncData究竟是用来做什么的呢?这个数据能够在设置组件的数据之前能一步猎取或许处置惩罚数据。也就是说在组件衬着之前先猎取到数据,然后守候挂载衬着。

举个例子:

<template>
  <div>
      <h2>姓名:{{userInfo.name}}</h2>
      <h2>岁数:{{userInfo.age}}</h2>
      <nuxt-child></nuxt-child>
  </div>
</template>
<script>
let getUserInfo = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      let data = {"name":"Aaron","age":18};
      resolve(data);
    })
  })
}
export default {
  layout:"about",
  head: {
    title:"About"
  },
  async asyncData(){
    const userInfo = await getUserInfo();
    return {userInfo}
  }
}
</script>

肯定要return出去猎取到的对象,如许就可以够在组件中运用,这里返回的数据会和组件中的data兼并。这个函数不光在效劳端会实行,在客户端一样也会实行。

注重事项:

  1. asyncData 要领会在组件(限于页面组件)每次加载之前被挪用
  2. asyncData 能够在效劳端或路由更新之前被挪用
  3. 第一个参数被设定为当前页面的上下文对象
  4. Nuxt会将 asyncData 返回的数据融合到组件的data要领返回的数据一并返回给组件运用
  5. 关于 asyncData 体式格局着实组件初始化前被挪用的,所以在要领内饰没办法经由过程this来援用组件的实例对象

方才提到了一点就是上下问对象,在上线文对象中能够猎取到许多东西,如路由参数,毛病信息等等等,这里就不作太多赘述了,有了这些能够做一些页面的重定向或许其他事变,比方参数校验,平安考证等事变。

路由扯了一大堆,接下来讲一下怎样在Nuxt中融入axios的运用。

装置axios

npm install @nuxtjs/axios --save-dev

装置完成后更改设置信息:

nuxt.config.js

module.exports = {
    modules: [
        // Doc: https://axios.nuxtjs.org/usage
        '@nuxtjs/axios',
    ],
    axios: {
        proxy:true  //  代办
    },
    proxy: {
        "/api/":"http://localhost:3001/"    //  key(路由前缀):value(代办地点)
    }
}

主要说名一下proxy这里,/api/在要求的时刻碰到此前缀则会只指向的代办地点去要求数据。

既然说到了axios,就不得不提到的一个东西就是拦截器,非常有用在项目开辟历程当中必不可少的。

举个例子:

module.expores{
  plugins: [
    '@/plugins/axios'
  ],
  modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
  ],
}

plugins/axios.js

export default ({ $axios, redirect }) => {
  $axios.onRequest(config => {
    console.log('Making request to ' + config.url)
  })

  $axios.onError(error => {
    const code = parseInt(error.response && error.response.status)
    if (code === 400) {
      redirect('/400')
    }
  })
}

总结

说了这么多或许会有些马虎,或许脱漏的知识点,如有什么毛病的处所能够在下方留言,尽快做出纠正。感谢人人消费这么长时间浏览这篇文章。

    原文作者:Aaron
    原文地址: https://segmentfault.com/a/1190000018784715
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞