vue項目最佳實踐

使用vue一年多了,作了一個javaee的項目(全棧,前端使用的mvvm框架vue),三個移動端項目,其中兩個釘釘子應用(釘釘的坑不少,心累),一個微信的(ing)。本身也慢慢摸索出一些項目中的最佳實踐,整理了一下,作個記錄一塊兒交流。若是你在閱讀過程當中,以爲我某些地方作的不對或者有更好的方法時,歡迎交流~javascript

項目結構

清晰的目錄結構不只能夠展示一個團隊的水平,並且別人維護(接鍋)的時候,也能更好的理解你的項目。這個每一個團隊都有本身的標準或者風格,沒有固定的格式。我通常是這麼安排的(vue-cli項目),下面是src目錄:css

—— src
  |—— assets // 項目資源目錄
      |—— styles // 樣式文件
          |—— reset.scss // reset css,會在 /src/main.js 中被導入
          |—— variables.scss // 項目中的變量,混合(mixin)等公有樣式變量
          |—— ...
      |—— images // 圖片
      |—— fonts // 字體
      |—— ...
  |—— components // 組件目錄
      |—— layout // 佈局相關組件
          |—— Header.vue // 頭部
          |—— BottomMenu.vue // 底部菜單
          |—— ...
      |—— common // 公有組件
      |—— base // 基礎組件
      |—— ...
  |—— pages // 頁面目錄
      |—— user // 用戶相關頁面
          |—— Login.vue // 登陸頁面
          |—— Register.vue // 註冊頁面
          |—— Info.vue // 詳情頁面
      |—— order // 訂單相關頁面
          |—— List.vue // 訂單列表
          |—— Detail.vue //訂單詳情
          |—— ...
      |—— Home.vue // 主頁
      |—— ...
  |—— router // 路由
      |—— modules // 存放各個模塊的路由
          |—— user.js // 用戶模塊
          |—— order.js // 訂單模塊
      |—— index.js // 路由主js,整合各個模塊,而且還會定義一些全局鉤子等其餘
  |—— store // 全局狀態管理目錄
      |—— mutation-types.js // mutation types
      |—— index.js // 主js,整合各個模塊的
      |—— actions.js // actions
      |—— modules // 各個模塊的states
          |—— user.js
          |—— order.js
  |—— common // 全局工具方法
      |—— data-format.js // 數據轉換
      |—— http.js // 網絡請求
      |—— ...
  |—— App.vue
  |—— main.js
  |—— init-plugins.js // 依賴的第三方的初始化,會在main.js中引入

以上只是我我的的習慣,不過這個結構要根據具體的項目狀況調整。沒必要爲了模塊化而模塊化。若是你的項目業務邏輯不復雜,整個項目也就十幾個頁面,能夠適當的刪減部分模塊。html

組件

你的項目可能須要一些這樣的組件,來提高用戶體驗。前端

  • no-data-foundvue

    這個存在的場景是,好比你加載數據列表或者篩選列表查詢等數據操做,若是請求成功可是沒有數據,這時候有必要提供一個no-data-found的組件。html5

  • errorjava

    當你的應用出錯的時候,好比網絡超時加載不了數據,也能夠給一個組件作提示ios

方法抽取

在開始咱們項目以前,咱們應該知道,有哪些方法是必要的、共有的,相似於咱們的工具方法同樣。這裏我羅列一些供參考:git

網絡請求

  • 項目可能用到幾種請求?(POST,GET,PUT,DELETE…)
    對於不一樣的請求,咱們的請求頭也須要改變,是抽取成四個方法,仍是在一個方法上變異?
    哪一種更適合如今的業務場景?
  • 請求出錯如何處理(組件內捕獲?所有捕獲?其餘?…)
    爲何提出這個問題呢?由於這是我前不久個人leader給我提的優化方案。以前的項目都沒在乎過這個,後來是把axios包了一層,使用了相似jQuery的請求方式,實現了組件內捕獲業務場景錯誤(校驗失敗之類的),所有捕獲請求錯誤(404,500,400等)。

