最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

手把手教你vue-cli單頁(yè)到多頁(yè)應(yīng)用的方法

 更新時(shí)間:2018年05月31日 14:07:04   作者:吃葡萄不吐番茄皮  
本篇文章主要介紹了手把手教你vue-cli單頁(yè)到多頁(yè)應(yīng)用的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

vue-cli到多頁(yè)應(yīng)用

前言:我有一個(gè)cli創(chuàng)建的vue項(xiàng)目,但是我想做成多頁(yè)應(yīng)用,怎么辦,廢話不多說(shuō),直接開(kāi)擼~

約定:新增代碼部分在//add和//end中間 刪除(注釋)代碼部分在//del和//end中間,很多東西都寫(xiě)在注釋里

第一步:cli一個(gè)vue項(xiàng)目

新建一個(gè)vue項(xiàng)目 官網(wǎng) vue init webpack demo

cli默認(rèn)使用webpack的dev-server服務(wù),這個(gè)服務(wù)是做不了單頁(yè)的,需要手動(dòng)建一個(gè)私服叫啥你隨意 一般叫dev.server或者dev.client

第二步:添加兩個(gè)方法處理出口入口文件(SPA默認(rèn)寫(xiě)死的)

進(jìn)入剛剛創(chuàng)建vue項(xiàng)目 cd demo

在目錄下面找到build/utils.js文件

修改部分:

utils.js

'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')

//add
const glob = require('glob');
const HtmlWebpackPlugin = require('html-webpack-plugin');  //功能:生成html文件及js文件并把js引入html
const pagePath = path.resolve(__dirname, '../src/views/'); //頁(yè)面的路徑,比如這里我用的views,那么后面私服加入的文件監(jiān)控器就會(huì)從src下面的views下面開(kāi)始監(jiān)控文件
//end

exports.assetsPath = function (_path) {
 const assetsSubDirectory = process.env.NODE_ENV === 'production'
  ? config.build.assetsSubDirectory
  : config.dev.assetsSubDirectory

 return path.posix.join(assetsSubDirectory, _path)
}

