vue-cli專案結構詳解

alentan發表於2017-12-25

Vue-cli是vue官方出品的快速構建單頁應用的腳手架,如果你是初次嘗試Vue,不建議使用,推薦你使用普通引入javascript檔案的方式進行學習,如果你已經有vue基礎那麼就可以用vue-cli這個腳手架進行學習。下面開始對vue-cli生成的專案結構進行一下簡單的解讀,這個解讀只是本人在專案中應用vue-cli的一些個人見解和總結,只針對一些剛入門vue的人,本人是菜鳥,如有不對請大神不吝賜教。

第1部分:安裝Vue-cli

一.安裝vue-cli

安裝vue-cli首先需要安裝node,如果你的電腦已經安裝node,就可以使用node自帶的npm來安裝vue-cli,你可以在命令列工具裡輸入npm -v 檢測你是否安裝了npm和版本情況。出現版本號說明你已經安裝了npm和node,我這裡的npm版本為5.3.0。

這裡寫圖片描述

如果npm沒有問題的話,就可以愉快的玩耍了。 npm 命令安裝vue-cli了,在命令列輸入下面的命令:

npm install vue-cli -g

-g :代表全域性安裝。如果你安裝時報錯,一般是網路問題,你可以嘗試用淘寶映象cnpm來進行安裝。安裝完成後,命令列輸入vue -V來進行檢視 vue-cli的版本號。注意這裡的V是大寫的。我這裡版本號是2.9.9,應該是截止到2017-12-22最新版本。

這裡寫圖片描述

出現這個版本號說明vue-cli安裝成功!

二.使用vue-cli建立vue專案

命令列輸入

vue init webpack my-project
複製程式碼

輸入命令後,會詢問我們幾個簡單的選項,我們按需填寫就好。

  • Project name :專案名稱 ,如果不需要更改直接回車就可以了。注意:這裡不能使用大寫,所以我把名稱改成了vueclitest
  • Project description:專案描述,預設為A Vue.js project,直接回車,不用編寫。
  • Author:作者,如果你有配置git的作者,他會讀取。
  • Install vue-router? 是否安裝vue的路由外掛,Y代表安裝,N無需安裝,下面的命令也是一樣的。
  • Use ESLint to lint your code? 是否用ESLint來限制你的程式碼錯誤和風格。
  • setup unit tests with Karma + Mocha? 是否需要安裝單元測試工具Karma+Mocha。
  • Setup e2e tests with Nightwatch?是否安裝e2e來進行使用者行為模擬測試。
  • Should we run npm install for you after the project has been created? (recommended) npm 這一步會詢問你使用npm安裝還是yarn安裝包依賴,我這裡選擇的是npm,聽說yarn更快更好,童鞋們可以試試,我建議大家使用yarn安裝,使用yarn之前確保你的電腦已經安裝yarn。以前老版本的vue-cli是沒有這個選項的,老版本的vue-cli只是下載vue專案模板,下載完成後需要進入專案資料夾進行包依賴安裝,現在vue-cli會幫你安裝包依賴,只能說vue真的是越來越人性化了,怪不得這麼多人使用vue進行開發。下面截個圖

這裡寫圖片描述

出現上面的文字說明專案初始化成功,然後我們可以按照上面的步驟啟動我們的專案,

  1. 第一步命令列輸入
cd my-project 
複製程式碼
  1. 第二步命令列輸入
npm run dev 
複製程式碼

出現如下畫面說明專案啟動成功

這裡寫圖片描述

然後開啟瀏覽器位址列輸入 http://localhost:8080 就可以看到尤大大為我們準備的hello-vue的頁面,開不開心,高不高興!

這裡寫圖片描述

有人會問為啥專案啟動了沒自動開啟瀏覽器,莫慌,只要在專案根目錄下找到package.json,然後開啟該檔案,在檔案中的script指令碼命令的dev行加入--open就可以了。如圖所示。然後重新啟動專案就可以自動開啟瀏覽器了

這裡寫圖片描述

補充說明:

再回看一下剛才我們在初始化專案的時候的命令

vue init webpack my-project

命令說明 :vue init <template-name> <project-name>

project-name 想必大家都知道是我們要初始化的專案名稱,而template-name 是表示模板名稱,vue-cli官方為我們提供了5種模板,其中webpack是最常用的模板,一般我們開發專案都會用webpack進行開發,而vue官方也推薦我們使用webpack,建議大家學學webpack,還是一個比較有用的前端構建工具。 下面看看其他剩下的幾種模板

  • webpack-simple:一個簡單webpack+vue-loader的模板,不包含其他功能。
  • browserify:一個全面的Browserify+vueify 的模板,功能包括熱載入,linting,單元檢測。
  • browserify-simple:一個簡單Browserify+vueify的模板,不包含其他功能。
  • simple:一個最簡單的單頁應用模板。