數據轉換

  • 日期格式轉換
  • 日期與字符串轉換
    github

    關於日期都全部操做,建議採用momentJs。功能強大並且兼容性好,我深深的記得以前一個釘釘項目中日期操做不兼容iphone手機的時候,那個bug讓我找了半天才找到根源。
    官網傳送門:http://momentjs.cn/

  • 數字與字符串轉換

交互方法

你的應用應該包含一套用於提示用戶的組件:
Toast
用於提示用戶一些信息
Confirm
用戶提示用戶是否確認接下來的操做。對於一些重要的操做,好比提交表單,刪除信息等操做,務必使用。
Loading
當用戶在上傳或者下載圖片等其餘資源的時候,用於提示進度信息。固然這個請求方法要可以得到到相應的進度信息才行,僞造須謹慎(手動斜眼笑)。
Spinner
加載數據時的提示,俗稱「菊花圖「

mint-ui:http://mint-ui.github.io/docs/#/
vux:https://doc.vux.li/zh-CN/

這裏要說的是,你能夠對這些方法進行二次封裝,以便更方便的使用。包裝後,可能就能夠像下面這樣使用了:

Dialog.toast('cool')
Dialog.confirm('Are you sure?',()=>{Dialog.toast('confirm')}) Dialog.spinner('loading...')

如何管理css

該分離仍是該合併

咱們知道vue的SFC(單文件組件,即以.vue結尾的文件),提供了三個基礎的頂級標籤:<template>, <style>,<script>。我我的比較喜歡把樣式也寫進SFC中,由於這樣針對性很強,調試某個頁面樣式的時候,只要打開一個文件就好了。(這麼說是由於我一開始是隔離全部的css文件到assets目錄下,這樣雖然代碼看起來漂亮了,你只要在style標籤內import樣式就能夠了,可是調試的時候很是不方便。)

可使用全局變量嗎

固然,前提是在你使用css預處理器的狀況下:
爲了系統的UI一致性(consistency),咱們的設計稿確定是一套統一的主題的。因此咱們不一樣頁面的邊框粗細顏色,按鈕背景色,字體大小顏色,一級邊框二級邊框…,一級標題二級標題…等等衆多的樣式須要保持一致。若是在每一個頁面都定義一次,這可行,可是工做量和作法都是不值得提倡的。
有一些loader就是負責處理這類狀況的,以sass爲例,你可使用 sass-resources-loader 來完成全局變量的共享。使用方法也很簡單:
- 安裝

npm install sass-resources-loader --save-dev
  • 使用
    若是你使用的vue-cli版本是3以前的話,修改項目中/build/utils.js中的scss成以下:
scss: generateLoaders('sass').concat({
 loader: 'sass-resources-loader',
 options: {
   resources: path.resolve(__dirname, '../src/assets/styles/variables.scss')
 }
})

接下來就能夠在任意的組件中使用這個varibles.scss裏面的樣式了。

reset.css

有的ui框架會修改默認樣式,並且不一樣瀏覽器的樣式標準也有一些不一樣,因此resetcss頗有必要。國內諸如淘寶,百度等都有本身的resetcss,你能夠參考這篇博客得到幫助,也能夠根據這個自定義本身項目的resetcss。
https://meyerweb.com/eric/tools/css/reset/

<style scoped> with <style>

也許你遇到過這種狀況,須要修改某一個ui框架的默認樣式,可是在scoped的style塊中修改不成功。不得不將style塊的scoped屬性拿掉,或者將這個要改變的樣式放進全局樣式裏再在main.js中導入,或者直接將樣式定義在App.vue裏面。這些都是可行的,可是要注意命名空間要是正確的,否則是找不到樣式的。
這裏提供另外一種方法。其實在vue的SFC中,是容許多個style塊的。你能夠像下面這樣使用:

