vue+vuecli+webapck2实现多页面应用
准备工作
在本地用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.assetsSubDirectory
- return 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 plugin
- function 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.html
- return {
- 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 development
- devtool: '#cheap-module-eval-source-map',
- plugins: [
- new webpack.DefinePlugin({
- 'process.env': config.dev.env
- }),
- // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
- new 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.env
- var 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.html
- new webpack.DefinePlugin({
- 'process.env': env
- }),
- new webpack.optimize.UglifyJsPlugin({
- compress: {
- warnings: false
- },
- sourceMap: true
- }),
- // extract css into its own file
- new 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 file
- new webpack.optimize.CommonsChunkPlugin({
- name: 'vendor',
- minChunks: function (module, count) {
- // any required modules inside node_modules are extracted to vendor
- return (
- 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 updated
- new webpack.optimize.CommonsChunkPlugin({
- name: 'manifest',
- chunks: ['vendor']
- }),
- // copy custom static assets
- new 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').BundleAnalyzerPlugin
- webpackConfig.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,但现在由于是多页面,因此入口页面多了,我目前就是两个:index和cell,之后如果打包,就会在dist
文件下生成两个HTML文件:index.html
和cell.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+vuecli+webapck2实现多页面应用的更多相关文章
- vue+vuecli+webapck2项目配置文件详解
1.文件结构 ├─build │ ├─build.js │ ├─check-versions.js │ ├─dev-client.js │ ├─dev-server.js │ ├─utils.js │ ...
- 使用Vue和djangoframwork完成登录页面构建 001
使用Vue和djangoframwork完成登录页面构建 001 环境的搭建 首先,我在我的电脑的F盘创建了一个文件夹 forNote,进入到这个文件夹中 F:\forNote> vue环境的搭 ...
- 基于VUE选择上传图片并在页面显示(图片可删除)
demo例子: 依赖文件 : http://files.cnblogs.com/files/zhengweijie/jquery.form.rar HTML文本内容: <template> ...
- vue+vue-cli+淘宝lib-flexible做移动端自适应
总结用vue+vue-cli+淘宝lib-flexible做移动端自适应方案: 1.安装淘宝lib-flexible npm install lib-flexible --save 2.在入口文价ma ...
- vue中如何缓存一些页面
在vue中,有时候我们只想缓存页面中的一些组件或页面,这个时候怎么办呢,我们就需要用判断来加载keep-alive. 例如: // router.js { path: "/driving_l ...
- Vue数据产生变化需要页面渲染完之后执行某操作
1.数据产生变化或者页面需要vue数据渲染完之后加载的东西 Vue.nextTick(function () { alert(123); }); 2 调用vue方法 --------------Vue ...
- 8种Vue中数据更新了但页面没有更新的情况
目录 1.Vue 无法检测实例被创建时不存在于 data 中的 属性 2. Vue 无法检测'对象属性'的添加或移除 3.Vue 不能检测利用数组索引直接修改一个数组项 4.Vue 不能监测直接修改数 ...
- vue+vuecli+webpack中使用mockjs模拟后端数据
前言 使用mockjs可以事先模拟数据,前提是和后端约定好了数据接口,怎样的数据.使用mock就可以生成你要的数据了,从而实现开发时前后端分离. 其主要功能是: 基于数据模板生成模拟数据. 基于HTM ...
- VUE (vue-cli)脚手架项目说明
1. 概述 1.1 说明 使用vue-cli快速创建的vue项目目录如下: build -- webpack相关配置以及服务启动文件,配置多依赖于下边的config文件夹中内容 config -- ...
随机推荐
- 【RL-TCPnet网络教程】第33章 SMTP简单邮件传输协议基础知识
第33章 SMTP简单邮件传输协议基础知识 本章节为大家讲解SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)的基础知识,方便后面章节的实战操作. (本 ...
- LeetCode724. 寻找数组的中心索引
1.题目描述 给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法. 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和. 如果数组不存在中 ...
- 如何将项目上传到GitHub?
如何将项目上传到GitHub? 1.注册GitHub账户 浏览器输入GitHub官网地址:https://github.com/ 进入后点击Sign In 然后点击Create an account ...
- Underscore.js 源码学习笔记(下)
上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...
- 死磕 java集合之CopyOnWriteArrayList源码分析
欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 CopyOnWriteArrayList是ArrayList的线程安全版本,内部也是通过 ...
- C#版 - Leetcode 215. Kth Largest Element in an Array-题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...
- Python和C++的混合编程(使用Boost编写Python的扩展包)
想要享受更轻松愉悦的编程,脚本语言是首选.想要更敏捷高效,c++则高山仰止.所以我一直试图在各种通用或者专用的脚本语言中将c++的优势融入其中.原来贡献过一篇<c++和js的混合编程>也是 ...
- SpringBoot入门教程(二十)Swagger2-自动生成RESTful规范API文档
Swagger2 方式,一定会让你有不一样的开发体验:功能丰富 :支持多种注解,自动生成接口文档界面,支持在界面测试API接口功能:及时更新 :开发过程中花一点写注释的时间,就可以及时的更新API文档 ...
- 初探Java设计模式3:行为型模式(策略,观察者等)
行为型模式 行为型模式关注的是各个类之间的相互作用,将职责划分清楚,使得我们的代码更加地清晰. 策略模式 策略模式太常用了,所以把它放到最前面进行介绍.它比较简单,我就不废话,直接用代码说事吧. 下面 ...