第二部分:解讀Vue-cli專案結構

看一下剛才生成的專案目錄結構

說明:每個人應用的模板和版本不一樣生成的專案目錄結構可能和下面的有所區別,(下面是vue-cli(版本2.9.9)以webpack模板生成的專案)

|-- build                            // 專案構建(webpack)相關程式碼
|   |-- build.js                     // 生產環境構建程式碼
|   |-- check-version.js             // 檢查node、npm等版本
|   |-- utils.js                     // 構建工具相關
|   |-- vue-loader.conf.js           // webpack loader配置
|   |-- webpack.base.conf.js         // webpack基礎配置
|   |-- webpack.dev.conf.js          // webpack開發環境配置,構建開發本地伺服器
|   |-- webpack.prod.conf.js         // webpack生產環境配置
|-- config                           // 專案開發環境配置
|   |-- dev.env.js                   // 開發環境變數
|   |-- index.js                     // 專案一些配置變數
|   |-- prod.env.js                  // 生產環境變數
|-- src                              // 原始碼目錄
|   |-- components                   // vue公共元件
|   |-- router                       // vue的路由管理
|   |-- App.vue                      // 頁面入口檔案
|   |-- main.js                      // 程式入口檔案,載入各種公共元件
|-- static                           // 靜態檔案,比如一些圖片,json資料等
|-- .babelrc                         // ES6語法編譯配置
|-- .editorconfig                    // 定義程式碼格式
|-- .gitignore                       // git上傳需要忽略的檔案格式
|-- .postcsssrc                       // postcss配置檔案
|-- README.md                        // 專案說明
|-- index.html                       // 入口頁面
|-- package.json                     // 專案基本資訊,包依賴資訊等
複製程式碼

以上就是vue-cli生成的專案目錄結構,雖然看起來有點複雜,但是這並不影響我們進行開發,雖然說我們可以不用關注這些檔案是怎麼回事也可以進行專案開發,但是可能會影響我們的開發效率,還有一個就是這vue-cli生成的專案結構可能並不滿足於我們公司的開發,這時候就要對這個專案進行改造,改成我們想要的結構和擴充相關功能。這時候就需要你看得懂相關的配置檔案。

1. packagejson檔案 packagejson檔案是專案的配置檔案,定義了專案的基本資訊以及專案的相關包依賴,npm執行命令等,位於專案根目錄下。

這裡寫圖片描述

其中“scripts”定義了一些npm命令,還記得我們初始化專案完成後執行

npm run dev 
複製程式碼

其實就是執行

webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
複製程式碼

這句話的大概意思就是利用 webpack-dev-server 讀取 webpack.dev.conf.js 資訊並啟動一個本地伺服器。這應該也是新版本vue-cli的新特性吧,以前老的專案是使用node的express開啟一個本地伺服器。 看一下沒改版之前的,是不是和現在的有點區別啦。由此可以看出script欄位是用來指定npm相關命令的縮寫。

這裡寫圖片描述

2. dependencies VS devDependencies

簡單的來說dependencies是執行時依賴(生產環境),devDependencies是開發時的依賴(開發環境) 相應的npm install 在安裝 npm 包時,有兩種命令引數可以把它們的資訊寫入 package.json 檔案,--save 會把依賴包名稱新增到 package.json 檔案 dependencies 鍵下,--save-dev 則新增到 package.json 檔案 devDependencies 鍵下。 舉個例子,比如我們專案要引用jQuery,因為jQuery部署到線上環境也要使用(生產環境),所以安裝jQuery的命令為

npm install jQuery --save
複製程式碼

這時候 dependencies 鍵下就會多了一個jQuery包。 package.json還有很多相關配置,如果你想全面瞭解,可以自己去百度學習一下。

3. 基礎配置檔案 webpack.base.conf.js 基礎的 webpack 配置檔案主要根據模式定義了入口出口,以及處理 vue, babel 等的各種模組,是最為基礎的部分。其他模式的配置檔案以此為基礎通過 webpack-merge 合併。

'use strict'
const path = require('path');
const utils = require('./utils');
const config = require('../config');
const vueLoaderConfig = require('./vue-loader.conf')
function resolve(dir) {//處理路徑
  return path.join(__dirname, '..', dir);
}

