vue+vuecli+webapck2实现多页面应用

准备工作

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

npm install -g vue-cli

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

vue init webpack vuedemo

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

修改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 服务器端渲染指南

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283821.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文把Docker、Kubernetes搞懂:什么是Docker?什么是Kubernetes?Docker和Kubernetes有什么关系和区别?通俗解释Docker、Kubernetes

一、Docker解决的问题 1、统一标准 ● 应用构建 ○ Java、C、JavaScript——编程各异 ○ 打成软件包 ○ .exe&#xff08;类似Windows&#xff0c;最终也只是生产exe执行&#xff09; ○ 使用docker build … 打包成 镜像——这就类似于exe ● 应用分享 ○ 所有软件的镜像放到一…

程序员双手飞快敲键盘的时候是在敲代码吗?

当你看到一个程序员的两只手在键盘上上下翻飞&#xff0c;行云流水的时候&#xff0c;多半不是在敲击代码大概率是在跟产品经理撕逼讨论需求另一种可能就是在跟测试打口水仗10%几率是在论坛码字摸鱼或者和人家开喷了。1%几率是在跟MM聊天可以手速飞快而不需要停下思考的代码&am…

几分钟上线一个网站 真是神器

1、ToolJet 简介 ToolJet 是一个开源的低代码框架&#xff0c;可以快速构建和部署内部工具&#xff0c;而无需工程团队付出太多努力。您可以连接到您的数据源&#xff0c;例如数据库&#xff08;如 PostgreSQL、MongoDB、Elasticsearch 等&#xff09;、API 端点&#xff08;To…

移植Python3到TQ2440(一)

平台 硬件&#xff1a;TQ2440 64MB内存 256MB NandFlashbootloader&#xff1a;U-Boot 2015.04kernel&#xff1a;linux-4.9Python: Python-3.6.0工具链&#xff1a;arm-none-linux-gnueabi-gcc 4.8.3概述 现在树莓派很火&#xff0c;在树莓派上面用户可以通过Python来控制板…

WinForm(六)组合布局属性

WinForm是基于控件的&#xff0c;不像codemark的架构&#xff0c;可以非常灵活的用mark来布局&#xff0c;它只能用控件布局属性和窗口控件来完成对UI的布局。容器控件有一组控件叫容器控件&#xff0c;对布局特别有作用&#xff0c;它们分别是&#xff1a;TableLayoutPanel&am…

Qt 网络编程

QT 网络编程 TCP 编程 模块引入 QT network 头文件 #include <QTcpServer> // TCP服务器端使用 #include <QTcpSocket> // TCP服务器和客户端都使用 编程流程 服务端 1&#xff09;实例化 QTcpServer 对象 -----------------------------> socket 2&#x…

日利率

2019独角兽企业重金招聘Python工程师标准>>> 利率计算 转载于:https://my.oschina.net/u/3342652/blog/1649028

Kafka 安装详解

注意&#xff1a;确保有JDK1.8版本及以上 官方文档&#xff1a;https://kafka.apache.org/quickstart 清华镜像下载&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/ 首先下载安装包&#xff0c;在linux及Windows都可以使用。 1. Centos 安装部署 1.1 下载 将下…

【Maui正式版】创建可跨平台的Maui程序,以及有关依赖注入、MVVM双向绑定的实现和演示...

前言&#xff1a;Maui终于在2022年8月9日推送出来了。今儿就迫不及待来把玩一下先。A、我本地已有VS2022&#xff0c;不过版本比较老&#xff0c;此处选择更新。工具 -> 获取功能和更新里面&#xff0c;可以获取到新版本更新。B、最新版本是17.3.0&#xff0c;我本地只有17.…

WebSQL存储

2019独角兽企业重金招聘Python工程师标准>>> WebSQL这种存储技术&#xff0c;相对于学过数据库的人来说&#xff0c;还是比较容易理解和上手的&#xff0c;主要就是它的存储风格和我们一般所学的SQL Server 和Oracle比较像&#xff0c;对于HTML5来说&#xff0c;当然…

