vue webpack多頁面構建

項目示例地址: https://github.com/ccyinghua/webpack-multipagecss

項目運行:html

下載項目以後

# 下載依賴
npm install

# 運行
npm run dev

http://localhost:3000/login.html
http://localhost:3000/index.html

1、開發環境

node v6.11.0vue

2、安裝vue-cli腳手架

npm install vue-cli@2.8.2 -g

3、初始化項目

vue init webpack webpack-multipage  // 建立項目

cd webpack-multipage  // 進入webpack-multipage目錄

npm install  // 下載依賴

npm run dev // 運行

http://localhost:8080node

4、修改配置支持多頁面

將項目根目錄index.html,src下的文件刪除,從新調整的src結構目錄:webpack

|-- src
    |-- assets
    |-- components
    |-- entry
        |-- index    // index模塊
            |-- components
                |-- Hello.vue
            |-- router
                |-- index.js
            |-- index.html
            |-- index.js
            |-- index.vue
        |-- login    // login模塊
            |-- login.html
            |-- login.js
            |-- login.vue

(1) 修改build/util.js,在文件最後添加

# 先下載glob組件
npm install glob -D

將目錄映射成配置。如./src/entry/login/login.js變成映射{login: './src/entry/login/login.js'}nginx

var glob = require('glob');
exports.getEntries = function (globPath) {
  var entries = {}
  glob.sync(globPath).forEach(function (entry) {
    var basename = path.basename(entry, path.extname(entry), 'router.js');
    entries[basename] = entry
  });
  return entries;
}

(2) 修改build/webpack.base.conf.js,找到entry屬性,使用了uitls.js文件中新添加的方法getEntries,將entry中的js都映射成程序的入口

module.exports = {
  entry: utils.getEntries('./src/entry/*/*.js'),
  ...
}

(3) 修改build/webpack.dev.conf.js

刪除文件內原有的HtmlWebpackPlugin相關內容git

...
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
  filename: 'index.html',
  template: 'index.html',
  inject: true
}),
...

在文件最後添加github

var pages = utils.getEntries('./src/entry/*/*.html')
for(var page in pages) {
  // 配置生成的html文件,定義路徑等
  var conf = {
    filename: page + '.html',
    template: pages[page], //模板路徑
    inject: true,
    // excludeChunks 容許跳過某些chunks, 而chunks告訴插件要引用entry裏面的哪幾個入口
    // 如何更好的理解這塊呢?舉個例子:好比本demo中包含兩個模塊(index和about),最好的固然是各個模塊引入本身所需的js,
    // 而不是每一個頁面都引入全部的js,你能夠把下面這個excludeChunks去掉,而後npm run build,而後看編譯出來的index.html和about.html就知道了
    // filter:將數據過濾,而後返回符合要求的數據,Object.keys是獲取JSON對象中的每一個key
    excludeChunks: Object.keys(pages).filter(item => {
      return (item != page)
    })
  }
  // 須要生成幾個html文件,就配置幾個HtmlWebpackPlugin對象
  devWebpackConfig.plugins.push(new HtmlWebpackPlugin(conf))
}

(4) 修改build/webpack.prod.conf.js

刪除文件內原有的HtmlWebpackPlugin相關內容web

...
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
    filename: config.build.index,
    template: 'index.html',
    inject: true,
    minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
    },
    // necessary to consistently work with multiple chunks via CommonsChunkPlugin
    chunksSortMode: 'dependency'
}),
...

在文件最後添加vue-router

var pages = utils.getEntries('./src/entry/*/*.html')
for(var page in pages) {
  // 配置生成的html文件,定義路徑等
  var conf = {
    filename: page + '.html',
    template: pages[page], //模板路徑
    inject: true,
    // excludeChunks 容許跳過某些chunks, 而chunks告訴插件要引用entry裏面的哪幾個入口
    // 如何更好的理解這塊呢?舉個例子:好比本demo中包含兩個模塊(index和about),最好的固然是各個模塊引入本身所需的js,
    // 而不是每一個頁面都引入全部的js,你能夠把下面這個excludeChunks去掉,而後npm run build,而後看編譯出來的index.html和about.html就知道了
    // filter:將數據過濾,而後返回符合要求的數據,Object.keys是獲取JSON對象中的每一個key
    excludeChunks: Object.keys(pages).filter(item => {
      return (item != page)
    }),
    minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
  }
  // 須要生成幾個html文件,就配置幾個HtmlWebpackPlugin對象
  module.exports.plugins.push(new HtmlWebpackPlugin(conf))
}