module.exports = {
  context: path.resolve(__dirname, '../'), // 基礎目錄
  entry: {
    app: './src/main.js'//入口檔案
  },
  output: {
    path: config.build.assetsRoot, // 輸出檔案,預設'../dist'
    filename: '[name].js',//輸出檔名稱,
    publicPath: process.env.NODE_ENV === 'production'
    ? config.build.assetsPublicPath // 生產模式publicpath
    : config.dev.assetsPublicPath // 開發模式publicpath
  },
  resolve: { // 解析確定的擴充名,方便模組匯入
    extensions: ['.js', '.vue', '.json'], 
    alias: {   // 建立別名
      'vue$': 'vue/dist/vue.esm.js', 
      '@': resolve('src') // 如 '@/components/HelloWorld'
    }
  },
  module: {//模組相關配置,包括loader,plugin等
    rules: [{
        test: /\.vue$/, // vue 要在babel之前
        loader: 'vue-loader',//vue轉普通的html
        options: vueLoaderConfig //可選項: vue-loader 選項配置
      },{
        test: /\.js$/, // babel
        loader: 'babel-loader',//es6轉es5loader
        include: [resolve('src')]
      },{ // url-loader 檔案大小低於指定的限制時,可返回 DataURL,即base64
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, // url-loader 圖片
        loader: 'url-loader',
        options: { // 相容性問題需要將query換成options
          limit: 10000, // 預設無限制
          name: utils.assetsPath('img/[name].[hash:7].[ext]') // hash:7 代表 7 位數的 hash
        }
      },{
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, // url-loader 音視訊
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },{
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, // url-loader 字型
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  },
  node: { // 是否 polyfill 或 mock
    setImmediate: false,
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  }
}
複製程式碼

4. 開發環境配置檔案 webpack.dev.conf.js 我們在啟動專案的時候就要用到這個檔案,說明這個檔案比較重要,大家要好好看一下

'use strict'
const utils = require('./utils')

const webpack = require('webpack')

const config = require('../config')//基本配置的引數

const merge = require('webpack-merge')// 用於合併webpack的配置檔案

const baseWebpackConfig = require('./webpack.base.conf')//webpack基本配置檔案(開發時和執行時公用)
/**
 * [HtmlWebpackPlugin description]
 * @type {[type]}
 * 這個外掛的作用是依據一個簡單的模板,幫你生成最終的Html5檔案,
 * 這個檔案中自動引用了你打包後的JS檔案。每次編譯都在檔名中插入一個不同的雜湊值
 */
const HtmlWebpackPlugin = require('html-webpack-plugin')

/*能夠更好在終端看到webapck執行的警告和錯誤*/
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

const portfinder = require('portfinder') // 自動檢索下一個可用埠

const HOST = process.env.HOST//讀取系統環境變數的host

const PORT = process.env.PORT && Number(process.env.PORT)//讀取系統環境變數的port

// 合併baseWebpackConfig配置
const devWebpackConfig = merge(baseWebpackConfig, {
  module: {
	  // 對一些獨立的css檔案以及它的預處理檔案做一個編譯
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
  },
  // cheap-module-eval-source-map is faster for development
  devtool: config.dev.devtool,// 新增元資訊(meta info)增強除錯
  // these devServer options should be customized in /config/index.js
  devServer: {//webpack-dev-server伺服器配置
    clientLogLevel: 'warning', // console 控制檯顯示的訊息,可能的值有 none, error, warning 或者 info
    historyApiFallback: true,
    hot: true,//開啟熱載入
    compress: true,//開啟壓縮
    host: HOST || config.dev.host,// process.env 優先
    port: PORT || config.dev.port,// process.env 優先
    open: config.dev.autoOpenBrowser,//自動開啟瀏覽器,這裡是預設是false,所以不會自動開啟
    overlay: config.dev.errorOverlay// warning 和 error 都要顯示
      ? { warnings: false, errors: true }
      : false,
    publicPath: config.dev.assetsPublicPath,
    proxy: config.dev.proxyTable,//代理設定,用於前後端分離
    quiet: true, // necessary for FriendlyErrorsPlugin
    watchOptions: {//啟用 Watch 模式。這意味著在初始構建之後,webpack 將繼續監聽任何已解析檔案的更改
      poll: config.dev.poll,//通過傳遞 true 開啟 polling,或者指定毫秒為單位進行輪詢。預設為false
    }
  },
  plugins: [//webpack一些構建用到的外掛
    new webpack.DefinePlugin({
      'process.env': require('../config/dev.env')
    }),
    
    /*模組熱替換它允許在執行時更新各種模組,而無需進行完全重新整理*/
    new webpack.HotModuleReplacementPlugin(),
    
    new webpack.NamedModulesPlugin(), // 熱載入時直接返回更新的檔名,而不是id
    new webpack.NoEmitOnErrorsPlugin(),// 跳過編譯時出錯的程式碼並記錄下來,主要作用是使編譯後執行時的包不出錯
    // https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
       // 指定編譯後生成的html檔名
      filename: 'index.html',
      // 需要處理的模板
      template: 'index.html',
      // 打包過程中輸出的js、css的路徑新增到html檔案中
      // css檔案插入到head中
      // js檔案插入到body中,可能的選項有 true, 'head', 'body', false
      inject: true
    }),
  ]
})

