webpack配合vue.js實現完整的單頁面demo

本篇文章主要是我在開發前研究了webpack+vue.js的單頁面應用,由於須要用到node的npm,因此確保安裝了node,建議官網安裝最新的穩定版本。而且在項目中須要加載一些npm包,因爲npm的服務器在國外,可能咱們下載的過程會比較慢,因此建議用阿里的鏡像cnpm安裝,10分鐘實時更新一次npm的鏡像。具體的下載配置參考阿里的cnpm官網。本文章只是和你們探討怎麼利用webpack配合vue.js作一個單頁面應用,具體關於vue裏面的內容怎麼寫並不在本篇文章的介紹範圍。具體請參考官方文檔,裏面作了詳細的vue的語法介紹.javascript

建議閱讀前準備內容

1. 定義咱們demo的基本目錄

├── README.md           
├── index.html         // 項目入口文件
├── package.json       // 項目配置文件
├── src                // 生產目錄
│   ├── vue         // 組件
│   |    ├──home.vue
│   |    ├──blog.vue
│   |    ├──about.vue
│   |    ├──topic.vue
│   ├── components     // 各類組件
│   ├── views          // css文件
│   ├── scss               //scss文件
│   └── main.js        // Webpack 預編譯入口
└── webpack.js  // Webpack 配置文件

2. 配置一下咱們的webpack.js文件

在介紹怎麼配置以前你須要掌握一個命令 npm install <模塊> --save-dev這個命令的意思是這個命名的意思是咱們安裝了這個包而且把它的基本信息寫入目錄的package.json文件。還有一個命令是咱們直接運行cnpm install會自動下載package.json裏面寫入的包.java

在webpack的配置文件咱們須要用到四個npm的模塊分別是:pathwebpackextract-text-webpack-plugin,vue-loader記得先下載包在用require命令引入進來node

//node的路徑模塊
var path=require('path');
//咱們是webpack固然要引入這個
var webpack = require('webpack');
//這個是構建頁面資源的插件
var ExtractTextPlugin = require('extract-text-webpack-plugin');
//由於咱們是vue.js的應用,把各個組件當作一個頁面.vue後綴,因此引入這個能夠編譯這些文件
var vue = require("vue-loader");

好了,咱們已經把須要的模塊引入進來了,接下來咱們定義一些接下來要用到的一些文件夾路徑webpack

//__dirname是node裏面的一個變量,指向的是當前文件夾目錄
var ROOT_PATH = path.resolve(__dirname);
//這個咱們的文件入口,等下咱們就會從main.js這個文件做爲入口
var APP_PATH = path.resolve(ROOT_PATH, 'src/main.js');
//這個是文件打包出來的輸出路徑
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');

基本的文件路徑咱們已經定義好了,接下來咱們要用到extract-text-webpack-plugin這個插件了git

var plugins = [
  //提公用js到common.js文件中
  new webpack.optimize.CommonsChunkPlugin('common.js'),
  //將樣式統一發布到style.css中
  new ExtractTextPlugin("style.css"),
 // 使用 ProvidePlugin 加載使用率高的依賴庫
  new webpack.ProvidePlugin({
    $: 'webpack-zepto'
  })
];

接下來是webpack的重點了loader,webpack的思想是把每一個靜態資源文件當作一個模塊加載,咱們須要作一些配置,在這裏咱們須要用到編譯css,sass模塊,多以咱們還須要安裝'css-loader','style-loader','node-sass','md5'es6

module.exports = {
     //文件的入口,還能夠寫成多數組的形式,具體本身擴展
     entry:[APP_PATH],
     //輸出
     output:{
         //輸出路徑
         path: BUILD_PATH,
         //打包的js命名
         filename:build.js'
         // 指向異步加載的路徑
         publicPath : __dirname + '/build/',
         // 非主文件的命名規則,加緩存用到md5
         chunkFilename: '[id].build.js?[chunkhash]'
     },
     module: {
         loaders: [
              {
                test: /\.vue$/,
                loader: 'vue',
              },
              {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract("style-loader", 'css-loader')
              },
              {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract("style-loader", "css-loader")
              },
              {
                test: /\.(png|jpg)$/,
                loader: 'url?limit=40000'
              }
         ]
    },
  //這個特別說明下,vue提倡把一個組件當作一個頁面,因此可能在一個頁面寫html,style,javascript,也能夠引入和寫scss文件
  vue: {
    css: ExtractTextPlugin.extract("css"),
    sass: ExtractTextPlugin.extract("css!sass-loader")
  },
  plugins: plugins
}

3. 配置咱們的入口文件main.js

這裏咱們須要三個npm模塊,vue,vue-router,vue-resource三個模塊,咱們依次安裝而後在引入github

//vue的應用固然要引,等下要用它來註冊
var Vue = require('vue')
//這個是路由,spa應用必要哦
var VueRouter = require('vue-router');
//這個是相似ajax請求,確定要拉去數據啦,因此也下載吧
var VueResource = require('vue-resource');

在vue裏面聲明並註冊個空組件

Vue.use(VueRouter);
Vue.use(VueResource);
var app = Vue.extend({});

實例化VueRounter

var router = new VueRouter({
    // 當hashbang的值爲true時,全部的路徑都會被格式化已#!開頭,
    hashbang: true,
    history: false,
    saveScrollPosition: true,
    transitionOnLoad: true
});

接下來寫下咱們的路由路徑,也能夠單獨把路由寫在一個文件,咱們這邊只是個demo因此寫一塊兒了,不打緊,關於這塊路由的寫法能夠具體參考下vue-router的文檔http://router.vuejs.org/zh-cn...,將的很詳細。

