1. 程式人生 > >vue-loader學習筆記

vue-loader學習筆記

1:vue-loader簡介

vue-loader是一個webpack的loader;可以將vue檔案轉換為JS模組;

2:vue-loader特性

(1)ES2015預設支援 
(2)允許對VUE元件的組成部分使用其他webpack loader;比如對< style >使用SASS(編譯CSS語言),對< template >使用JADE(jade是一個高效能的模板引擎,用JS實現,也有其他語言的實現—php,scala,yuby,python,java,可以供給node使用) 
(3).vue檔案中允許自定義節點,然後使用自定義的loader處理他們 
(4)對< style >< template >中的靜態資源當做模組來對待,並且使用webpack loaders進行處理 
(5)對每個元件模擬出CSS作用域 
(6)支援開發期元件的熱過載 
在編寫vue應用程式時,組合使用webpack跟vue-loader能帶來一個現代。靈活並且非常強大的前端工作流程;

3:webpack簡介

(1)webpack是一個模組打包工具,他可以將一堆檔案中的每個檔案都作為一個模組;找出他們的依賴關係,將他們打包為可部署的靜態資源; 
(2)使用webpack的loaders,我們可以配置webpack以任何方式去轉換所有型別的檔案;例如 
A:轉換ES2015,CoffeeScript或者TypeScript模組為普通的ES5 CommonJs模組; 
B:可以選擇在編譯之前檢驗你的原始碼; 
C:將jade模板轉換為純HTML並且嵌入JS字串中 
D:將SASS檔案轉換為純CSS,然後將其轉換成JS片段,將生成的CSS作為< style >標籤插入頁面; 
E:處理html或者CSS中引用的圖片。移動到配置的路徑中,並且使用MD5 hash重新命名; 
(3)當你理解webpack原理後會感覺到它是這麼強大,可以大大的優化你的前端工作流程;缺點是配置比較複雜;

4:VUE元件細則

.vue檔案是一個自定義的檔案型別,用類HTML語法描述一個vue元件,每個.vue元件包含三種類型的頂級語言快< template>< script>< style>,還允許新增自定義的模組;

<template>
  <div class="example">{{ msg }}</div>
</template>

<script>
export default {
  data () {
    return {
      msg: 'Hello world!'
    }
  }
}
</script>

<style>
.example {
  color: red;
}
</style>

<custom1>
  This could be e.g. documentation for the component.
</custom1>

 vue-loader會解析檔案,提取出每個語言塊,如果有必要會通過其他loader處理,最後將他們組裝成一個commonjs模組;module.exports出一個vue.js元件物件; 
vue-loader支援使用非預設語言,比如CSS前處理器,預編譯的HTML模板語言,通過設定語言塊的lang屬性;例如

<style lang='sass'>
    /*sass*/
</style>

1:< temlate>語言塊 
(1)預設語言:html 
(2)每個.vue檔案最多包含一個< template>塊 
(3)內容將被提取為字串,將編譯用作VUE元件的template選項; 
2:< script> 
(1)預設語言:JS(在監測到babel-loader或者buble-loader配置時,自動支援ES2015) 
(2)每個.vue檔案最多包含一個< script>塊 
(3)該指令碼在類CommonJS環境中執行(就像通過webpack打包的正常JS模組)。所以你可以require()其他依賴。在ES2015支援下,也可以使用import跟export語法 
(4)指令碼必須匯出Vue.js元件物件,也可以匯出由VUE.extend()建立的擴充套件物件;但是普通物件是更好的選擇; 
3:< style> 
(1)預設語言:css 
(2)一個.vue檔案可以包含多個< style>標籤 
(3)這個標籤可以有 scoped 或者 module屬性來幫助你講樣式封裝到當前元件;具有不同封裝模式的多個< style>標籤可以在同一個元件中混合使用 
(4)預設情況下,可以使用style-loader提取內容,並且通過< style>標籤動態假如文件的< head>中,也可以配置webpack將所有的styles提取到單個CSS檔案中; 
4:自定義塊 
可以在.vue檔案中新增額外的自定義塊來實現專案的特殊需求;例如< docs>塊;vue-loader將會使用標籤名來查詢對應的webpack loaders來應用到對應的模組上;webpack需要在vue-loader的選項loaders中指定; 
以上4個模組的匯入方式 
如果你喜歡分隔你的.vue檔案到多個檔案中,你可以通過src屬性匯入外部檔案;

