nuxt企業(yè)商城小結(jié)

nuxt是一個(gè)基于 Vue.js的服務(wù)端渲染應(yīng)用框架,為了解決C端項(xiàng)目諸如"首屏加載速度" "SEO優(yōu)化"之類的痛點(diǎn)而生,從發(fā)布到現(xiàn)在已經(jīng)接近兩年趨于穩(wěn)定.我接手這個(gè)商城也有一段時(shí)間了,本著提高自己的目的再來梳理下我對這個(gè)框架的認(rèn)識.

應(yīng)用流程

下圖闡述的是Nuxt.js 應(yīng)用一個(gè)完整的服務(wù)器請求到渲染(或用戶通過 <nuxt-link> 切換路由渲染頁面)的流程.首先是服務(wù)器端接受到請求,然后nuxt服務(wù)啟動(dòng),這時(shí)候也初始化了vuex.然后依次通過中間件去匹配 配置(config.js) 布局(layout) 具體頁面,在頁面組件被加載之前服務(wù)器端執(zhí)行異步數(shù)據(jù)方法(asyncData 和 fetch),最后輸出模板.這里我們要注意的是,只有beforeCreate和created會(huì)在服務(wù)器端和瀏覽器端均被調(diào)用.


image.png

項(xiàng)目結(jié)構(gòu)

image.png

我們這個(gè)項(xiàng)目應(yīng)該是用官方提供的starter模板啟動(dòng),讓我們一個(gè)個(gè)來分析.

  • nuxt是自動(dòng)生成的,關(guān)于布局 請求 loading 中間件 路由 vuex的一些官方封裝,無需過多關(guān)注.
  • api用于存放項(xiàng)目地址和localstorage的一些命名.
  • assets用于存放一些靜態(tài)資源,我們這里有 全局CSS iconfont文件 圖片 element-ui主題 全局工具類js函數(shù).這里的文件會(huì)被webpack做構(gòu)建編譯處理,而static不會(huì).
  • components用于存放一些公共組件,框架并不會(huì)對其進(jìn)行增強(qiáng).
  • layouts是一些布局文件,404頁面也放在這里了.在page下的頁面文件里指定layout就可以使用這里的布局.
  • locales是我們用于國際化的一些語言文件
  • middleware是一些運(yùn)行在頁面渲染之前的自定義函數(shù),我們這里主要是語言切換和loading.
  • pages用于組織應(yīng)用的路由和視圖.nuxt比較省心的地方是已經(jīng)約定了路由配置的自動(dòng)生成,所以同時(shí)也需要注意文件的地址.
  • plugins配置需要在 根vue.js應(yīng)用實(shí)例化之前需要運(yùn)行的 Javascript 插件,我們這里有全局過濾器,element-ui的國際化配置,用于站長統(tǒng)計(jì)的piwik,以及對于第三方庫vue-loading的引用和配置.


    image.png
  • static 用于存放應(yīng)用的靜態(tài)文件,此類文件不會(huì)被 Nuxt.js 調(diào)用 Webpack 進(jìn)行構(gòu)建編譯處理。 服務(wù)器啟動(dòng)的時(shí)候醉蚁,該目錄下的文件會(huì)映射至應(yīng)用的根路徑 / 下啤它。我們這里只有favicon.ico.
  • store用于組織應(yīng)用的Vuex 狀態(tài)樹文件.這里涉及到兩個(gè)方法,一個(gè)是fetch,會(huì)在渲染頁面前被調(diào)用,作用是填充store 數(shù)據(jù);一個(gè)是nuxtServerInit 方法,是在啟動(dòng)nuxt應(yīng)用時(shí)去填充stores數(shù)據(jù).這個(gè)方法我們就是用來拿token和進(jìn)行其他初始化.
  • 下面的文件都比較常見了,eslint代碼檢查 package.json依賴管理 lock版本鎖定,mes_pc.js里面存了給服務(wù)器用的啟動(dòng)配置.nuxt.config.js是核心,在下一小節(jié)進(jìn)行講解.

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: [
    // 項(xiàng)目中的 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 // 響應(yīng)時(shí)間
      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用于配置應(yīng)用的的title和meta等信息
  • 在頁面切換的時(shí)候,Nuxt.js 使用內(nèi)置的加載組件顯示加載進(jìn)度條遭商。通過Loading我們可以進(jìn)行定置,這里我們指定了顏色.
  • plugins指定了實(shí)例化之前運(yùn)行的Vue.js插件,首先配置路徑,然后用 ssr: false 變量來配置插件只從客戶端還是服務(wù)端運(yùn)行.
  • css指定了全局css文件和第三方css庫
  • router可用于覆蓋 Nuxt.js 默認(rèn)的 vue-router 配置,我們這里主要是給每個(gè)頁面設(shè)置默認(rèn)中間件.
  • axios配置可以單獨(dú)抽成一個(gè)文件.這里我們設(shè)置了如響應(yīng)時(shí)間 返回格式 請求格式 baseUrl之類的基本參數(shù),然后配置了請求攔截 返回?cái)r截 錯(cuò)誤處理,主要是對 loading的管理 token的攜帶 語言包配置在請求頭里,以及特定狀態(tài)碼的重定向等等.
  • build是自定義webpack配置,會(huì)覆蓋掉nuxt.js默認(rèn)的.這里用MinChunkSizePlugin指定了chunk 體積,vendor提取出了會(huì)被頻繁使用的公共庫.extend這里主要是通過一些參數(shù),使得在開發(fā)環(huán)境&客戶端環(huán)境下使用了eslint代碼檢查.
  • 此外還有一些配置項(xiàng),比較實(shí)用的是env用來定義環(huán)境變量 dev配置開發(fā)還是生產(chǎn)模式,這樣我們的axios就不用手動(dòng)改baseUrl了.