module.exports = new Promise((resolve, reject) => {
  portfinder.basePort = process.env.PORT || config.dev.port// 獲取當前設定的埠
  portfinder.getPort((err, port) => {
    if (err) {
      reject(err)
    } else {
      // process 釋出埠
      process.env.PORT = port 
      // 設定 devServer 埠
      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)
    }
  })
})
複製程式碼

5. 生產模式配置檔案 webpack.prod.conf.js

'use strict'
const path = require('path');
const utils = require('./utils');
const webpack = require('webpack');
const config = require('../config');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');

const env = process.env.NODE_ENV === 'production'
  ? require('../config/prod.env')
  : require('../config/dev.env')

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap, // production 下生成 sourceMap
      extract: true, // util 中 styleLoaders 方法內的 generateLoaders 函式
      usePostCSS: true
    })
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    new webpack.DefinePlugin({ 'process.env': env }),
    new webpack.optimize.UglifyJsPlugin({ // js 程式碼壓縮還可配置 include, cache 等,也可用 babel-minify
      compress: { warnings: false },
      sourceMap: config.build.productionSourceMap,
      parallel: true // 充分利用多核cpu
    }),
    // 提取 js 檔案中的 css
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css'),
      allChunks: false,
    }),
    // 壓縮提取出的css
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
      ? { safe: true, map: { inline: false } }
      : { safe: true }
    }),
    // 生成 html
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'production'
        ? config.build.index
        : 'index.html',
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      },
      chunksSortMode: 'dependency' // 按 dependency 的順序引入
    }),
    new webpack.HashedModuleIdsPlugin(), // 根據模組的相對路徑生成一個四位數的 hash 作為模組 id
    new webpack.optimize.ModuleConcatenationPlugin(), // 預編譯所有模組到一個閉包中
    // 拆分公共模組
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module) {
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),

    // 拷貝靜態文件
    new CopyWebpackPlugin([{
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
    }])]
})

if (config.build.productionGzip) { // gzip 壓縮
  const 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, // 10kb 以上大小的檔案才壓縮
      minRatio: 0.8 // 最小比例達到 .8 時才壓縮
    })
  )
}

if (config.build.bundleAnalyzerReport) { // 視覺化分析包的尺寸
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
  webpackConfig.plugins.push(new BundleAnalyzerPlugin());
}

module.exports = webpackConfig;
複製程式碼

6. build.js 編譯入口

'use strict'

process.env.NODE_ENV = 'production'; // 設定當前環境為生產環境
const ora = require('ora'); //loading...進度條
const rm = require('rimraf'); //刪除檔案 'rm -rf'
const chalk = require('chalk'); //stdout顏色設定
const webpack = require('webpack');
const path = require('path');
const config = require('../config');
const webpackConfig = require('./webpack.prod.conf');

const spinner = ora('正在編譯...');
spinner.start();

// 清空資料夾
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
    if (err) throw err;
    // 刪除完成回撥函式內執行編譯
    webpack(webpackConfig, function (err, stats) {
        spinner.stop();
        if (err) throw err;
    
    // 編譯完成,輸出編譯檔案
        process.stdout.write(stats.toString({
            colors: true,
            modules: false,
            children: false,
            chunks: false,
            chunkModules: false
        }) + '\n\n');

    //error
    if (stats.hasErrors()) {
        console.log(chalk.red('  編譯失敗出現錯誤.\n'));
        process.exit(1);
    }

    //完成
    console.log(chalk.cyan('  編譯成功.\n'))
    console.log(chalk.yellow(
      '  file:// 無用,需http(s)://.\n'
    ))
  })

})
複製程式碼

7. 實用程式碼段 utils.js

const config = require('../config')
const path = require('path')
exports.assetsPath = function (_path) {
    const assetsSubDirectory = process.env.NODE_ENV === 'production'
        ? config.build.assetsSubDirectory // 'static'
        : config.dev.assetsSubDirectory
    return path.posix.join(assetsSubDirectory, _path) // posix方法修正路徑
}