exports.cssLoaders = function (options) {
 options = options || {}

 const cssLoader = {
  loader: 'css-loader',
  options: {
   sourceMap: options.sourceMap
  }
 }

 const postcssLoader = {
  loader: 'postcss-loader',
  options: {
   sourceMap: options.sourceMap
  }
 }

 // generate loader string to be used with extract text plugin
 function generateLoaders (loader, loaderOptions) {
  const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [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) {
 const output = []
 const loaders = exports.cssLoaders(options)

 for (const extension in loaders) {
  const loader = loaders[extension]
  output.push({
   test: new RegExp('\\.' + extension + '$'),
   use: loader
  })
 }

 return output
}

exports.createNotifierCallback = () => {
 const notifier = require('node-notifier')

 return (severity, errors) => {
  if (severity !== 'error') return

  const error = errors[0]
  const filename = error.file && error.file.split('!').pop()

  notifier.notify({
   title: packageConfig.name,
   message: severity + ': ' + error.name,
   subtitle: filename || '',
   icon: path.join(__dirname, 'logo.png')
  })
 }
}

//add 新增一個(gè)方法處理入口文件(單頁(yè)應(yīng)用的入口都是寫(xiě)死,到時(shí)候替換成這個(gè)方法)
exports.createEntry = () => {
 let files = glob.sync(pagePath + '/**/*.js');
 let entries = {};
 let basename;
 let foldername;

 files.forEach(entry => {
  // Filter the router.js
  basename = path.basename(entry, path.extname(entry), 'router.js');
  foldername = path.dirname(entry).split('/').splice(-1)[0];

  // If foldername not equal basename, doing nothing
  // The folder maybe contain more js files, but only the same name is main
  if (basename === foldername) {
   entries[basename] = [
    'webpack-hot-middleware/client?noInfo=true&reload=true&path=/__webpack_hmr&timeout=20000',
    entry];
  }
 });
 return entries;
};
//end

//add 新增出口文件
exports.createHtmlWebpackPlugin = () => {
 let files = glob.sync(pagePath + '/**/*.html', {matchBase: true});
 let entries = exports.createEntry();
 let plugins = [];
 let conf;
 let basename;
 let foldername;

 files.forEach(file => {
  basename = path.basename(file, path.extname(file));
  foldername = path.dirname(file).split('/').splice(-1).join('');

  if (basename === foldername) {
   conf = {
    template: file,
    filename: basename + '.html',
    inject: true,
    chunks: entries[basename] ? [basename] : []
   };
   if (process.env.NODE_ENV !== 'development') {
    conf.chunksSortMode = 'dependency';
    conf.minify = {
     removeComments: true,
     collapseWhitespace: true,
     removeAttributeQuotes: true
    };
   }

   plugins.push(new HtmlWebpackPlugin(conf));
  }
 });
 return plugins;
};
//end

第三步:創(chuàng)建私服(不使用dev-server服務(wù),自己建一個(gè))

從express新建私服并配置(build文件夾下新建 我這里叫webpack.dev.client.js)

webpack.dev.client.js

/**
 * created by qbyu2 on 2018-05-30
 * express 私服
 * */
'use strict';

const fs = require('fs');
const path = require('path');
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');  //文件監(jiān)控(前面配置了從views下面監(jiān)控)
const webpackHotMiddleware = require('webpack-hot-middleware');  //熱加載
const config = require('../config');
const devWebpackConfig = require('./webpack.dev.conf');
const proxyMiddleware = require('http-proxy-middleware');  //跨域

const proxyTable = config.dev.proxyTable;

const PORT = config.dev.port;
const HOST = config.dev.host;
const assetsRoot = config.dev.assetsRoot;
const app = express();
const router = express.Router();
const compiler = webpack(devWebpackConfig);

let devMiddleware = webpackDevMiddleware(compiler, {
 publicPath: devWebpackConfig.output.publicPath,
 quiet: true,
 stats: {
  colors: true,
  chunks: false
 }
});

let hotMiddleware = webpackHotMiddleware(compiler, {
 path: '/__webpack_hmr',
 heartbeat: 2000
});

app.use(hotMiddleware);
app.use(devMiddleware);

Object.keys(proxyTable).forEach(function (context) {
 let options = proxyTable[context];
 if (typeof options === 'string') {
  options = {
   target: options
  };
 }
 app.use(proxyMiddleware(context, options));
});

//雙路由  私服一層控制私服路由  vue的路由控制該頁(yè)面下的路由
app.use(router)
app.use('/static', express.static(path.join(assetsRoot, 'static')));

let sendFile = (viewname, response, next) => {
 compiler.outputFileSystem.readFile(viewname, (err, result) => {
  if (err) {
   return (next(err));
  }
  response.set('content-type', 'text/html');
  response.send(result);
  response.end();
 });
};

//拼接方法
function pathJoin(patz) {
 return path.join(assetsRoot, patz);
}

/**
 * 定義路由(私服路由 非vue路由)
 * */

// favicon
router.get('/favicon.ico', (req, res, next) => {
 res.end();
});

// http://localhost:8080/
router.get('/', (req, res, next)=>{
 sendFile(pathJoin('index.html'), res, next);
});

// http://localhost:8080/home
router.get('/:home', (req, res, next) => {
 sendFile(pathJoin(req.params.home + '.html'), res, next);
});

// http://localhost:8080/index
router.get('/:index', (req, res, next) => {
 sendFile(pathJoin(req.params.index + '.html'), res, next);
});

module.exports = app.listen(PORT, err => {
 if (err){
  return
 }
 console.log(`Listening at http://${HOST}:${PORT}\n`);
})

私服創(chuàng)建好了 安裝下依賴

有坑。。。

webpack和熱加載版本太高太低都不行

npm install webpack@3.10.0 --save-dev
npm install webpack-dev-middleware --save-dev
npm install webpack-hot-middleware@2.21.0 --save-dev
npm install http-proxy-middleware --save-dev

第四步:修改配置webpack.base.conf.js

'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')

const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)