<template src='./template.html'></template>
<style src='./style.css'></style>
<script src='./script.js'></script>

5:ES2015

1:當專案中配置了babel-loader或者buble-loader,vue-loader會使用它們處理所有.vue檔案中的< script>部分,允許我們在VUE元件中使用ES2015;如果你還沒有使用ES2015,你應該使用它;

<template>
    <Component-a><Component-a>
    <Component-b><Component-b>
<template>
<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'

export default {
  components: {
    ComponentA,
    ComponentB
  }
}
</script>

2:在 Templates 中使用 ES2015

<li v-for="{ id, text } in items">
  {{ id }} {{ text }}
</li>
<my-component>
  <template scope="{ id, text }">
    <span>{{ id }} {{ text }}</span>
  </template>
</my-component>

 3:vue-loader只處理.vue檔案,你需要告訴webpack如何使用babel-loader或者buble-loader處理.js檔案,在webpack中配置babel-loader或者buble-loader;腳手架vue-cli已經為你做了這些;

6:CSS作用域

<style scoped>
.example {
  color: red;
}
</style>

<template>
  <div class="example">hi</div>
</template>

 轉換結果

<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>

注意:可以在同一個元件中使用scoped跟non-scoped styles

<style>
/* global styles */
</style>

<style scoped>
/* local styles */
</style>

CSS 作用域不能代替 classes。考慮到瀏覽器渲染各種 CSS 選擇器的方式,當使用 scoped 時,p { color: red } 在作用域中會慢很多倍(即當與屬性選擇器組合時)。如果你使用 classes 或者 ids 代替,比如 .example { color: red },這樣幾乎沒有效能影響。

7:CSS模組

在< style>上新增module屬性,將為css-loader開啟CSS模組模式;生成的CSS物件將為元件注入一個名叫$style的計算屬性,可以在模組中使用動態的class繫結;由於他是一個計算屬性,它也適用於:class的object/array語法

<template>
  <p :class="$style.red">
    This should be red
  </p>
</template>
<template>
  <div>
    <p :class="{ [$style.red]: isRed }">
      Am I red?
    </p>
    <p :class="[$style.red, $style.bold]">
      Red and bold
    </p>
  </div>
</template>
<style module>
.red {
  color: red;
}
.bold {
  font-weight: bold;
}
</style>

<script>
export default {
  created () {
    console.log(this.$style.red)
  }
}
</script>

 自定義注入名稱

<style module="a">

</style>

<style module="b">

</style>

配置 css-loader Query

CSS 模組處理是通過 css-loader。預設 query 如下:

{
  modules: true,
  importLoaders: true,
  localIdentName: '[hash:base64]'
}

你可以使用 vue-loader 的 cssModules 選項去為 css-loader 新增 query 配置:

// webpack 2
module: {
  rules: [
    {
      test: '\.vue$',
      loader: 'vue-loader',
      options: {
        cssModules: {
          localIdentName: '[path][name]---[local]---[hash:base64:5]',
          camelCase: true
        }
      }
    }
  ]
}

8:PostCSS

vue-loader處理的CSS輸出,都是通過PostCSS進行作用域重寫,還可以為PostCSS新增自定義外掛,

module.exports = {
  // other options...
  module: {
    // module.rules is the same as module.loaders in 1.x
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        // vue-loader options goes here
        options: {
          // ...
          postcss: [require('postcss-cssnext')()]
        }
      }
    ]
  }
}