exports.cssLoaders = function (options) { // 示例: ({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
  options = options || {};

  // cssLoader
  const cssLoader = {
    loader: 'css-loader',
    options: { sourceMap: options.sourceMap }
  }
  // postcssLoader
  var postcssLoader = {
    loader: 'postcss-loader',
    options: { sourceMap: options.sourceMap }
  }

  // 生成 loader
  function generateLoaders (loader, loaderOptions) {
    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] // 設定預設loader
    if (loader) {
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, { // 生成 options 物件
          sourceMap: options.sourceMap
        })
      })
    }

    // 生產模式中提取css
    if (options.extract) { // 如果 options 中的 extract 為 true 配合生產模式
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader' // 預設使用 vue-style-loader
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
  }

  return { // 返回各種 loaders 物件
    css: generateLoaders(),
    postcss: generateLoaders(),
    less: generateLoaders('less'), 
    // 示例:[
    // { loader: 'css-loader', options: { sourceMap: true/false } },
    // { loader: 'postcss-loader', options: { sourceMap: true/false } },
    // { loader: 'less-loader', options: { sourceMap: true/false } },
    // ]
    sass: generateLoaders('sass', { indentedSyntax: true }),
    scss: generateLoaders('sass'),
    stylus: generateLoaders('stylus'),
    styl: generateLoaders('stylus')
  }
}

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
    })
    // 示例:
    // {
    //   test: new RegExp(\\.less$),
    //   use: {
    //     loader: 'less-loader', options: { sourceMap: true/false }
    //   }
    // }
  }
  return output
}

exports.createNotifierCallback = function () { // 配合 friendly-errors-webpack-plugin
  // 基本用法:notifier.notify('message');
  const notifier = require('node-notifier'); // 傳送跨平臺通知系統

  return (severity, errors) => {
    // 當前設定是隻有出現 error 錯誤時觸發 notifier 傳送通知
    if (severity !== 'error') { return } // 嚴重程度可以是 'error''warning'
    const error = errors[0]

    const filename = error.file && error.file.split('!').pop();
    notifier.notify({
      title: pkg.name,
      message: severity + ': ' + error.name,
      subtitle: filename || ''
      // icon: path.join(__dirname, 'logo.png')  // 通知圖示
    })
  }
}
複製程式碼

8. babel配置檔案.babelrc

{ //設定轉碼規則
  "presets": [
    ["env", {
      "modules": false,
      //對BABEL_ENV或者NODE_ENV指定的不同的環境變數,進行不同的編譯操作
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  //轉碼用的外掛
  "plugins": ["transform-vue-jsx", "transform-runtime"]
}
複製程式碼

9 .編碼規範.editorconfig

root = true
 
[*]    // 對所有檔案應用下面的規則
charset = utf-8                    // 編碼規則用utf-8
indent_style = space               // 縮排用空格
indent_size = 2                    // 縮排數量為2個空格
end_of_line = lf                   // 換行符格式
insert_final_newline = true        // 是否在檔案的最後插入一個空行
trim_trailing_whitespace = true    // 是否刪除行尾的空格
複製程式碼

9 .src/main.js檔案解讀 main.js是整個專案的入口檔案

import Vue from 'vue'      
import App from './App'
import router from './router'
 
Vue.config.productionTip = false   //生產環境提示,這裡設定成了false
 
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }//引入App元件
})
複製程式碼

10 .src/app.vue檔案解讀

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view></router-view>
  </div>
</template>
 
<script>
export default {
  name: 'app'
}
</script>
 
<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
複製程式碼

<template></template>標籤包裹的內容:這是模板的HTMLDom結構 <script></script>標籤包括的js內容:你可以在這裡寫一些頁面的js的邏輯程式碼。 <style></style>標籤包裹的css內容:頁面需要的CSS樣式。

11. src/router/index.js 路由檔案

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
 
Vue.use(Router)
 
export default new Router({
  routes: [//配置路由
    {
      path: '/',//訪問路徑
      name: 'Hello',//路由名成
      component: Hello//路由需要的元件
    }
  ]
})
複製程式碼

具體的請參見vue-router。

總結:大概解讀了vue-cli專案目錄結構,如果你想完全弄明白vue-cli,最好是有調理的閱讀所有程式碼,這對你以後成為vue實際專案 的開發很有幫助。說實話,越來越喜歡vue了。第一次寫這麼多東西,寫的不好請大家諒解。

相關文章