nuxt.js 简述

为什么使用nuxt.js?

vue单页面应用渲染是从服务器获取所需js,在客户端将其解析生成html挂载于
id为app的DOM元素上,这样会存在两大问题。

  1. 由于资源请求量大,造成网站首屏加载缓慢,不利于用户体验。
  2. 由于页面内容通过js插入,对于内容性网站来说,搜索引擎无法抓取网站内容,不利于SEO。
    Nuxt.js 是一个基于Vue.js的通用应用框架,预设了利用Vue.js开发服务端渲染的应用所需要的各种配置。可以将html在服务端渲染,合成完整的html文件再输出到浏览器。

除此之外,nuxt与vue还有一些其他方面的区别。

  1. 路由
    nuxt按照 pages 文件夹的目录结构自动生成路由
    vue需在 src/router/index.js 手动配置路由

  2. 入口页面
    nuxt页面入口为 layouts/default.vue
    vue页面入口为 src/App.vue

  1. webpack配置
    nuxt内置webpack,允许根据服务端需求,在 nuxt.config.js 中的build属性自定义构建webpack的配置,覆盖默认配置
    vue关于webpack的配置存放在build文件夹下

下图为关于nuxt的简单概述


NUXT.js.png

nuxt是关于服务端渲染的,如若想让组件在客户端渲染,可以使用<no-ssr></no-ssr>将其包裹起来(该标签最多只能包含一个子组件/元素)。
这样在未获取到内容时,页面先采用<div class="no-ssr-placeholder" data-v-2a183b29=""></div>占位,然后将获取到的html覆盖该占位

安装sass
npm i node-sass sass-loader scss-loader --save-dev

vue文件中可直接使用

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

sass文件如需解析,nuxt.config.js中配置css属性

css: [
    {
      src: '~/assets/style/reset.scss',
      lang: 'scss'
    }
],
使用axios并跨域
  1. package.json
    npm install @nuxtjs/proxy
    nuxt 项目默认安装axios, 所以只需安装proxy即可
"dependencies": {
    "@nuxtjs/axios": "^5.0.0",
    "@nuxtjs/proxy": "^1.2.4",
}
  1. nuxt.config.js
modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  proxy: {
    '/api': {
      target: 'http:www.xxx.com',
      changeOrigin: true,
      pathRewrite: {
        '^/api ': ''
      }
    }
  },
  1. index.vue
import axios from 'axios'
export default {
    data () {
        return {
          page: 0
        }
    },
    async asyncData () {
        let data = await axios.get('http://localhost:3000/api/admin/list')
        return {
          page: data.data.page
        }
  },
}

注意
采用 import axios from 'axios' 方式引入axios时,接口参数前须加baseURL -> http://localhost:3000
如果采取 axios.get('/api/admin/game') 调用接口返回nuxt服务器错误,如下图

1540541910156.jpg

封装axios,解决每个请求前加baseURL
plugins/axios.js

import * as axios from 'axios'

let options = {}
// The server-side needs a full url to works
if (process.server) {
  options.baseURL = `http://${process.env.HOST || 'localhost'}:${process.env.PORT || 3000}`
}

export default axios.create(options)

index.vue

import axios from '~/plugins/axios'
axios.get('/api/admin/game')
引入第三方插件(vue-awesome-swiper)
  1. npm install vue-awesome-swiper --save

  2. plugins文件夹下新建awesome-swiper.js

import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper/dist/ssr'

Vue.use(VueAwesomeSwiper)
  1. nuxt.config.js引入css及js
css: [
    'swiper/dist/css/swiper.css',
],
plugins: [
    { src: "~/plugins/awesome-swiper.js", ssr: false },
],
  1. 页面初始化
<div v-swiper:mySwiper="swiperOption">
    <div class="swiper-wrapper">
         <div class="swiper-slide" v-for="(banner, index) in banners" :key="index">
            <img :src="banner">
         </div>
    </div>
    <div class="swiper-pagination swiper-pagination-bullets"></div>
</div>

export default {
  data () {
    return {
      banners: [ 
        require('~/assets/img/1540892214119.jpg'),
        require('~/assets/img/1540892214119.jpg'),
        require('~/assets/img/1540892214119.jpg')
      ],
      swiperOption: {
        autoplay: true,
        loop: true,
        pagination: {
          el: '.swiper-pagination',
        },
      }
    }
  },
}
引入第三方模块(moment.js)
  1. npm install moment --save
  2. vue页面
import moment from 'moment'
export default {
    mounted() {
      moment.locale('zh-cn') // moment.js 默认为英文,可通过此方法设置中文
      console.log(moment().format('dddd')) // 星期三
    },
}

为避免每个页面都引入moment,执行moment.locale('zh-cn'),可将其定义为全局方法

  1. 在plugins文件夹下新建common.js
import Vue from 'vue'
import moment from 'moment'
let common = {
  install (Vue) {
    Vue.prototype.$op = {
      'moment': (date) => {
        let newMoment = new moment(date)
        newMoment.locale('zh-cn')
        return newMoment
      }
    }
  }
}

Vue.use(common)
  1. nuxt.config.js
plugins: [
    { src: '~/plugins/common.js', ssr: false }, 
],
  1. vue页面
this.$op.moment().format('dddd')
修改网站icon

icon.png文件存放在static文件夹下,nuxt.config.js中配置head属性

head: {
    link: [
      { rel: 'icon', type: 'image/png', href: '/icon.png' }
    ]
  },
关于中间件

中间件存放于middleware文件夹下,按使用场景可分为全局中间件和单页面中间件

//全局使用
module.exports = {
  router: {
    middleware: '中间件名称'
  }  
}

//页面单独使用
export default {
    middleware: '中间件名称'
}

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

PS.关于查看NUXT 官网插件demo时遇到的问题
屏幕快照 2018-10-26 下午4.58.47.png

按照index.vue通过require('mini-toastr')引入miniToastr,运行程序报错如下

1540544070985.jpg

打印miniToastr发现为一Module对象,init挂载在其default属性上


1540544125776.jpg

所以修改引入方法为

miniToastr = require('mini-toastr').default

为什么需要require().default

When using ES6 imports (export default HeaderBar), the exported module is of the format {"default" : HeaderBar}. The import statement handles this assignment for you, however, you have to do the require("./mycomponent").default conversion yourself. The HMR interface code cannot use import as it doesn't work inline.

If you want to avoid that, use module.exports instead of export default.

关于如上介绍,测试关于两种模块的导出方法
方式一:export default
新建test.js文件

export default {
  test: function () {
    console.log('test')
  }
}

vue页面导入

let obj = require('~/plugins/con.js').default
obj.test() // 打印‘test’

let obj = require('~/plugins/con.js')
obj.default.test() // 打印‘test’

此时 require('~/plugins/con.js') 打印为

屏幕快照 2018-10-26 下午5.35.24.png

方式二:module.exports

const obj = {
  test: function () {
    console.log('test')
  }
}
module.exports = obj
let obj = require('~/plugins/con.js')
obj.test() // 打印‘test’

此时 require('~/plugins/con.js') 打印为

屏幕快照 2018-10-26 下午5.47.03.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容