9:前處理器

1:CSS

npm install sass-loader node-sass --save-dev
<style lang="sass">
  /* write sass here */
</style>

與名稱相反,sass-loader 預設解析 SCSS 語法。如果你想要使用 SASS 語法,你需要配置 vue-loader 的選項:

{
  test: /\.vue$/,
  loader: 'vue-loader',
  options: {
    loaders: {
      scss: 'vue-style-loader!css-loader!sass-loader', // <style lang="scss">
      sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' // <style lang="sass">
    }
  }
}

2:JS 
Vue 元件中的所有 JavaScript 預設使用 babel-loader 處理。你也可以改變處理方式:

npm install coffee-loader --save-dev
<script lang="coffee">
  # Write coffeescript!
</script>

3:template 
模版的處理方式略有不同,因為大多數 Webpack 模版處理器(比如 pug-loader)會返回模版處理函式,而不是編譯的 HTML 字串,我們使用原始的 pug 替代 pug-loader:

npm install pug --save-dev
<template lang="pug">
div
  h1 Hello world!
</template>

重要: 如果你使用 [email protected]<8.2.0, 你還需要安裝 template-html-loader。

10:資源路徑處理

預設情況下,vue-loader 使用 css-loader 和 Vue 模版編譯器自動處理你的樣式和模版檔案。在編譯過程中,所有的資源路徑例如 , background: url(…) 和 @import 會作為模組依賴。

例如,url(./image.png) 會被轉換為 require(‘./image.png’) 
因為 .png 不是一個 JavaScript 檔案,你需要配置 Webpack 使用 file-loader 或者 url-loader 去處理它們。vue-cli 腳手器工具已經為你配置好了

使用它們的好處: 
(1)file-loader 可以指定要複製和放置資原始檔的位置,以及如何使用版本雜湊命名以獲得更好的快取。此外,這意味著 你可以就近管理你的圖片檔案,可以使用相對路徑而不用擔心佈署時URL問題。使用正確的配置,Webpack 將會在打包輸出中自動重寫檔案路徑為正確的URL。

(2)url-loader 允許你有條件將檔案轉換為內聯的 base-64 URL(當檔案小於給定的閾值),這會減少小檔案的 HTTP 請求。如果檔案大於該閾值,會自動的交給 file-loader 處理。

11:Loader 進階配置

module.exports = {
  // other options...
  module: {
    // module.rules 與 1.x中的 module.loaders 相同
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          // `loaders` 覆蓋預設 loaders.
          // 以下配置會導致所有的 <script> 標籤 "lang" 屬性失效。
          // attribute to be loaded with coffee-loader
          loaders: {
            js: 'coffee-loader'
          },

          // `preLoaders` 會在預設 loaders 之前載入.
          // 你可以用來預處理語言塊 - 一個例子是用來處理構建時的 i18n
          preLoaders: {
            js: '/path/to/custom/loader'
          },

          // `postLoaders` 會在預設 loaders 之後載入.
          //
          // - 對於 `html`, 預設 loader 返回會編譯為 JavaScript 渲染函式
          //
          // - 對於 `css`, 由`vue-style-loader` 返回的結果通常不太有用。使用 postcss 外掛將會是更好的選擇。
          postLoaders: {
            html: 'babel-loader'
          }

          // `excludedPreLoaders` 應是正則表示式
          excludedPreLoaders: /(eslint-loader)/
        }
      }
    ]
  }
}

12:提取CSS檔案

npm install extract-text-webpack-plugin --save-dev



// webpack.config.js
var ExtractTextPlugin = require("extract-text-webpack-plugin")

module.exports = {
  // other options...
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            css: ExtractTextPlugin.extract({
              use: 'css-loader',
              fallback: 'vue-style-loader' // <- 這是vue-loader的依賴,所以如果使用npm3,則不需要顯式安裝
            })
          }
        }
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("style.css")
  ]
}