單個(gè)頁面分析

(未完待續(xù))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末固灵,一起剝皮案震驚了整個(gè)濱河市捅伤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巫玻,老刑警劉巖丛忆,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異仍秤,居然都是意外死亡熄诡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門诗力,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凰浮,“玉大人,你說我怎么就攤上這事苇本⊥嗉耄” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵瓣窄,是天一觀的道長笛厦。 經(jīng)常有香客問我,道長俺夕,這世上最難降的妖魔是什么裳凸? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮劝贸,結(jié)果婚禮上姨谷,老公的妹妹穿的比我還像新娘。我一直安慰自己映九,他們只是感情好梦湘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著氯迂,像睡著了一般践叠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嚼蚀,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天禁灼,我揣著相機(jī)與錄音,去河邊找鬼轿曙。 笑死弄捕,一個(gè)胖子當(dāng)著我的面吹牛僻孝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播守谓,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼穿铆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了斋荞?” 一聲冷哼從身側(cè)響起荞雏,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎平酿,沒想到半個(gè)月后凤优,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜈彼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年筑辨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幸逆。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棍辕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出还绘,到底是詐尸還是另有隱情楚昭,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布蚕甥,位于F島的核電站哪替,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏菇怀。R本人自食惡果不足惜凭舶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望爱沟。 院中可真熱鬧帅霜,春花似錦、人聲如沸呼伸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽括享。三九已至搂根,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铃辖,已是汗流浹背剩愧。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留娇斩,地道東北人仁卷。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓穴翩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锦积。 傳聞我的和親對象是個(gè)殘疾皇子芒帕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,969評論 3 119
  • https://cn.vuejs.org 轉(zhuǎn)載 :OpenDigg awesome-github-vue 是由Op...
    文朝明閱讀 6,577評論 0 38
  • 轉(zhuǎn)載 :OpenDiggawesome-github-vue 是由OpenDigg整理并維護(hù)的Vue相關(guān)開源項(xiàng)目庫...
    果汁密碼閱讀 23,100評論 8 124
  • 曾經(jīng)以為 盛開的花朵是生命的極致 夜晚的黑暗有蛐蛐的奏鳴就是水墨畫 張無忌的人生是最完美的描繪 有電視的下午是最幸...
    樂行僧閱讀 363評論 0 1
  • 第一章 站在陰森森的大鐵門外丰介,白芨不禁抖擻著背蟆,卷起袖子,是一層雞皮疙瘩基矮。 這里淆储,就是父親大人說的借住的地方嗎? 穿...
    唐山耶閱讀 5,126評論 0 12