本篇文章為大家展示了使用vue怎么構(gòu)建一個(gè)多頁面應(yīng)用,內(nèi)容簡明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
成都創(chuàng)新互聯(lián)是專業(yè)的阿克陶網(wǎng)站建設(shè)公司,阿克陶接單;提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行阿克陶網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
準(zhǔn)備工作
在本地用vue-cli新建一個(gè)項(xiàng)目,這個(gè)步驟vue的官網(wǎng)上有,我就不再說了。
這里有一個(gè)地方需要改一下,在執(zhí)行npm install命令之前,在package.json里添加一個(gè)依賴,后面會(huì)用到。
修改webpack配置
這里展示一下我的項(xiàng)目目錄
├── 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
在這一步里我們需要改動(dòng)的文件都在build文件下,分別是:
utils.js
webpack.base.conf.js
webpack.dev.conf.js
webpack.prod.conf.js
我就按照順序放出完整的文件內(nèi)容,然后在做修改或添加的位置用注釋符標(biāo)注出來:
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安裝時(shí)依賴的一個(gè)第三方模塊,還模塊允許你使用 *等符號(hào), 例如lib/*.js就是獲取lib文件夾下的所有js后綴名的文件 var glob = require('glob') // 頁面模板 var HtmlWebpackPlugin = require('html-webpack-plugin') // 取得相應(yīng)的頁面路徑,因?yàn)橹暗呐渲?,所以是src文件夾下的pages文件夾 var PAGE_PATH = path.resolve(__dirname, '../src/pages') // 用于做相應(yīng)的merge處理 var merge = require('webpack-merge') //多入口配置 // 通過glob模塊讀取pages文件夾下的所有對(duì)應(yīng)文件夾下的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文件夾下的對(duì)應(yīng)的html后綴文件,然后放入數(shù)組中 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', // 頁面模板需要加對(duì)應(yīng)的js腳本,如果不加這行則每個(gè)頁面都會(huì)引入所有的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 } /* 這里是添加的部分 ---------------------------- 結(jié)束 */
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(), /* 修改部分 ---------------- 結(jié)束 */ 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 /* 注釋這個(gè)區(qū)域的文件 ------------- 開始 */ // new HtmlWebpackPlugin({ // filename: 'index.html', // template: 'index.html', // inject: true // }), /* 注釋這個(gè)區(qū)域的文件 ------------- 結(jié)束 */ 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 /* 注釋這個(gè)區(qū)域的內(nèi)容 ---------------------- 開始 */ // 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' // }), /* 注釋這個(gè)區(qū)域的內(nèi)容 ---------------------- 結(jié)束 */ // 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的配置就結(jié)束了。
但是還沒完啦,下面繼續(xù)。
文件結(jié)構(gòu)
├── 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分別是靜態(tài)資源文件、組件文件、頁面文件。
前兩個(gè)就不多說,主要是頁面文件里,我目前是按照項(xiàng)目的模塊分的文件夾,你也可以按照你自己的需求調(diào)整。然后在每個(gè)模塊里又有三個(gè)內(nèi)容:vue文件,js文件和html文件。這三個(gè)文件的作用就相當(dāng)于做spa單頁面應(yīng)用時(shí),根目錄的index.html頁面模板,src文件下的main.js和app.vue的功能。
原先,入口文件只有一個(gè)main.js,但現(xiàn)在由于是多頁面,因此入口頁面多了,我目前就是兩個(gè):index和cell,之后如果打包,就會(huì)在dist文件下生成兩個(gè)HTML文件:index.html和cell.html(可以參考一下單頁面應(yīng)用時(shí),打包只會(huì)生成一個(gè)index.html,區(qū)別在這里)。
cell文件下的三個(gè)文件,就是一般模式的配置,參考index的就可以,但并不完全相同。
特別注意的地方
cell.js
在這個(gè)文件里,按照寫法,應(yīng)該是這樣的吧:
import Vue from 'Vue' import cell from './cell.vue' new Vue({ el:'#app',// 這里參考cell.html和cell.vue的根節(jié)點(diǎn)id,保持三者一致 teleplate:'<cell/>', components:{ cell } })
這個(gè)配置在運(yùn)行時(shí)(npm run dev)會(huì)報(bào)錯(cuò)
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
(found in <Root>)
網(wǎng)上的解釋是這樣的:
運(yùn)行時(shí)構(gòu)建不包含模板編譯器,因此不支持 template 選項(xiàng),只能用 render 選項(xiàng),但即使使用運(yùn)行時(shí)構(gòu)建,在單文件組件中也依然可以寫模板,因?yàn)閱挝募M件的模板會(huì)在構(gòu)建時(shí)預(yù)編譯為 render 函數(shù)。運(yùn)行時(shí)構(gòu)建比獨(dú)立構(gòu)建要輕量30%,只有 17.14 Kb min+gzip大小。
上面一段是官方api中的解釋。就是說,如果我們想使用template,我們不能直接在客戶端使用npm install之后的vue。
也給出了相應(yīng)的修改方案:
resolve: { alias: { 'vue': 'vue/dist/vue.js' } }
這里是修改package.json的resolve下的vue的配置,很多人反應(yīng)這樣修改之后就好了,但是我按照這個(gè)方法修改之后依然報(bào)錯(cuò)。然后我就想到上面提到的render函數(shù),因此我的修改是針對(duì)cell.js文件的。
import Vue from 'Vue' import cell from './cell.vue' /* eslint-disable no-new */ new Vue({ el: '#app', render: h => h(cell) })
這里面我用render函數(shù)取代了組件的寫法,在運(yùn)行就沒問題了。
頁面跳轉(zhuǎn)
既然是多頁面,肯定涉及頁面之間的互相跳轉(zhuǎn),就按照我這個(gè)項(xiàng)目舉例,從index.html文件點(diǎn)擊a標(biāo)簽跳轉(zhuǎn)到cell.html。
我最開始寫的是:
<!-- index.html --> <a href='../cell/cell.html'></a>
但這樣寫,不論是在開發(fā)環(huán)境還是最后測(cè)試,都會(huì)報(bào)404,找不到這個(gè)頁面。
改成這樣既可:
<!-- index.html --> <a href='cell.html'></a>
這樣他就會(huì)自己找cell.html這個(gè)文件。
打包后的資源路徑
執(zhí)行npm run build之后,打開相應(yīng)的html文件你是看不到任何東西的,查看原因是找不到相應(yīng)的js文件和css文件。
這時(shí)候的文件結(jié)構(gòu)是這樣的:
├── dist │ ├── js │ ├── css │ ├── index.html │ └── cell.html
查看index.html文件之后會(huì)發(fā)現(xiàn)資源的引用路徑是:
/dist/js.........
這樣,如果你的dist文件不是在根目錄下的,就根本找不到資源。
方法當(dāng)然也有啦,如果你不嫌麻煩,就一個(gè)文件一個(gè)文件的修改路徑咯,或者像我一樣偷懶,修改config下的index.js文件。具體的做法是:
build: { env: require('./prod.env'), index: path.resolve(__dirname, '../dist/index.html'), assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/', productionSourceMap: true, // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to `true`, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: false, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: // `npm run build --report` // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report },
將這里面的
assetsPublicPath: '/',
改成
assetsPublicPath: './',
上述內(nèi)容就是使用vue怎么構(gòu)建一個(gè)多頁面應(yīng)用,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
分享文章:使用vue怎么構(gòu)建一個(gè)多頁面應(yīng)用
瀏覽路徑:http://chinadenli.net/article12/pghodc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、網(wǎng)站策劃、靜態(tài)網(wǎng)站、網(wǎng)站排名、移動(dòng)網(wǎng)站建設(shè)、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)