nuxt.js 简述

作者: 然后呢_ | 来源:发表于2018-11-05 15:14 被阅读737次
    为什么使用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

    相关文章

      网友评论

        本文标题:nuxt.js 简述

        本文链接:https://www.haomeiwen.com/subject/dsesxqtx.html