這裏有必要將一下,webpack提供了異步加載功能,配合vue-router的路由使用,當哪一個組件須要渲染是,會加載它依賴的組件,而且異步加載進來。是否是很棒。

router.map({
     '/':{                    //首頁
        component: function (resolve) {
           require(['./vue/home.vue'],resolve)
         }
    },
    '/home':{
        name : 'home',                    //首頁
        component: function (resolve) {
           require(['./vue/home.vue'],resolve)
         }
    },
    '/blog':{
         name : 'blog',               //博客列表
        component: function (resolve) {
           require(['./vue/blog.vue'],resolve)
         }
    },
    '/blog/topic':{
         name : 'topic',
         //文章詳情
         component: function (resolve) {
           require(['./vue/topic.vue'],resolve)
         }
    },
    '/about':{
         name : 'about',
         //關於
         component: function (resolve) {
           require(['./vue/about.vue'],resolve)
         }
    }
})

再加句代碼,測試訪問路由訪問是否成功

router.afterEach(function (transition) {
  console.log('成功瀏覽到: ' + transition.to.path)
})

最後咱們註冊下vue

router.start(app, "#app");

4. 填充下index.html文件的結構

<router-view> 用於渲染匹配的組件,它基於 Vue 的動態組件系統。咱們的index.html結構是這樣子的

<!DOCTYPE html>
<html lang="en">
<head>
     <meta charset="UTF-8">
     <title>我的站</title>
     <link rel="stylesheet" href="./build/style.css">
</head>
<body>
     <div id="app">    
        <router-view></router-view>
    </div>
    <script src="./build/common.js"></script>
    <script src="./build/build.js"></script>
</body>
</html>

5. 怎麼寫一個組件

關於組件,vue提倡一個模塊寫一個具體的組件好比列表組件能夠list.vue,而後根據路由加載具體的組件,組件之間也能夠相互的引用,具體參考vue文檔。

爲了方便咱們測試,咱們以home爲例,其餘組件也相似,方便等下測試,等項目能完整跑起來你在本身去添加組件裏面的內容。

<template>
     <div>home</div>
</template>
<script>
     // js
</script>
<style>
     /*style*/
</style>

6. 運行webpack

關於一個單頁面的大致的框架咱們已經搭建好了,如今直接運行webpack就能把文件載出來了。而後打開index.html直接測試就行了。更詳細的demo已經提交到github上了 demo,還有本人使用webpack+vue+es6+sass的技術棧重構的Cnode中文網單頁面應用,感興趣的能夠圍觀下,歡迎star。

7.開發模式

在實際開發過程當中咱們確定不是每一次修改保存,而後在運行一下webpack命令,那樣就太麻煩了,因此咱們用到了熱替換,webpack-dev-server這個包,安裝好這個包後在pack.json加上

"scripts": {
    "start": "webpack-dev-server --hot --inline"
}

而且把webpack.config.js這前咱們配置好的

// 指向異步加載的路徑
 publicPath : __dirname + '/build/';

替換爲

// 指向異步加載的路徑
 publicPath : '/build/';

爲何這樣作呢?由於咱們這前用webpack是把組件異步加載在本地上,而咱們用了熱替換後是地址委託到了http://localhost:8080/端口了,因此要去掉__dirname(指向本地根目錄),一切準備完畢了,接下來直接運行npm start,而後打開http://localhost:8080/就能夠訪問,試着修改內容保存能夠看看頁面實時的在刷新,是否是省了不少的開發時間呢!

關於vue-cli

vue.js的原做者爲了方便咱們作項目前期花費時間配置這些自動化構建工具,出了一個vue-cli的腳手架,能夠自動生成項目的一系列基本配置。vue-cli的github地址爲https://github.com/vuejs/vue-cli,感興趣的童鞋能夠去了解下。

關於vue2.0

2.0已經出來了,相信之後你們也要慢慢跟上2.0的版本了,2.0在1.0的基礎上構建這邊有一點點和1.0的區別,聽我講來。
在評論裏有位同窗說2.0已經不支持1.0的路由方式了,恩,的確是,這裏我把2.0的路由方式從新寫了下。

var Vue = require('vue');
var VueRouter = require('vue-router');
Vue.use(VueRouter);
const Home = resolve => {
    require.ensure(['./vue/home.vue'], () => {
        resolve(require('./vue/home.vue'));
    });
};
const List = resolve => {
    require.ensure(['./vue/list.vue'], () => {
        resolve(require('./vue/list.vue'));
    });
};
const routes = [{
        path: '/',
        name: 'home',
        component: Home
    },{
        path: '/list',
        name: 'list',
        component: List
    },{
        path: '*',
        component: Home
    }];
const router = new VueRouter({
    mode: 'history',
    routes
});
new Vue({
    router
}).$mount('#app');

更多有關於路由的問題請參考vue-router2.0中文文檔
還有一點問題是若是是用webpack構建項目的時候,要在webpack.confing.js的配置文件加上

resolve: {
    alias: {
      'vue$': 'vue/dist/vue.js'
    }
 }

由於vue2.0有兩種構建模式,默認狀況下運行構建,可是不能解析單文件的template模板,因此要使用獨立構建。具體能夠參考vue2.0中文文檔,其餘一些關於語法的改變看下2.0的文檔就好了,還有vuex不被2.0影響,能夠兼容。

寄語:

以爲本篇文章對你有幫助的話能夠關注我一下,後期會出一些關於基於vue.js開發單頁面開發心得,謝謝!
代碼已上傳在github

相關文章
相關標籤/搜索