vue多页实践-开发

vue多页实践-开发,第1张

环境 node v12.5.0系统 winvuecli @vue/cli 4.5.15ide WebStorm 2021.1 x64 本文是将vue-cli创建的spa应用改造为多页应用。

我们可以把多页应用理解为由多个单页构成的应用,而何谓多个单页呢?其实你可以把一个单页看成是一个 html 文件,那么多个单页便是多个 html 文件,多页应用便是由多个 html 组成的应用,如下图所示:

文章 示例代码仓库 建议先大概看一遍文章-在看示例代码。 开始改造 更改目录 多页应用的每个单页都可以拥有单页应用 src 目录下的文件及功能在 src 下新建 pages 文件夹,将 public文件夹中 index.html、src 文件夹中 App.vue、main.js 复制到相应的应用文件夹内修改文件名称,然后删除即可。创建如下图所示文件目录,文件夹的名称不做要求但需要同名的入口js、html文件边配置多页会用到。拿index文件夹来举例说明 index.js 相当于 main.jsindex.html 相当于 public文件夹中 index.htmlindex.vue 相当于 src 文件夹中 App.vue src 下的 router、store 文件夹保留与否 看具体场景,是所用应用共用一个还是需要分开。比如应用的 router、store 文件差别很大,那就需要分开或者使用命名空间,如果几乎一样那就可以共用一个文件(数据不共享)。

更改 vue.config.js 这里先看下 vuecli 文档

单页应用中入口文件默认指定 main.js,多页应用入口文件则包含了 page1.js、page2.js、index.js等,数量取决于 pages 文件夹下目录的个数,动态生成 pages 对象是一个很好的选择。 动态获取 pages 对象 安装 yarn add glob 扫描文件夹,并返回我们需要的文件
const path = require('path')
const glob = require('glob')

// 配置pages多页面获取当前文件夹下的html和js
function getEntry (globPath) {
  const entries = {}
  let basename
  let tmp
  let pathname
  glob.sync(globPath).forEach(function (entry) {
    basename = path.basename(entry, path.extname(entry))
    tmp = entry.split('/').splice(-3)
    pathname = basename // 正确输出js和html的路径
    entries[pathname] = {
      entry: 'src/' + tmp[0] + '/' + tmp[1] + '/' + tmp[1] + '.js',
      template: 'src/' + tmp[0] + '/' + tmp[1] + '/' + tmp[2],
      title: tmp[2],
      filename: tmp[2],
      chunks: ['chunk-vendors', 'chunk-common', tmp[1]]
    }
  })
  return entries
}

const pages = getEntry('./src/pages/**?/*.html')
获取到的对象 可以在 vue.config.js 进行打印
vue.config.js 中的 module.exports 对象写入多页配置(也就是比单页多了一个 pages 配置)

配置动态引入js css文件 配置动态引入需要使用 html-webpack-plugin 插件,多页会存在多个配置 只配置一个就会抛错 如下图。

错误也让人摸不着头脑
可以这样做

html使用动态配置的 js,css 图中红框为模板语法具体查看文档

完整的配置
const path = require('path')
const glob = require('glob')

// 配置pages多页面获取当前文件夹下的html和js
function getEntry (globPath) {
  const entries = {}
  let basename
  let tmp
  let pathname
  glob.sync(globPath).forEach(function (entry) {
    basename = path.basename(entry, path.extname(entry))
    tmp = entry.split('/').splice(-3)
    pathname = basename // 正确输出js和html的路径
    entries[pathname] = {
      entry: 'src/' + tmp[0] + '/' + tmp[1] + '/' + tmp[1] + '.js',
      template: 'src/' + tmp[0] + '/' + tmp[1] + '/' + tmp[2],
      title: tmp[2],
      filename: tmp[2],
      chunks: ['chunk-vendors', 'chunk-common', tmp[1]]
    }
  })
  return entries
}

const pages = getEntry('./src/pages/**?/*.html')

module.exports = {
  pages,
  publicPath: '/',
  outputDir: 'dist',
  assetsDir: 'assets',
  filenameHashing: true,
  lintOnSave: true,
  productionSourceMap: false,
  devServer: {
    index: 'index.html', // 默认启动serve 打开的页面
    host: '0.0.0.0',
    port: 8889,
    https: false,
    hotOnly: false,
    proxy: null
  },
  chainWebpack: config => {
    Object.keys(pages).forEach(entryName => {
      // 配置动态引入js、css
      config
        .plugin(`html-${entryName}`)
        .tap(args => {
          args[0].cdn = []
          return args
        })

      config.plugins.delete(`prefetch-${entryName}`)
    })
  }
}
运行-打包 上述配置运行 npm run serve 会运行所有应用
+ index 访问 `http://localhost:8889/#/`
+ page1 访问 `http://localhost:8889/page1/#/`
+ page2 访问 `http://localhost:8889/page2/#/`

上述的配置运行 运行npm run build 会打包所有应用

打包后访问应用(使用node库 http-server), 默认会访问index.html 所以除了 index 外其他应用访问需要指定 html文件 index 访问 http://localhost:8889/#/page1 访问 http://localhost:8889/page1.html/#/page2 访问 http://localhost:8889/page2.html/#/ 所以使用路径做一些判断的时候需要自行处理 比如 使用字符换替换html 等无关字符。

打包单一应用-以page1文件夹为例 多个页面 pages 多个配置,同理可得 单个应用 pages 只有一个配置。这样也就需要有一个配置的地方,这里使用env文件配置。

根目录新建 .env、.env.dev_page1、.env.pro_page1 并写入对应数据。 .env 所有环境都被载入 在默认打包所有应用时使用.env.dev_page1 dev 本地开发时加载.env.pro_page1 pro 打包后加载

更改 package.jsonscripts配置

修改vue.config.js 完整代码可在示例仓库中找到

优化 上述 动态配置js,css写死了两示例,同样可以将数据配置在 .env文件中,指定环境加载指定文件多个入口js文件,引入文件 配置重复,可以提取出一个公共的js,导出一个初始化 vue 的函数,将store、router传进去做初始化。其他压缩打包体积等不在 本文讨论范围 (各位想必都有一手绝活!!!) 参考文章

+掘金小册 Vue 项目构建与开发入门

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1324670.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存