准备工作

在本地用vue-cli新建一个项目,首先安装vue-cil,命令:

npm install -g vue-cli

新建一个vue项目,创建一个基于"webpack"的项目,项目名为vuedemo:

vue init webpack vuedemo

这里有一个地方需要改一下,在执行npm install命令之前,在package.json里添加一个依赖,后面会用到。

修改webpack配置

项目目录

├── README.md
├── build
│   ├── build.js
│   ├── check-versions.js
│   ├── dev-client.js
│   ├── dev-server.js
│   ├── utils.js
│   ├── vue-loader.conf.js
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   └── webpack.prod.conf.js
├── config
│   ├── dev.env.js
│   ├── index.js
│   └── prod.env.js
├── package.json
├── src
│   ├── assets
│   │   └── logo.png
│   ├── components
│   │   ├── Hello.vue
│   │   └── cell.vue
│   └── pages
│       ├── cell
│       │   ├── cell.html
│       │   ├── cell.js
│       │   └── cell.vue
│       └── index
│           ├── index.html
│           ├── index.js
│           ├── index.vue
│           └── router
│               └── index.js
└── static

在这一步里我们需要改动的文件都在build文件下,分别是:

  • utils.js
  • webpack.base.conf.js
  • webpack.dev.conf.js
  • webpack.prod.conf.js

utils.js文件

// utils.js文件var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')exports.assetsPath = function (_path) {var assetsSubDirectory = process.env.NODE_ENV === 'production' ?config.build.assetsSubDirectory :config.dev.assetsSubDirectoryreturn path.posix.join(assetsSubDirectory, _path)
}exports.cssLoaders = function (options) {options = options || {}var cssLoader = {loader: 'css-loader',options: {minimize: process.env.NODE_ENV === 'production',sourceMap: options.sourceMap}}// generate loader string to be used with extract text pluginfunction generateLoaders(loader, loaderOptions) {var loaders = [cssLoader]if (loader) {loaders.push({loader: loader + '-loader',options: Object.assign({}, loaderOptions, {sourceMap: options.sourceMap})})}// Extract CSS when that option is specified// (which is the case during production build)if (options.extract) {return ExtractTextPlugin.extract({use: loaders,fallback: 'vue-style-loader'})} else {return ['vue-style-loader'].concat(loaders)}}// https://vue-loader.vuejs.org/en/configurations/extract-css.htmlreturn {css: generateLoaders(),postcss: generateLoaders(),less: generateLoaders('less'),sass: generateLoaders('sass', { indentedSyntax: true }),scss: generateLoaders('sass'),stylus: generateLoaders('stylus'),styl: generateLoaders('stylus')}
}// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {var output = []var loaders = exports.cssLoaders(options)for (var extension in loaders) {var loader = loaders[extension]output.push({test: new RegExp('\\.' + extension + '$'),use: loader})}return output
}/* 这里是添加的部分 ---------------------------- 开始 */// glob是webpack安装时依赖的一个第三方模块,还模块允许你使用 *等符号, 例如lib/*.js就是获取lib文件夹下的所有js后缀名的文件
var glob = require('glob')
// 页面模板
var HtmlWebpackPlugin = require('html-webpack-plugin')
// 取得相应的页面路径,因为之前的配置,所以是src文件夹下的pages文件夹
var PAGE_PATH = path.resolve(__dirname, '../src/pages')
// 用于做相应的merge处理
var merge = require('webpack-merge')//多入口配置
// 通过glob模块读取pages文件夹下的所有对应文件夹下的js后缀文件,如果该文件存在
// 那么就作为入口处理
exports.entries = function () {var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')var map = {}entryFiles.forEach((filePath) => {var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))map[filename] = filePath})return map
}//多页面输出配置
// 与上面的多页面入口配置相同,读取pages文件夹下的对应的html后缀文件,然后放入数组中
exports.htmlPlugin = function () {let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')let arr = []entryHtml.forEach((filePath) => {let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))let conf = {// 模板来源template: filePath,// 文件名称filename: filename + '.html',// 页面模板需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本chunks: ['manifest', 'vendor', filename],inject: true}if (process.env.NODE_ENV === 'production') {conf = merge(conf, {minify: {removeComments: true,collapseWhitespace: true,removeAttributeQuotes: true},chunksSortMode: 'dependency'})}arr.push(new HtmlWebpackPlugin(conf))})return arr
}
/* 这里是添加的部分 ---------------------------- 结束 */

webpack.base.conf.js 文件

// webpack.base.conf.js 文件var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')function resolve(dir) {return path.join(__dirname, '..', dir)
}module.exports = {/* 修改部分 ---------------- 开始 */entry: utils.entries(),/* 修改部分 ---------------- 结束 */output: {path: config.build.assetsRoot,filename: '[name].js',publicPath: process.env.NODE_ENV === 'production' ?config.build.assetsPublicPath :config.dev.assetsPublicPath},resolve: {extensions: ['.js', '.vue', '.json'],alias: {'vue$': 'vue/dist/vue.esm.js','@': resolve('src'),'pages': resolve('src/pages'),'components': resolve('src/components')}},module: {rules: [{test: /\.vue$/,loader: 'vue-loader',options: vueLoaderConfig},{test: /\.js$/,loader: 'babel-loader',include: [resolve('src'), resolve('test')]},{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader: 'url-loader',options: {limit: 10000,name: utils.assetsPath('img/[name].[hash:7].[ext]')}},{test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,loader: 'url-loader',options: {limit: 10000,name: utils.assetsPath('fonts/[name].[hash:7].[ext]')}}]}
}