(5)修改config/index.js

'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
  dev: {
    env: require('./dev.env'),  // 引入當前目錄下的dev.env.js,用來指明開發環境
    port: 3000,  // dev-server的端口號,能夠自行更改
    autoOpenBrowser: true,  // 是否自定代開瀏覽器

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    // 下面是代理表,做用是用來,建一個虛擬api服務器用來代理本機的請求,只能用於開發模式
    proxyTable: {
        "/demo/api":"http://localhost:8080"
    },

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
    
    
    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    // 是否生成css,map文件,上面這段英文就是說使用這個cssmap可能存在問題,可是按照經驗,問題不大,可使用
    cssSourceMap: false
  },

  build: {
    env: require('./prod.env'),  // 導入prod.env.js配置文件,只要用來指定當前環境

    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),  // 相對路徑的拼接
    
    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),  // 靜態資源的根目錄 也就是dist目錄
    assetsSubDirectory: 'static',  // 靜態資源根目錄的子目錄static,也就是dist目錄下面的static
    assetsPublicPath: '/',   // 靜態資源的公開路徑,也就是真正的引用路徑
    
    /**
     * Source Maps
     */
    productionSourceMap: true,   // 改爲false運行時不會出現map調試文件。;是否生成生產環境的sourcmap,sourcmap是用來debug編譯後文件的,經過映射到編譯前文件來實現
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',


    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,  // 是否在生產環境中壓縮代碼,若是要壓縮必須安裝compression-webpack-plugin
    productionGzipExtensions: ['js', 'css'],  // 定義要壓縮哪些類型的文件
    

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    // 下面是用來開啓編譯完成後的報告,能夠經過設置值爲true和false來開啓或關閉
    // 下面的process.env.npm_config_report表示定義的一個npm_config_report環境變量,能夠自行設置
    bundleAnalyzerReport: process.env.npm_config_report
  }
}
assetsRoot:執行npm run build以後,項目生成的文件放到哪一個目錄中。vue生成的文件都是靜態文件,能夠放在nginx中,也能夠放到Spring Boot項目的resources/static目錄中。
assetsPublicPath:項目的根路徑。注意,這個屬性在build、dev兩個環境都有,修改時,應該同時修改兩處。
port:這裏改爲3000,這個是在開發時,webpack-dev-server運行的端口。
proxyTable:這個屬性用於將請求轉發到指定地址去。這裏的配置意思是將全部以/demo/api開頭的請求,都轉發到http://localhost:8080地址。

5、創建頁面

index/index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>index</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

index/index.js

import Vue from 'vue'
import IndexView from './index.vue'
import router from './router'

// import VueResource from 'vue-resource';  // 使用前先npm install vue-resource --save下載vue-resource
// Vue.use(VueResource);

new Vue({
  el: '#app',
  router,
  render: h => h(IndexView)
});

index/index.vue

<template>
  <div>
    <router-view></router-view>
  </div>
</template>

<script>
  export default {
  }
</script>

<style>
</style>

index/router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '../components/Hello.vue'

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    }
  ]
})

index/components/Hello.vue

<template>
  <div>
    Hello {{ name }}
  </div>
</template>

<script>
  export default {
    data(){
      return {
        name: "admin"
      }
    },
    mounted(){
      //this.$http.get("/demo/api/userinfo").then(resp =>{
      //  this.name = resp.data.data;
      //});
    }
  }
</script>

<style>
</style>

login/login.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>login</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

login/login.js

import Vue from 'vue'
import LoginView from './login.vue'

// import VueResource from 'vue-resource';
// Vue.use(VueResource);

new Vue({
  el: '#app',
  render: h => h(LoginView)
})

login/login.vue

<template>
  <div>
    <form id="login-form">
      <label for="username">用戶名:</label>
      <input type="text" id="username" name="username">

      <br>

      <label for="password">密碼:</label>
      <input type="password" id="password" name="password"><br>

      <br>

      <button @click.prevent="submit">登陸</button>
    </form>
  </div>
</template>

<script>
  export default {
    methods:{
      submit(){
        window.location = "/demo/index.html";
        //let formData = new FormData(document.getElementById("login-form"));

        //this.$http.post("/demo/api/login", formData).then(resp => {
        //  if (resp.data.status === 200){
        //    window.location = "/index.html";
        //  }else {
        //    alert(resp.data.desc);
        //  }
        //})
      }
    }
  }
</script>

<style>
</style>

6、運行

http://localhost:3000/login.html

http://localhost:3000/index.html

相關文章
相關標籤/搜索