const devWebpackConfig = merge(baseWebpackConfig, {
 module: {
  rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
 },
 // cheap-module-eval-source-map is faster for development
 devtool: config.dev.devtool,

 // these devServer options should be customized in /config/index.js
 devServer: {
  clientLogLevel: 'warning',
  historyApiFallback: {
   rewrites: [
    { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
   ],
  },
  hot: true,
  contentBase: false, // since we use CopyWebpackPlugin.
  compress: true,
  host: HOST || config.dev.host,
  port: PORT || config.dev.port,
  open: config.dev.autoOpenBrowser,
  overlay: config.dev.errorOverlay
   ? { warnings: false, errors: true }
   : false,
  publicPath: config.dev.assetsPublicPath,
  proxy: config.dev.proxyTable,
  quiet: true, // necessary for FriendlyErrorsPlugin
  watchOptions: {
   poll: config.dev.poll,
  }
 },
 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
  //del  注釋掉spa固定的單頁(yè)出口 末尾動(dòng)態(tài)配上出口
  // new HtmlWebpackPlugin({
  //  filename: 'index.html',
  //  template: 'index.html',
  //  inject: true
  // }),
  //end
  // copy custom static assets
  new CopyWebpackPlugin([
   {
    from: path.resolve(__dirname, '../static'),
    to: config.dev.assetsSubDirectory,
    ignore: ['.*']
   }
  ])
 ]
 //add
  .concat(utils.createHtmlWebpackPlugin())
 //end
})
//del
// module.exports = new Promise((resolve, reject) => {
//  portfinder.basePort = process.env.PORT || config.dev.port
//  portfinder.getPort((err, port) => {
//   if (err) {
//    reject(err)
//   } else {
//    // publish the new Port, necessary for e2e tests
//    process.env.PORT = port
//    // add port to devServer config
//    devWebpackConfig.devServer.port = port
//
//    // Add FriendlyErrorsPlugin
//    devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
//     compilationSuccessInfo: {
//      messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
//     },
//     onErrors: config.dev.notifyOnErrors
//     ? utils.createNotifierCallback()
//     : undefined
//    }))
//
//    resolve(devWebpackConfig)
//   }
//  })
// })
//end

webpack.dev.conf.js

'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')

const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)

const devWebpackConfig = merge(baseWebpackConfig, {
 module: {
  rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
 },
 // cheap-module-eval-source-map is faster for development
 devtool: config.dev.devtool,

 // these devServer options should be customized in /config/index.js
 //del 注掉SPA的服務(wù)器
 // devServer: {
 //  clientLogLevel: 'warning',
 //  historyApiFallback: {
 //   rewrites: [
 //    { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
 //   ],
 //  },
 //  hot: true,
 //  contentBase: false, // since we use CopyWebpackPlugin.
 //  compress: true,
 //  host: HOST || config.dev.host,
 //  port: PORT || config.dev.port,
 //  open: config.dev.autoOpenBrowser,
 //  overlay: config.dev.errorOverlay
 //   ? { warnings: false, errors: true }
 //   : false,
 //  publicPath: config.dev.assetsPublicPath,
 //  proxy: config.dev.proxyTable,
 //  quiet: true, // necessary for FriendlyErrorsPlugin
 //  watchOptions: {
 //   poll: config.dev.poll,
 //  }
 // },
 //end
 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
  //del  注釋掉spa固定的單頁(yè)出口 末尾動(dòng)態(tài)配上出口
  // new HtmlWebpackPlugin({
  //  filename: 'index.html',
  //  template: 'index.html',
  //  inject: true
  // }),
  //end
  // copy custom static assets
  new CopyWebpackPlugin([
   {
    from: path.resolve(__dirname, '../static'),
    to: config.dev.assetsSubDirectory,
    ignore: ['.*']
   }
  ])
 ]
 //add
  .concat(utils.createHtmlWebpackPlugin())
 //end
})
//del
// module.exports = new Promise((resolve, reject) => {
//  portfinder.basePort = process.env.PORT || config.dev.port
//  portfinder.getPort((err, port) => {
//   if (err) {
//    reject(err)
//   } else {
//    // publish the new Port, necessary for e2e tests
//    process.env.PORT = port
//    // add port to devServer config
//    devWebpackConfig.devServer.port = port
//
//    // Add FriendlyErrorsPlugin
//    devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
//     compilationSuccessInfo: {
//      messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
//     },
//     onErrors: config.dev.notifyOnErrors
//     ? utils.createNotifierCallback()
//     : undefined
//    }))
//
//    resolve(devWebpackConfig)
//   }
//  })
// })
//end
module.exports = devWebpackConfig;

