利用webpack和vue實現元件化
在vue中實現元件化用到了vue特有的檔案格式.vue,在每一個.vue檔案就是一個元件,在元件中我們將html,css,js全部寫入,然後在webpack中配置vue-loader就可以了。
建立vue元件
在src目錄下建立components
資料夾,並在其中建立app.vue檔案,這樣我們專案的目錄結構如下:
12345678910 |
|--dist //webpack打包後生成的資料夾| |--build.js|--node_modules //專案的依賴所在的資料夾|--src //檔案入口| |--components //元件存放資料夾 |
首先在index.hmtl中寫入程式碼:
1234567891011 |
<html lang="en"><head> <meta charset="UTF-8"> <title>Vue example</title></head> |
在編輯器中開啟app.vue檔案,寫入如下程式碼:
12345678910111213141516171819 |
<template><div class="message">{{msg}}</div> </template><script>export default { data () { return |
在main.js中寫入:
1234567 | import Vue from 'vue'import App from './components/app.vue'new Vue({ el: 'body', components:{App}}); |
這樣執行命令webpack就可以看到效果了
這裡用到了ES6的模組兒—import
,export
export
命令
export
命令用於規定模組的對外介面。一個模組就是一個獨立檔案。該檔案內的所有變數外部都無法獲取。如果希望外部能夠讀取模組內部的某個變數,就必須使用export
關鍵字對外暴露出該變數。例如:
1234 | //export.jsexport var firstName = 'Michael';export var lastName = 'Jackson';export var year = 1958; |
這樣就可以對外輸出三個變數。
import
命令
使用export
對外暴露了介面後,其他js檔案通過import
命令載入這個模組檔案。上面暴露的三個變數在另一個js檔案中引入如下:
12345 | //import.jsimport {firstName,lastName,year} from './export';function setName(element){ element.textContent = firstName + ' ' + lastName;} |
webpack的hot-reload
前端自動重新整理現在已經很常見了,即改變頁面後,瀏覽器自動重新整理,但是這個功能在我們做單頁面應用時候會很不好用,所以,webpack支援hot-reload(熱替換),當我們修改模組時候不會頁面不會重新整理,會直接在頁面中生效。
hot-reload的基礎—webpack-dev-server
webpack-dev-server支援兩種模式的自動重新整理頁面:
- iframe模式(頁面嵌入一個iframe並在其中呈現頁面的變化)
- inline模式(一個小型的webpack-dev-server客戶端會作為入口檔案打包,這個客戶端會在後端程式碼改變的時候重新整理頁面)
iframe模式
使用iframe模式無需額外的配置,在dos下輸入命令
1 | $ webpack-dev-server |
inline模式
在dos下輸入命令
1 | $ webpack-dev-server --inline --hot |
啟動伺服器,在瀏覽器中開啟 http://loacalhost:8080 就可以看到我們的頁面,此時修改app.vue中的css,以及html中的文字,都可以看到在瀏覽器中立馬呈現。
關於webpack-dev-server的詳細說明,可以參考官方文件或者部落格WEBPACK
DEV SERVER。
這裡有一個問題需要說明下
在很多文章中都說,修改app.vue檔案中script
標籤中的msg文字,會在瀏覽器中立即呈現效果,但是事實上我在做demo的時候並沒有出現這個效果,Google了很多,找到了答案,尤大說:“data是初始值,但熱更新的時候會保留當前狀態”,原問題及答案連結。
至此,關於webpack+vue的基本結束,雖然簡單,但是由於在這個過程中也遇到一些坑,所以總結下,關於對vue的研究,這才只是個開始…
附:
我的webpack配置檔案:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
var path = require('path');module.exports = { entry: './src/main.js', output: { path: './dist', publicPath:'dist/', filename: 'build.js' }, //配置自動重新整理,如果開啟會使瀏覽器重新整理而不是熱替換 /*devServer: { historyApiFallback: true, hot: false, inline: true, grogress: true },*/ module: { loaders: [ //轉化ES6語法 { test: /\.js$/, loader: 'babel', exclude: /node_modules/ }, //解析.vue檔案 { test:/\.vue$/, loader:'vue' }, //圖片轉化,小於8K自動轉化為base64的編碼 { test: /\.(png|jpg|gif)$/, loader:'url-loader?limit=8192' } ] }, vue:{ loaders:{ js:'babel' } }, resolve: { // require時省略的副檔名,如:require('app') 不需要app.js extensions: ['', '.js', '.vue'], // 別名,可以直接使用別名來代表設定的路徑以及其他 alias: { filter: path.join(__dirname, './src/filters'), |