<style scoped lang="scss"> .order-detail { // put your local style here } </style>
<style> .mint-button{ // put your global style here if you want to change the lib's style } </style>

善用vue-router的meta

可能不少人用vue-router的時候,只是用來作路由跳轉,配置路由的時候,添加一個path和component就完事了。若是這樣能知足你的全部需求,那也ok。可是有一些業務場景,使用meta屬性能夠很是巧妙的解決問題。
這裏分享一下我使用過的例子:

title

想要動態的顯示應用/系統的標題,你會怎麼作呢?
你可能會在每個頁面的鉤子中給document.title賦值,可是有更簡單的方法,好比我定義一個下面的router:

{ name:'user-detail', path:'/user-detail', component: UserDetail, meta: { title: '用戶信息' }
},

接着在App.vue裏面,添加下面的代碼:

watch:{
  '$route':function(to, from){
    document.title = to.meta.title
  }
}

這樣每次定義router的時候,只要填寫了meta屬性,系統的title就會跟着改變了。
另外,在App.vue裏面watch的$route,還有不少用處,好比處理前進後退的動畫等。

keepAlive

咱們知道vue提供了一個<keep-alive> 組件,用戶緩存組件以得到更快的交互。簡單介紹一下,當設置某一頁面爲keep-alive的時候,它的mounted只會在第一次加載的時候執行一次,後面在打開該頁面的時候都不會執行。可是activateddeactivated兩個鉤子能夠捕獲頁面進入和退出的動做。
根據不一樣的業務邏輯,有些頁面須要緩存有些頁面不須要緩存,因此咱們也能夠定義在router中:

{ name:'user-detail', path:'/user-detail', component: UserDetail, meta: { title: '用戶信息', keepAlive: true }
},

而後修改主路由入口的代碼(App.vue)

<template v-if="$route.meta.keepAlive">
  <keep-alive>
    <router-view/>
  </keep-alive>
</template>
<template v-else>
  <router-view/>
</template>

這樣你就能夠根據本身的須要,決定哪些頁面須要緩存了。
關於<keep-alive> 組件的更多用法,參考:https://cn.vuejs.org/v2/api/#keep-alive

scrollToTop

咱們知道,vue-router提供了頁面的滾動行爲。vue-router的滾動行爲
咱們也能夠在路由中配置該屬性,來細粒度的控制咱們頁面的滾動行爲。

scrollBehavior方法,摘自官網例子 。我給註釋翻譯了一下。
https://github.com/vuejs/vue-router/blob/next/examples/scroll-behavior/app.js

// - 只在支持html5 history 模式的瀏覽器中有效
// - 默認無滾動行爲
// - 返回false的話,會阻止滾動行爲
const scrollBehavior = (to, from, savedPosition) => {
  if (savedPosition) {
    // savedPosition 只在popstate的導航中有效
    // popstate:https://developer.mozilla.org/zh-CN/docs/Web/Events/popstate
    return savedPosition
  } else {
    const position = {}
    // 經過返回選擇器來滾動到錨點位置
    if (to.hash) {
      position.selector = to.hash
    }
    // 檢查路由元數據(meta)配置中是不是返回頂部的需求
    if (to.matched.some(m => m.meta.scrollToTop)) {
     // 設置滾動位置的x和y座標:頂部
      position.x = 0
      position.y = 0
    }
    // 若是返回的位置是假值(falsy)或者是空對象,將會返回當前滾動的位置
    return position
  }
}

OK,今天就說這麼多,還有一些,好比異常處理,vuex使用場景,一致性(consistency)等,下次有機會在寫一篇,今天頭有點痛,得睡覺了。

有一些實踐我已經用到這個項目https://github.com/JerryYuanJ/a-vue-app-template中了,可是因爲這個項目寫的時間比較早,並且主要是爲了熟悉vue和其餘一些練習爲主,那時候還不懂事,因此不少地方仍是得改的,若是你須要拿項目來練手上面的一些實踐的話,這會是個不錯的選擇。你能夠pull requeset,我會merge的~歡迎star

相關文章
相關標籤/搜索