webpack.prod.conf.js

plugins最后加上.concat(utils.createHtmlWebpackPlugin())

test環(huán)境一樣

第五步:修改package.json 指令配置

scripts下面'dev':

這樣執(zhí)行的時(shí)候就不會(huì)走默認(rèn)的dev-server而走你的私服了

"scripts": {
  "dev": "node build/webpack.dev.client.js",
  "start": "npm run dev",
  "build": "node build/build.js"
 },

第六步:創(chuàng)建測(cè)試文件

src目錄下新建 views文件夾 (代碼注釋里有 當(dāng)時(shí)配的目錄跟這個(gè)一致就可以 隨便你命名 遵循命名規(guī)范就行)
views 文件夾下新建兩個(gè)文件夾index和home 代表多頁(yè) 每頁(yè)單獨(dú)一個(gè)文件夾 文件夾下建對(duì)應(yīng)文件

最后,npm run dev

這個(gè)時(shí)候你會(huì)發(fā)現(xiàn),特么的什么鬼文章 報(bào)錯(cuò)了啊

稍安勿躁~

兩個(gè)地方,

1.webpack.dev.client.js

//雙路由  私服一層控制私服路由  vue的路由控制該頁(yè)面下的路由
app.use(router)
app.use('/static', express.static(path.join(assetsRoot, 'static')));

這個(gè)assetsRoot cli創(chuàng)建的時(shí)候是沒(méi)有的 在config/index.js 下面找到dev加上

assetsRoot: path.resolve(__dirname, '../dist'),


順便把dev和build的assetsPublicPath 路徑都改成相對(duì)路徑'./'

2.還是版本問(wèn)題

webpack-dev-middleware 默認(rèn)是3.1.3版本但是會(huì)報(bào)錯(cuò)

具體哪個(gè)版本不報(bào)錯(cuò)我也不知道

context.compiler.hooks.invalid.tap('WebpackDevMiddleware', invalid);

找不到invalid 源碼里面是有的

卸載webpack-dev-middleware

npm uninstall webpack-dev-middleware

使用dev-server自帶的webpack-dev-middleware (cli單頁(yè)應(yīng)用是有熱加載的)

重新install dev-server

npm install webpack-dev-server@2.10.0 --save-dev
npm run dev

總結(jié):核心點(diǎn)就在創(chuàng)建并配置私服和修改出口入口配置,坑就在版本不兼容

建議:cli一個(gè)vue的demo項(xiàng)目 從頭擼一遍 再在實(shí)際項(xiàng)目里使用,而不是copy一下運(yùn)行沒(méi)問(wèn)題搞定~