抖音服务器带宽有多大,才能供上亿人同时刷?

最近看到一个有意思的提问&#xff1a;抖音服务器带宽有多大&#xff0c;为什么能够供那么多人同时刷&#xff1f;今天来给小伙伴们科普一下。 抖音&#xff0c;百度&#xff0c;阿里云&#xff0c;腾讯都是自建的数据中心&#xff0c;都是 T 级别出口带宽&#xff08;总出口带…

ASP.NET Core 5.0中的Host.CreateDefaultBuilder执行过程

通过Rider调试的方式看了下ASP.NET Core 5.0的Web API默认项目&#xff0c;重点关注Host.CreateDefaultBuilder(args)中的执行过程&#xff0c;主要包括主机配置、应用程序配置、日志配置和依赖注入配置这4个部分。由于水平和篇幅有限&#xff0c;先整体理解、建立框架&#xf…

404和302

为什么80%的码农都做不了架构师&#xff1f;>>> 404 php中用header()函数是可以为返回页面添加404的头信息的&#xff0c;从而提示浏览器该网页找不到了。 所以可以使用&#xff1a;header("HTTP/1.0 404 Not Found");或者&#xff1a;header("Stat…

oracle sqlplus使用

2019独角兽企业重金招聘Python工程师标准>>> 1、常用连接方式 sqlplus / as sysdba 无需数据库进入可用状态&#xff0c;就可用用该命令登录&#xff0c;运行startup来启动。 sqlplus username/pwdhost/service_name&#xff0c;如&#xff1a; sqlplus tiger/scott…

20款IDEA 神级插件 效率提升 30 倍,写代码必备

插件目录 1. Alibaba Java Coding Guidelines 2.GsonFormat 3.A8Translation 4.Maven Helper 5.Free Mybatis plugin 6.Grep Console 7.Lombok 8.Nyan progress bar 9.FindBugs-IDEA 10.Key Promoter X 11.JavaDoc 12.ignore 13.RainbowBrackets 14.Activate-power-mode 15.C…

【温故知新】C# Linq中 Where使用技巧

微信公众号&#xff1a;趣编程ACE关注可了解更多的.NET日常实战开发技巧&#xff0c;如需源码 后台回复 源码 即可;如果觉得对你有帮助&#xff0c;欢迎关注C# Linq中 Where使用技巧hello 大家好&#xff0c;很开心又能重新分享C#编程开发技巧了&#xff0c;之前因为工作和生活…

分布式id解决方案

文章目录 1.分布式id实现方案 1.1.uuid1.2 数据库主键自增1.3 Redis自增1.4 号段模式1.5 雪花算法&#xff08;snowflake&#xff09; 1.5.1 百度&#xff08;uid-generator&#xff09;1.5.2 美团&#xff08;Leaf&#xff09;所谓id就是能够用作唯一标识的记号。 在我们日常的…

我和大象的十年往事 - 感恩、感谢、加油、腾飞

背景 http://www.idcquan.com/Special/OSCAR2018/index.html 由中国信息通信研究院主办、中国通信标准化协会支持的"OSCAR云计算开源产业大会"于2018年3月21日&#xff0d;22日在国家会议中心举行。 非常有幸获得了“OSCAR尖峰开源人物”奖项。 奖项不敢自居&#xf…

4种分布式session解决方案

cookie和session的区别和联系 cookie是本地客户端用来存储少量数据信息的&#xff0c;保存在客户端&#xff0c;用户能够很容易的获取&#xff0c;安全性不高&#xff0c;存储的数据量小 session是服务器用来存储部分数据信息&#xff0c;保存在服务器&#xff0c;用户不容易获…

Blazor University (43)JavaScript 互操作 —— 类型安全

原文链接&#xff1a;https://blazor-university.com/javascript-interop/calling-dotnet-from-javascript/type-safety/类型安全在从 JavaScript 调用 .NET[1] 部分中&#xff0c;您可能已经注意到我们的 JavaScript 的第 6 行在将随机生成的数字传递给 .NET 之前调用了 toStr…