webpack.dev.conf.js 文件

var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})module.exports = merge(baseWebpackConfig, {module: {rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })},// cheap-module-eval-source-map is faster for developmentdevtool: '#cheap-module-eval-source-map',plugins: [new webpack.DefinePlugin({'process.env': config.dev.env}),// https://github.com/glenjamin/webpack-hot-middleware#installation--usagenew webpack.HotModuleReplacementPlugin(),new webpack.NoEmitOnErrorsPlugin(),// https://github.com/ampedandwired/html-webpack-plugin/* 注释这个区域的文件 ------------- 开始 */// new HtmlWebpackPlugin({//   filename: 'index.html',//   template: 'index.html',//   inject: true// }),/* 注释这个区域的文件 ------------- 结束 */new FriendlyErrorsPlugin()/* 添加 .concat(utils.htmlPlugin()) ------------------ */].concat(utils.htmlPlugin())
})

webpack.prod.conf.js 文件

var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')var env = config.build.envvar webpackConfig = merge(baseWebpackConfig, {module: {rules: utils.styleLoaders({sourceMap: config.build.productionSourceMap,extract: true})},devtool: config.build.productionSourceMap ? '#source-map' : false,output: {path: config.build.assetsRoot,filename: utils.assetsPath('js/[name].[chunkhash].js'),chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')},plugins: [// http://vuejs.github.io/vue-loader/en/workflow/production.htmlnew webpack.DefinePlugin({'process.env': env}),new webpack.optimize.UglifyJsPlugin({compress: {warnings: false},sourceMap: true}),// extract css into its own filenew ExtractTextPlugin({filename: utils.assetsPath('css/[name].[contenthash].css')}),// Compress extracted CSS. We are using this plugin so that possible// duplicated CSS from different components can be deduped.new OptimizeCSSPlugin({cssProcessorOptions: {safe: true}}),// 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'// }),/* 注释这个区域的内容 ---------------------- 结束 */// split vendor js into its own filenew webpack.optimize.CommonsChunkPlugin({name: 'vendor',minChunks: function (module, count) {// any required modules inside node_modules are extracted to vendorreturn (module.resource &&/\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0)}}),// extract webpack runtime and module manifest to its own file in order to// prevent vendor hash from being updated whenever app bundle is updatednew webpack.optimize.CommonsChunkPlugin({name: 'manifest',chunks: ['vendor']}),// copy custom static assetsnew CopyWebpackPlugin([{from: path.resolve(__dirname, '../static'),to: config.build.assetsSubDirectory,ignore: ['.*']}])/* 该位置添加 .concat(utils.htmlPlugin()) ------------------- */].concat(utils.htmlPlugin())
})if (config.build.productionGzip) {var CompressionWebpackPlugin = require('compression-webpack-plugin')webpackConfig.plugins.push(new CompressionWebpackPlugin({asset: '[path].gz[query]',algorithm: 'gzip',test: new RegExp('\\.(' +config.build.productionGzipExtensions.join('|') +')$'),threshold: 10240,minRatio: 0.8}))
}if (config.build.bundleAnalyzerReport) {var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginwebpackConfig.plugins.push(new BundleAnalyzerPlugin())
}module.exports = webpackConfig

至此,webpack的配置就结束了。

文件结构

├── src
│   ├── assets
│   │   └── logo.png
│   ├── components
│   │   ├── Hello.vue
│   │   └── cell.vue
│   └── pages
│       ├── cell
│       │   ├── cell.html
│       │   ├── cell.js
│       │   └── cell.vue
│       └── index
│           ├── index.html
│           ├── index.js
│           ├── index.vue
│           └── router
│               └── index.js

src就是我所使用的工程文件了,assets,components,pages分别是静态资源文件、组件文件、页面文件。

原先,入口文件只有一个main.js,但现在由于是多页面,因此入口页面多了,我目前就是两个:indexcell,之后如果打包,就会在dist文件下生成两个HTML文件:index.htmlcell.html(可以参考一下单页面应用时,打包只会生成一个index.html,区别在这里)。

页面跳转问题

既然是多页面,肯定涉及页面之间的互相跳转,就按照我这个项目举例,从index.html文件点击a标签跳转到cell.html。

一般都认为这样写:

 <!-- index.html -->
<a href='../cell/cell.html'></a>

但这样写,不论是在开发环境还是最后测试,都会报404,找不到这个页面。

改成这样既可:

 <!-- index.html -->
<a href='cell.html'></a>

如果想跳转到另外一个路由配置的某个模块,如账号中心,如下例子:

<a class="home_account" href="login.html#/inner/acount/acountCenter">{{userInfo.phone}}</a>

参考地址

  • 用vue构建多页面应用
  • vue-cli实现多页面多路由
  • vue-cli + webpack 多页面实例应用
  • Webpack-dev-server and Jest
  • Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇——纯前端多页面)
  • Vue.js 服务器端渲染指南

vue+vuecli+webapck2实现多页面应用相关推荐

  1. 【骨架屏】【vue】如何在webpack+vue+vue-cli下搭建多模块/单模块多路由骨架屏

    如何在webpack+vue+vue-cli下搭建多模块/单模块多路由骨架屏 前言 骨架屏的用户感知比loading更好,此前看过很多专栏以及文章,此次实践中还是遇到需要学习的部分. 对于骨架屏或者占 ...

  2. vue(vue-cli+vue-router)+babel+webpack项目搭建入门(四)

    vue(vue-cli+vue-router)+babel+webpack项目搭建入门<四> 本系列文章将介绍基于vue+webpack的前端项目的构建过程.文章分为四章内容,第一章介绍开 ...

  3. vue(vue-cli+vue-router)+babel+webpack项目搭建入门(三)

    vue(vue-cli+vue-router)+babel+webpack项目搭建入门<三> 本系列文章将介绍基于vue+webpack的前端项目的构建过程.文章分为四章内容,第一章介绍开 ...

  4. vue(vue-cli+vue-router)+babel+webpack项目搭建入门 (第一步)

    vue(vue-cli+vue-router)+babel+webpack项目搭建入门<一> 本系列文章将介绍基于vue+webpack的前端项目的构建过程.文章分为四章内容,第一章介绍开 ...

  5. Asp.net+Vue2构建简单记账WebApp之六(vue.js构建记账统计页面)

    Asp.net+Vue2构建简单记账WebApp之一(设计) Asp.net+Vue2构建简单记账WebApp之二(使用ABP迅速搭建.Net后台) Asp.net+Vue2构建简单记账WebApp之 ...

  6. VUE还没生效,页面闪屏的问题解决办法 v-cloak

    当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码.我们可以使用 v-cloak 指令来解决这一问题. html: <div id=&quo ...

  7. 基于vue的移动web app页面缓存解决方案

    现在移动web app越来越热门了,许多公司开始尝试使用angular.react.vue等MVVM框架来开发单页架构的web app.但在开发web app时,如果希望页面的导航体验也接近原生应用, ...

  8. vue里面怎么删除部分页面_基于VUE选择上传图片并页面显示(图片可删除)

    基于VUE选择上传图片并在页面显示,图片可删除,具体内容如下 demo例子: 依赖文件: HTML文本内容: 相关照片 JS文本内容: /** * 从 file 域获取 本地图片 url */ fun ...

  9. vue中组件在不同页面中渲染出错

    vue中组件在不同页面中渲染出错 封装了一个组件 封装了一个组件 遇到问题了,特向各位大佬请教 比如我封装了一个 child 组件 我在father 页面中引入 可以正常使用 而且css 样式不会出现 ...

最新文章

  1. 【Qt】解决在linux上使用Qt的媒体模块(Qt += multimedia)缺少模块multimedia的问题
  2. 大学教师辞职创业,已向高校捐赠超10亿元!多以个人名义……
  3. “好像在哪见过你”现在有了科学解释,一群脑细胞帮你回忆那张脸 | Science
  4. 基于Python Tornado的在线问答系统
  5. 51nod 1343 行列式的根
  6. android item弹出popupwindow recycleview_Android实现RecycleView嵌套RecycleView中的item自动循环滚动功能...
  7. Android初学第87天
  8. 基于BERT的ASR纠错
  9. Jmeter html 报告中添加90% line time
  10. 关于js中的冒泡事件
  11. Android 滑动冲突问题的简单解决思路
  12. [Windows] Visio 图形怎么旋转到指定角度?
  13. Pico Neo3 4VR游戏下载地址及十大好玩游戏推荐
  14. java中solr的面试题_【索引服务器面试题】面试问题:Solr索引文… - 看准网
  15. 浏览器的同源策略,以及为什么浏览器要用同源策略。
  16. Sue Shallow
  17. 虚拟机win7 DNS 不可用
  18. python抠图精确到发丝_ps抠图有一些发丝怎么扣
  19. MySQL——SQLyog如何导出、导入数据库
  20. win10---血战上海滩

热门文章

  1. 综合时如何插入scan_三综合环境试验箱维修时如何做出正确判断?
  2. sql多层嵌套别名无效_SQL之复杂查询
  3. ediplus 复制编辑一列_vi编辑器的使用详解
  4. 手动创建线程池 效果会更好_创建更好的,可访问的焦点效果
  5. 10 个你可能还不知道 VS Code 使用技巧
  6. HybridTime - Accessible Global Consistency with High Clock Uncertainty
  7. LCD1602,4位数据总线液晶屏时钟,STC12C5A60S2的10位ADC功能程序
  8. python 测试框架
  9. [转]ORACLE 异常错误处理
  10. J2EE第五课Servlet随课笔记