nuxt企业商城小结

nuxt是一个基于 Vue.js的服务端渲染应用框架,为了解决C端项目诸如"首屏加载速度" "SEO优化"之类的痛点而生,从发布到现在已经接近两年趋于稳定.我接手这个商城也有一段时间了,本着提高自己的目的再来梳理下我对这个框架的认识.

应用流程

下图阐述的是Nuxt.js 应用一个完整的服务器请求到渲染(或用户通过 <nuxt-link> 切换路由渲染页面)的流程.首先是服务器端接受到请求,然后nuxt服务启动,这时候也初始化了vuex.然后依次通过中间件去匹配 配置(config.js) 布局(layout) 具体页面,在页面组件被加载之前服务器端执行异步数据方法(asyncData 和 fetch),最后输出模板.这里我们要注意的是,只有beforeCreate和created会在服务器端和浏览器端均被调用.


image.png

项目结构

image.png

我们这个项目应该是用官方提供的starter模板启动,让我们一个个来分析.

  • nuxt是自动生成的,关于布局 请求 loading 中间件 路由 vuex的一些官方封装,无需过多关注.
  • api用于存放项目地址和localstorage的一些命名.
  • assets用于存放一些静态资源,我们这里有 全局CSS iconfont文件 图片 element-ui主题 全局工具类js函数.这里的文件会被webpack做构建编译处理,而static不会.
  • components用于存放一些公共组件,框架并不会对其进行增强.
  • layouts是一些布局文件,404页面也放在这里了.在page下的页面文件里指定layout就可以使用这里的布局.
  • locales是我们用于国际化的一些语言文件
  • middleware是一些运行在页面渲染之前的自定义函数,我们这里主要是语言切换和loading.
  • pages用于组织应用的路由和视图.nuxt比较省心的地方是已经约定了路由配置的自动生成,所以同时也需要注意文件的地址.
  • plugins配置需要在 根vue.js应用实例化之前需要运行的 Javascript 插件,我们这里有全局过滤器,element-ui的国际化配置,用于站长统计的piwik,以及对于第三方库vue-loading的引用和配置.


    image.png
  • static 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下。我们这里只有favicon.ico.
  • store用于组织应用的Vuex 状态树文件.这里涉及到两个方法,一个是fetch,会在渲染页面前被调用,作用是填充store 数据;一个是nuxtServerInit 方法,是在启动nuxt应用时去填充stores数据.这个方法我们就是用来拿token和进行其他初始化.
  • 下面的文件都比较常见了,eslint代码检查 package.json依赖管理 lock版本锁定,mes_pc.js里面存了给服务器用的启动配置.nuxt.config.js是核心,在下一小节进行讲解.

nuxt.config.js分析

const webpack = require('webpack')
const NLE = require('./api/constant')
module.exports = {
  /*
  ** Headers of the page
  */
  head: {
    title: '欧亚商城',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width' },
      { hid: 'description', name: 'description', content: 'Nuxt.js project' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  /*
  ** Customize the progress bar color
  */
  loading: { color: '#019ae0' },
  plugins: [
    { src: '~plugins/vue-lazyload', ssr: true },
    { src: '~plugins/piwik', ssr: false },
    { src: '~plugins/filter', ssr: true },
    { src: '~plugins/i18n', ssr: true }
  ],
  css: [
    // 项目中的 CSS 文件
    'bootstrap/dist/css/bootstrap.min.css',
    '~/assets/fontsize/iconfont.css',
    '~/assets/theme/index.css',
    '~/assets/style/common.css',
    '~/assets/style/global.css',
    '~/assets/style/home.css',
    '~/assets/style/transform.css'
  ],
  modules: [
    '@nuxtjs/axios'
  ],
  router: {
    middleware: ['startLoading', 'i18n']
  },
  axios: {
    baseURL: NLE.BASE_API_URL, // 配置接口地址
    browserBaseURL: NLE.BASE_API_URL,
    credentials: false,
    init (axios, ctx) {
      axios.defaults.timeout = 60000 // 响应时间
      axios.defaults.responseType = 'json'
      axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8' // 配置请求头
    },
    requestInterceptor (config, {store}) {
      // console.log(process.env.SERVER, 111)
      process.client && store.commit('onLoading', true)
      config.headers.versions = 'multi-specification'
      config.headers.language = store.state.locale
      const token = store.state.login_state
      if (token) config.headers.Authorization = token
      return config
    },
    responseInterceptor (response, {store}) {
      process.client && store.commit('onLoading', false)
      return response
    },
    errorHandler (error, {redirect, store}) {
      process.client && store.commit('onLoading', false)
      const status = error.response.status
      if (status === 401 || status === 402) redirect('/login')
      return error
    },
    redirectError: {
      401: '/login'
    }
  },
  /*
  ** Build configuration
  */
  build: {
    plugins: [
      new webpack.optimize.MinChunkSizePlugin({minChunkSize: 15000})
    ],
    vendor: ['element-ui', 'localStorage', 'vue-i18n'],
    /*
    ** Run ESLint on save
    */
    extend (config, ctx) {
      if (ctx.dev && ctx.isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
}
  • head用于配置应用的的title和meta等信息
  • 在页面切换的时候,Nuxt.js 使用内置的加载组件显示加载进度条。通过Loading我们可以进行定置,这里我们指定了颜色.
  • plugins指定了实例化之前运行的Vue.js插件,首先配置路径,然后用 ssr: false 变量来配置插件只从客户端还是服务端运行.
  • css指定了全局css文件和第三方css库
  • router可用于覆盖 Nuxt.js 默认的 vue-router 配置,我们这里主要是给每个页面设置默认中间件.
  • axios配置可以单独抽成一个文件.这里我们设置了如响应时间 返回格式 请求格式 baseUrl之类的基本参数,然后配置了请求拦截 返回拦截 错误处理,主要是对 loading的管理 token的携带 语言包配置在请求头里,以及特定状态码的重定向等等.
  • build是自定义webpack配置,会覆盖掉nuxt.js默认的.这里用MinChunkSizePlugin指定了chunk 体积,vendor提取出了会被频繁使用的公共库.extend这里主要是通过一些参数,使得在开发环境&客户端环境下使用了eslint代码检查.
  • 此外还有一些配置项,比较实用的是env用来定义环境变量 dev配置开发还是生产模式,这样我们的axios就不用手动改baseUrl了.

单个页面分析

(未完待续)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AGI阅读 16,009评论 3 119
  • https://cn.vuejs.org 转载 :OpenDigg awesome-github-vue 是由Op...
    文朝明阅读 6,646评论 0 38
  • 转载 :OpenDiggawesome-github-vue 是由OpenDigg整理并维护的Vue相关开源项目库...
    果汁密码阅读 23,202评论 8 124
  • 曾经以为 盛开的花朵是生命的极致 夜晚的黑暗有蛐蛐的奏鸣就是水墨画 张无忌的人生是最完美的描绘 有电视的下午是最幸...
    乐行僧阅读 384评论 0 1
  • 第一章 站在阴森森的大铁门外,白芨不禁抖擞着,卷起袖子,是一层鸡皮疙瘩。 这里,就是父亲大人说的借住的地方吗? 穿...
    唐山耶阅读 5,461评论 0 12