建議而已,你怎么打人,嗚嗚嗚~

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue中key為index和id的區(qū)別示例詳解

    Vue中key為index和id的區(qū)別示例詳解

    這篇文章主要介紹了Vue中key為index和id的區(qū)別詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • Vue element商品列表的增刪改功能實(shí)現(xiàn)

    Vue element商品列表的增刪改功能實(shí)現(xiàn)

    這篇文章主要介紹了Vue+element 商品列表、新增、編輯、刪除業(yè)務(wù)實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Vue數(shù)據(jù)驅(qū)動(dòng)試圖的實(shí)現(xiàn)方法及原理

    Vue數(shù)據(jù)驅(qū)動(dòng)試圖的實(shí)現(xiàn)方法及原理

    當(dāng)Vue實(shí)例中的數(shù)據(jù)(data)發(fā)生變化時(shí),與之相關(guān)聯(lián)的視圖(template)會(huì)自動(dòng)更新,反映出最新的數(shù)據(jù)狀態(tài), Vue的數(shù)據(jù)驅(qū)動(dòng)視圖是通過(guò)其響應(yīng)式系統(tǒng)實(shí)現(xiàn)的,以下是Vue數(shù)據(jù)驅(qū)動(dòng)視圖實(shí)現(xiàn)的核心原理,需要的朋友可以參考下
    2024-10-10
  • vue中的get方法\post方法如何實(shí)現(xiàn)傳遞數(shù)組參數(shù)

    vue中的get方法\post方法如何實(shí)現(xiàn)傳遞數(shù)組參數(shù)

    這篇文章主要介紹了vue中的get方法\post方法如何實(shí)現(xiàn)傳遞數(shù)組參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • node.js開(kāi)發(fā)輔助工具nodemon安裝與配置詳解

    node.js開(kāi)發(fā)輔助工具nodemon安裝與配置詳解

    node.js代碼修改后,需要重新啟動(dòng) Express 應(yīng)用,所做的修改才能生效。若之后的每次代碼修改都要重復(fù)這樣的操作,勢(shì)必會(huì)影響開(kāi)發(fā)效率,本文將詳細(xì)介紹Nodemon,它會(huì)監(jiān)測(cè)項(xiàng)目中的所有文件,一旦發(fā)現(xiàn)文件有改動(dòng),Nodemon 會(huì)自動(dòng)重啟應(yīng)用
    2020-02-02
  • vue+elementui實(shí)現(xiàn)拖住滑塊拼圖驗(yàn)證

    vue+elementui實(shí)現(xiàn)拖住滑塊拼圖驗(yàn)證

    這篇文章主要為大家詳細(xì)介紹了vue+elementui實(shí)現(xiàn)拖住滑塊拼圖驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Vue項(xiàng)目引進(jìn)ElementUI組件的方法

    Vue項(xiàng)目引進(jìn)ElementUI組件的方法

    這篇文章主要介紹了Vue項(xiàng)目引進(jìn)ElementUI組件的方法,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2018-11-11
  • 解析vue中的$mount

    解析vue中的$mount

    本文主要是帶領(lǐng)大家分析$mount的相關(guān)知識(shí),需要的朋友一起學(xué)習(xí)吧
    2017-12-12
  • 使用vue引入maptalks地圖及聚合效果的實(shí)現(xiàn)

    使用vue引入maptalks地圖及聚合效果的實(shí)現(xiàn)

    這篇文章主要介紹了使用vue引入maptalks地圖及聚合效果的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • vue.js循環(huán)radio的實(shí)例

    vue.js循環(huán)radio的實(shí)例

    今天小編就為大家分享一篇vue.js循環(huán)radio的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-11-11

最新評(píng)論

隆化县| 和田县| 和林格尔县| 西城区| 会东县| 大同县| 龙口市| 乌恰县| 溧阳市| 韶关市| 麦盖提县| 家居| 赣榆县| 土默特左旗| 瑞金市| 公安县| 漯河市| 蕉岭县| 电白县| 蓝山县| 昌宁县| 阳江市| 沁水县| 民乐县| 定安县| 宜兴市| 邯郸县| 白城市| 邵阳县| 陆丰市| 礼泉县| 濉溪县| 阿勒泰市| 湛江市| 金湖县| 深泽县| 昆明市| 湘阴县| 互助| 突泉县| 金塔县|