Vue入坑教程(二)——项目结构详情介绍

Vue入坑教程(二)——项目结构详情介绍

之前已经介绍了关于Vue的脚手架vue-cli的安装,以及一些文件目录介绍。具体可以查看《vue 入坑教程(一)——搭建vue-cli脚手架》

下面简单说一下具体的文件介绍

(一) package.json 配置文件

package.json是项目的配置文件,里面是项目的相关的包依赖,npm运行命令,位于项目根目录。

{
 "name": "ddlcwecaht",                           ---------------------项目名称
  "version": "1.0.0",                            ---------------------项目版本号(以上两者是必须的,否则无法执行install)
  "description": "A Vue.js project",             ---------------------项目描述
  "author": "wujy",                              ---------------------作者名称(以上这些都和vue-cli搭建的时候填写的信息是一致的,当然这里也可以修改)
  "private": true,
  "scripts": {                                   ---------------------定义npm命令
    "dev": "webpack-dev-server --inline --progress --open --config build/webpack.dev.conf.js",       ------------cnpm run dev 运行项目
    "start": "npm run dev",                     ----------------------和上面的相同,运行项目
    "build": "node build/build.js"              ----------------------cnpm run build项目打包构建
  },
  "dependencies": {                              ---------------------运行时的依赖
    "axios": "^0.18.0",
    "vue": "^2.5.2",
    "vue-router": "^3.0.1",
    "vuex": "^3.0.1",
    "vux": "^2.9.0"
  },
  "devDependencies": {                        -----------------------开发时的依赖
    "autoprefixer": "^7.1.2",
    "babel-core": "^6.22.1",
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
    "babel-loader": "^7.1.1",
    "babel-plugin-import": "^1.7.0"
    ……
  },
  "engines": {                          -------------------------环境的版本号
    "node": ">= 6.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": [                      ------------------------浏览器的版本号
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

1. scripts

指定了运行脚本命令的npm命令行缩写,比如start指定了运行npm run start时,所要执行的命令。

dev: "webpack-dev-server --inline --progress --open --config build/webpack.dev.conf.js"

执行命令:cnpm run dev,其中webpack-dev-server启动本地的服务器, --inline --progress启动时分行展示启动的进度条,--open启动完成后自动打开浏览器,--config build/webpack.dev.conf.js启动时调用的配置文件

"build": "node build/build.js"  

执行的命令: cnpm run buildbuild/build.js运行时调用的配置文件,命令执行之后会生成一个dist文件夹,里面存放的是打包构建后的文档,用于正式环境。

2. dependencies 和 devDependencies

这两项分别是项目运行所依赖的模块、项目开发所依赖的模块。他们的成员比如 "vue": "^2.5.2",分别由模块名和对应的版本号组成,表示依赖的模块及其版本范围。

这些依赖在执行了cnpm install之后都会添加到node_modules文件夹中。

可以通过命令添加自己需要的依赖:(这里使用的是淘宝镜像)

#将该模块写入dependencies属性
cnpm install <name> --save  
#该模块写入devDependencies属性
cnpm install <name> --save-dev  

命令执行结束之后,刷新,可以看到package.json里面对应的增加了刚才下载的依赖,同样的在node_modules文件夹里也增加了相同对应的依赖

3. engines 和 browserslist

分别表示项目所需要的node.js版本号、浏览器的版本号。

注意:

  1. vue不支持IE8及其以下的版本。
  2. 注意本地的node的版本号是否符合。 可以打开命令行控制面板,通过node -vnpm -v查看本地的版本号
  3. package.json 文档中不能加注释,不然会报错

(二)src/router/index.js 路由文件

/* 使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)*/
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router); 
/*定义路由*/        
export default new Router({
  /*当切换到新路由时,想要页面滚到顶部。不设置页面将在默认的地方*/
  scrollBehavior(to, from, savedPosition) {
    return {x: 0, y: 0}
  },
  routes: [{                                ------------------------配置路由                 
    path: '/',                              ------------------------路由路径
    redirect: '/home'                       ------------------------路由重定向
  },
    {
      path: '/home',
      name: 'home',                        -------------------------路由需要的组件
      component: (resolve) => require(['@/views/home/home.vue'], resolve),         
    },
    {
      path: '/login',
      name: 'login',
      component: (resolve) => require(['@/views/login/login.vue'], resolve),
      meta: {         ---------------路由的元信息
        title: '登录'
      }
    },
  }]
})

具体的可以参考官网vue-router
代码中可以通过this.$router来使用,实现页面跳转,路由信息的传值。

(三) 基础配置文件 webpack.base.conf.js

这是webpack最为基础的配置文件,主要是来定义入口文件,处理vue,babel等各种模块。由此还有两个配置文件分别是开发环境配置文件 webpack.dev.conf.js 生产模式配置文件 webpack.prod.conf.js

/*定义变量,引入需要的配置*/
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
const vuxLoader = require('vux-loader')
var PostCompilePlugin = require('webpack-post-compile-plugin')
var TransformModulesPlugin = require('webpack-transform-modules-plugin')
/*处理路径的函数*/
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' ?                   //生产环境和开发环境判断,来确定引用的publicpath
      config.build.assetsPublicPath : config.dev.assetsPublicPath
  },
  resolve: {                                            //解析确定的扩展名,方便模块的导入
    extensions: ['.js', '.vue', '.json'],
    alias: {                                            //创建别名
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),                              //方便模块的引用,比如@/components/HelloWorld = src/components/HelloWorld
    }
  },
  module: {                                            //模块的相关配置
    rules: [{
      test: /.vue$/,
      loader: 'vue-loader',
      options: vueLoaderConfig
    },
      {
        test: /.js$/,
        loader: 'babel-loader',                        //babel,用来将es6转换为es5,解决部分浏览器不支持es6的问题
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
      },
      {
        test: /.(png|jpe?g|gif|svg)(?.*)?$/,       //图片类型
        loader: 'url-loader',                       //url-loader 文件大小低于指定的限制时,可返回 DataURL,即base64
        options: {
          limit: 10000,                            //默认无限制
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/,         //音频类型
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /.(woff2?|eot|ttf|otf)(?.*)?$/,               //字体类型
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  },
  node: {                    
    setImmediate: false,
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  },
  plugins:[                                       //可以添加自定义的插件
    new PostCompilePlugin(),
    new TransformModulesPlugin()
  ]
}

(四)开发环境配置文件 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 path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')          //引入webpack基础的配置文件
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')          //帮你自动生成一个html5文件, 这个文件中自动引用了你打包后的JS文件。每次编译都在文件名中插入一个不同的hash值。可以去打包后的dist文件夹中查看html文件
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')      //能在终端更好的查看webpack的警告和错误
const portfinder = require('portfinder')               //自动检索下一个可用端口,比如8080端口被占用,启动后会自动调用8081端口打开项目
const HOST = process.env.HOST               //读取系统环境变量host
const PORT = process.env.PORT && Number(process.env.PORT)       //读取系统环境变量端口号  
const devWebpackConfig = merge(baseWebpackConfig, {              //合并基础配置文件
  module: {
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
  },
  devtool: config.dev.devtool,
  devServer: {                                                   //webpack-dev-server服务器配置
    clientLogLevel: 'warning',
    historyApiFallback: {
      rewrites: [
        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
      ],
    },
    hot: true,                                    //开启热加载,热加载是指代码启动后,修改代码,会自动检测代码的更新,浏览器自动渲染更新的部分
    contentBase: false,
    compress: true,
    host: HOST || config.dev.host,
    port: PORT || config.dev.port,
    open: config.dev.autoOpenBrowser,                 //启动项目的时候自动打开浏览器,默认的是false。可以在config/index.js中修改为true,启动的时候就会自动打开浏览器
    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: [                                        //webpack一些构建用到的插件
    new webpack.DefinePlugin({
      'process.env': require('../config/dev.env')
    }),
    new webpack.HotModuleReplacementPlugin(),       //模块热替换它允许在运行时更新各种模块,而无需进行完全刷新
    new webpack.NamedModulesPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
   /*打包后会自动生成一个html文件,并自动将 打包过程中输出的js、css的路径添加到html文件中,css文件插入到head中*/
    new HtmlWebpackPlugin({
      filename: 'index.html',              // 指定编译后生成的html文件名
      template: 'index.html',
      inject: true                       
    }),
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.dev.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

module.exports = new Promise((resolve, reject) => {
  portfinder.basePort = process.env.PORT || config.dev.port
  portfinder.getPort((err, port) => {
    if (err) {
      reject(err)
    } else {
      process.env.PORT = port;
      devWebpackConfig.devServer.port = port;
      devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({          //webpack错误提示的插件
        compilationSuccessInfo: {
          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
        },
        onErrors: config.dev.notifyOnErrors
        ? utils.createNotifierCallback()
        : undefined
      }))
      resolve(devWebpackConfig)
    }
  })
})

(五)src/app.vue vue文件

<template>
  <div >
    <img src="./assets/logo.png">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'app',
  data(){
      return {}
  },
  methods:{}
}
</script>

<style lang="scss" scoped>
#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>
  1. <template></template>标签内存放的是 HTMLDOM 结构,注意:只能有一个*标签
  2. <script></script>标签内存放的是 js 内容,用来写逻辑代码。里面有data,methods,props,components……等,具体的可以参考Vue官网
  3. <style></style>标签内放的是 CSS 样式,加上scoped 表示该样式只在这个.vue文件中有效,还可以用scss来写,具体请自行百度查询。

(六)src/main.js 入口文件

import Vue from 'vue'
import router from './router'
Vue.config.productionTip = false;     //生产环境提示,这里设置成了false

// 引入reset.scss
import './assets/styles/reset.scss'

// 引入小图标
import 'font-awesome/css/font-awesome.css'

/*引入vue-awesome-swiper组件和样式,swsiper参考4.x的API,前提,先安装vue-awesome-swiper插件*/
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
Vue.use(VueAwesomeSwiper);
/*引入vuex*/
import store from '@/utils/vuex.js'
new Vue({router, store}).$mount('#app');

项目的入口文件main.js,全局的设置可以在这里添加。

(七)其他

  1. 编码规范.editorconfig
  2. babel配置文件.babelrc
  3. 实用代码段 utils.js
  4. 编译入口文件build.js
  5. 生产模式配置文件 webpack.prod.conf.js

写的有点乱,本文的参考文章:《vue-cli项目结构详解》,作者博客:tanzhenyan的博客