1.NUXT是什么?

Nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染)。
首先说下 SSR,最近很热的词,意为 Server Side Rendering(服务端渲染),目的是为了解决单页面应用的 SEO 的问题,对于一般网站影响不大,但是对于论坛类,内容类网站来说是致命的,搜索引擎无法抓取页面相关内容,也就是用户搜不到此网站的相关信息。

SSR 还适用以下场景

1、客户端的网络比较慢

2、客户端运行在老的或者直接没有 JavaScript 引擎上

2.NUXT为什么?

vue开发的SPA(单页应用)不利于搜索引擎的SEO优化。

3.NUXT适用于:

Nuxt.js适合作新闻、博客、电影、咨询等需要搜索引擎提供流量的项目。

4.NUXT优点:

基于 Vue.js
自动代码分层
服务端渲染
强大的路由功能,支持异步数据
静态文件服务
ES6/ES7 语法支持
打包和压缩 JS 和 CSS
HTML头部标签管理
本地开发支持热加载
集成ESLint
支持各种样式预处理器: SASS、LESS、 Stylus等

安装流程
Nuxt.js 团队提供了 vue-cli 的初始化模板。前提安装 vue-cli,安装过的忽略此步
 

npm install -g vue-cli

完成后在需要创建的目录下执行以下

vue init nuxt/starter <project-name>
cd <project-name>
npm install

依赖安装完成后

npm run dev

 

打开浏览器 http://localhost:3000

目录结构
完成上面命令后你的目录结构会如下

文件的路径建议都采用绝对路径,表格如下

例:怎么在 /pages/user/me.vue 引入一个 static 文件夹里的图片

<img src="~static/img/logo.png" alt="Logo"/>

 

路由

Nuxt.js 根据 pages 目录结构去生成 vue-router 配置,也就是说 pages 目录的结构直接影响路由结构

例1:

 

|-- pages
    |-- posts
        |-- index.vue
        |-- welcome.vue
    |-- about.vue
    |-- index.vue

 会生成

routes: [
  {
    path: '/posts',
    component: '~pages/posts/index.vue'
  }, {
    path: '/posts/welcome',
    component: '~pages/posts/welcome.vue'
  }, {
    path: '/about',
    component: '~pages/about.vue'
  }, {
    path: '/',
    component: '~pages/index.vue'
  }
]

例2:隐藏路由

在文件名前加 _

|-- pages
    |-- _about.vue
    |-- index.vue

会生成:

routes: [
  {
    path: '/',
    component: '~pages/index.vue'
  }
]

 

配置文件
目录下的 nuxt.config.js 是我们唯一的配置入口,这里不建议修改 .nuxt 目录,除非特殊需求

默认的给力我们三个配置 ·head·css·loading· 分别是头部设置,全局css,loading进度条

nuxt.config.js 的全部的配置如下,点击查看具体例子

1、cache

2、loading
3、router
4、css

5、plugins
6、head

另外还提供了 vuex 等配置,感兴趣可以去 github 和官网。

其他一些配置的引用
安装需要的loader后指定lang就可以直接使用。
 

 

npm i less less-loader --save--dev

//全局css
  css: [
    {
      src: 'static/less/base.sass',
      lang: 'less'
    }
  ],
  //页面中使用

    <style lang="less" scoped></style>

 loading 

//禁用
module.exports = {
  loading: false
}

//颜色条
module.exports = {
loading: { color: '#3B8070' }
}

//使用组件
添加一个loading组件 (官方示例如下,详情可看官方文档)
引用该组件
module.exports = {
  loading: '~components/loading.vue'
}
///  components/loading.vue

 <template lang="html">
  <div class="loading-page" v-if="loading">
    <p>Loading...</p>
  </div>
</template>

<script>
export default {
  data: () => ({
    loading: false
  }),
  methods: {
    start () {
      this.loading = true
    },
    finish () {
      this.loading = false
    }
  }
}
</script>

<style scoped>
.loading-page {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.8);
  text-align: center;
  padding-top: 200px;
  font-size: 30px;
  font-family: sans-serif;
}
</style>

使用插件、第三方模块

//通过script标签

 head: {  
     script: [
      { src: 'https://res.wx.qq.com/open/js/jweixin-1.2.0.js' }
    ]
  },

  //plugins配置 , ssr:false 设置只在客户端使用

   plugins: [
    { src: '~plugins/flexible.js', ssr: false }
  ],

//在页面中使用axios,配置vendor使其只打包一次

//页面
<template>
  <h1>{{ title }}</h1>
</template>

<script>
import axios from 'axios'

export default {
  async asyncData ({ params }) {
    let { data } = await axios.get(`https://my-api/posts/${params.id}`)
    return { title: data.title }
  }
}
</script>

//配置文件

module.exports = {
  build: {
    vendor: ['axios']
  }
}

使用第三方组件库

在nuxt里使用第三方UI组件库也非常简单。以iview为例

///在plugins下新建 iview.js

import Vue from 'vue'
import iView from 'iview';

Vue.use(iView);

////配置文件引入css和plugin

module.exports = {
  css: [
    { src: 'iview/dist/styles/iview.css'}
  ],
  plugins: [
    { src: '~plugins/iview.js', ssr: false }
  ],

}

asyncData

nuxt扩展的异步数据方法,对于页面数据,我们一般有页面data定义的形式和vuex统一管理的形式,可以根据自己的需求选择。

data定义这里就不赘述了,这里说一下vuex统一管理数据的做法。

///page页面
<template>
  <div class="container">
    <p class="title">数据展示!</p>
    <Table :columns="columns1" :data="data1"></Table>
  </div>
</template>

<script>
  import { mapState } from 'vuex'
  import axios from 'axios'

  export default {
    middleware: 'auth',  //定义页面中间件
    head () {
      return {
        title: '其他页面'
      }
    },
    data () {
      return {}
    },
    async fetch ({ store, params }) {
      let { data } = await axios.get('http://106.14.205.222/article/list?page=1&limit=10&isActive=1')
      console.log( data )
      store.commit('SET_LIST', data.list)
    },
    computed: {
      ...mapState([
        // 映射 this.xxx 为 store.state.xxx
        'columns1',
        'data1'
      ])
    },
  }
</script>




//store  index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = () => new Vuex.Store({

  state: {
    columns1: [
      {
        title: '标题',
        key: 'title'
      },
      {
        title: '介绍',
        key: 'intro'
      },
      {
        title: '日期',
        key: 'time'
      }
    ],
    data1: [],
    user: 'xu' //如果为空,则会中间件控制跳转404
  },
  mutations: {
    SET_LIST: (state, data) => {
      state.data1 = data
    },
  }
})

export default store