Vue单页应用改多页应用及跨页面组件间跳转

1.我要做一个考试系统,大部分页面是左右布局,但“考试中”的页面我需要做成上下结构,因此,需要把单页应用改为多页应用,实现在不同页面框架下的布局。

2.同时,我从A.html下的组件“考试列表”跳转到B.html下的“考试中”组件,需要实现夸页面的组件间跳转。

Vue单页应用改多页应用及跨页面组件间跳转_第1张图片

Vue单页应用改多页应用及跨页面组件间跳转_第2张图片

先说第一个问题:

1.首先安装glob

2.修改build目录下的

  • utils.js 增加以下代码,大概是require了相关模块,定义了多入口入口函数entries()和多入口对应html加载函数
  • //+添加以下部分
    
    // 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 修改entry,将入口定义部分的指定入口改为utils中的entries函数
  • module.exports = {
      /* 修改部分 ---------------- 开始 */
      entry: utils.entries(),
      /* 修改部分 ---------------- 结束 */

     

  • webpack.dev.conf.js  删除掉new HtmlwebpackPlugin,此处是指定的单一html模板,改为
    concat(utils.htmlPlugin()),附加一个utils中的函数来处理
  •   plugins: [
        new webpack.DefinePlugin({
          'process.env': require('../config/dev.env')
        }),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
        new webpack.NoEmitOnErrorsPlugin(),
        // https://github.com/ampedandwired/html-webpack-plugin
        /* new HtmlWebpackPlugin({
           filename: 'index.html',
           template: 'index.html',
           inject: true
         }),*/
    
        // copy custom static assets
        new CopyWebpackPlugin([
          {
            from: path.resolve(__dirname, '../static'),
            to: config.dev.assetsSubDirectory,
            ignore: ['.*']
          }
        ])
      ].concat(utils.htmlPlugin())
    })

     

  • webpack.prod.conf.js 还是plugins部分,注释掉new HtmlWebpackPlugin,在后面添加,concat(utils.htmlPlugin()),附加一个utils中的函数来处理
     
  • plugins: [
        // http://vuejs.github.io/vue-loader/en/workflow/production.html
        new webpack.DefinePlugin({
          'process.env': env
        }),
        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              warnings: false
            }
          },
          sourceMap: config.build.productionSourceMap,
          parallel: true
        }),
        // extract css into its own file
        new ExtractTextPlugin({
          filename: utils.assetsPath('css/[name].[contenthash].css'),
          // Setting the following option to `false` will not extract CSS from codesplit chunks.
          // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
          // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 
          // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
          allChunks: true,
        }),
        // Compress extracted CSS. We are using this plugin so that possible
        // duplicated CSS from different components can be deduped.
        new OptimizeCSSPlugin({
          cssProcessorOptions: config.build.productionSourceMap
            ? {safe: true, map: {inline: false}}
            : {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'
         }),*/
        // keep module.id stable when vendor modules does not change
        new webpack.HashedModuleIdsPlugin(),
        // enable scope hoisting
        new webpack.optimize.ModuleConcatenationPlugin(),
        // split vendor js into its own file
        new webpack.optimize.CommonsChunkPlugin({
          name: 'vendor',
          minChunks(module) {
            // 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',
          minChunks: Infinity
        }),
        // This instance extracts shared chunks from code splitted chunks and bundles them
        // in a separate chunk, similar to the vendor chunk
        // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
        new webpack.optimize.CommonsChunkPlugin({
          name: 'app',
          async: 'vendor-async',
          children: true,
          minChunks: 3
        }),
    
        // copy custom static assets
        new CopyWebpackPlugin([
          {
            from: path.resolve(__dirname, '../static'),
            to: config.build.assetsSubDirectory,
            ignore: ['.*']
          }
        ])
      ].concat(utils.htmlPlugin())

     

以上配置完成。

3.新建router文件:

import Vue from 'vue'
import Router from 'vue-router'
import ExamDetails from '@/components/ExamDetails'
import HistoryDetails from '@/components/HistoryDetails'

Vue.use(Router)
const routes = [

  {
    path: '/', name: 'ExamDetails', component: ExamDetails,
  },
  {path: '/history', name: 'HistoryDetails', component: HistoryDetails},
]

const vueRouter = new Router({
  // path: '/exam',
  mode: 'history',//去掉#,
  base: './exam',//这个配置也很重要,否则会出现页面空白情况
  routes,

})
export default vueRouter

4.将其注入跟组件

Vue单页应用改多页应用及跨页面组件间跳转_第3张图片

完成,我这里只是记录一下,具体参考https://segmentfault.com/a/1190000011265006?utm_source=tag-newest

现在来说第二个问题,现在要从A.html的组件“考试列表”跳转到B.html的ExamDetails,我使用标签跳转

1.如果你的B页面只有一个组件,或者都是嵌套组件,不包含并列切换组件,你在router.js页面将B.html,redirect一下就可以了,但这种情况通常很少

const routes = [
 {
    path: '/B.html',redirect:'/',
  },

  {
    path: '/', name: 'ExamDetails', component: ExamDetails,
  },
  {path: '/history', name: 'HistoryDetails', component: HistoryDetails},
]

2.现在来解决我的问题,要从A的ExamList到B的ExamDetails,还要从A的HistoryList到B的HistoryDetails,采用导航守卫解决:

在router.js中采用beforeEach函数,根据跳转目标的fullPath,next重定向到不同的目标。

特别注意:采用next("*")必须有一个next()函数作为出口,否则将进入死循环。

原理是:此函数,如果遇到next("*")执行完就会返回再次执行此函数,如果没有遇到next()就不会继续往下执行。

Vue单页应用改多页应用及跨页面组件间跳转_第4张图片

你可能感兴趣的:(Html5,Vue,前端)