vue框架搭建

1.安装node环境

Node.js是-一个基于Chrome V8引擎的JavaScript 运行环境。

  1. 直接简单粗暴,下载对应版本的node包http://nodejs.cn/download/
  2. 使用node版本管理工具
    nvm全名node.js version management,顾名思义是一个nodejs的版本管理工具。
nvm install 11.13.0 // 安装node版本
nvm list  //  查看已安装的node版本
nvm use 11.13.0 // 使用某个特定的版本
nvm uninstall 11.13.0 // 卸载

npm,全称是 Node Package Manager =>node 包管理器

//  npm(国外受限制)可能下载包失败,直接指定源,改成国内镜像
npm set registry https://registry.npm.taobao.org/  //直接使用npm i 即可
// 或者安装cnpm 
npm install -g cnpm --registry=http://registry.npm.taobao.org
// 检测是否切换到了淘宝源
npm info underscore
// nrm是专门用来管理和快速切换私人配置的registry ls add use  ls
npm install nrm -g

号外~~~
npm和yarn的区别:
“Yarn是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具 ,正如官方文档中写的,Yarn 是为了弥补 npm 的一些缺陷而出现的。”这句话让我想起了使用npm时的坑了:
npm install的时候巨慢。特别是新的项目拉下来要等半天,删除node_modules,重新install的时候依旧如此。
同一个项目,安装的时候无法保持一致性。由于package.json文件中版本号的特点,下面三个版本号在安装的时候代表不同的含义。

Yarn的优点:
速度快 : 并行安装:无论 npm 还是 Yarn 在执行包的安装时,都会执行一系列任务。npm 是按照队列执行每个 package,也就是说必须要等到当前 package 安装完成之后,才能继续后面的安装。而 Yarn 是同步执行所有任务,提高了性能;离线模式:如果之前已经安装过一个软件包,用Yarn再次安装时之间从缓存中获取,就不用像npm那样再从网络下载了。
安装版本统一:为了防止拉取到不同的版本,Yarn 有一个锁定文件 (lock file) 记录了被确切安装上的模块的版本号。每次只要新增了一个模块,Yarn 就会创建(或更新)yarn.lock 这个文件。这么做就保证了,每一次拉取同一个项目依赖时,使用的都是一样的模块版本。npm 其实也有办法实现处处使用相同版本的 packages,但需要开发者执行 npm shrinkwrap 命令。这个命令将会生成一个锁定文件,在执行 npm install 的时候,该锁定文件会先被读取,和 Yarn 读取 yarn.lock 文件一个道理。npm 和 Yarn 两者的不同之处在于,Yarn 默认会生成这样的锁定文件,而 npm 要通过 shrinkwrap 命令生成 npm-shrinkwrap.json 文件,只有当这个文件存在的时候,packages 版本信息才会被记录和更新。
更简洁的输出:npm 的输出信息比较冗长。在执行 npm install 的时候,命令行里会不断地打印出所有被安装上的依赖。相比之下,Yarn 简洁太多:默认情况下,结合了 emoji直观且直接地打印出必要的信息,也提供了一些命令供开发者查询额外的安装信息。
多注册来源处理:所有的依赖包,不管他被不同的库间接关联引用多少次,安装这个包时,只会从一个注册来源去装,要么是 npm 要么是 bower, 防止出现混乱不一致。
更好的语义化: yarn改变了一些npm命令的名称,比如 yarn add/remove,感觉上比 npm 原本的 install/uninstall 要更清晰。
前期工作准备就绪,切入正题。

2.全局安装vue-cli

  1. 前期准备
vue -V // 可以通过命令查看你以前有没有安装过vue-cli
//或者
vue -version
npm install -g @vue/cli
//安装3.0以上指定版本
// npm install -g @vue/cli@版本号

如过之前已经安装过其他版本的vue-cli,在安装新版本或者指定版本的vu-cli,需要通过命令卸载之前的,命令:

//卸载3.0之前的版本
npm uninstall -g vue-cli
//卸载3.0之后的版本(可以统一使用此指令卸载)
npm uninstall -g @vue/cli

安装了vue-cli后会默认帮我们安装最新版本的vue,我们可以通过npm list vue命令查看默认安装的vue版本。如果我们不想要此版本的vue,我们可以另外安装我们指定版本的vue

npm install vue -g@版本号

2.项目搭建
新建文件夹存放此前端项目

npm install -g @vue/cli-init
//vue-cli2.x的初始化方式,可以使用githab上面的一些模板来初始化项目,webpack是官方推荐的标准模板名
vue init webpack 项目名称 // 创建一个基于 webpack 模板的新项目 old
//vue-cli3.x的初始化方式,目前模板是固定的,模板选项可自由配置
vue create 项目名称
这个自行选择配置,按上下键切换目标选项,按空格键勾选和取消,按a全选,按i反选,选好后回车确定

//1、Babel,转译成浏览器可识别的语言,可以让你的项目支持最新的语法,如es6\es7等
//2、TypeScript,新增的选项卡
//3、PWA,模拟原生app,渐进式网络应用程序(渐进式增强WEB应用)
//4、路由
//5、vuex管理模式
//6、css预处理语言
//7、代码规范
//8、组件单元测试
//9、端对端测试,模拟用户真实场景

3.开发用到的资源包

–save:将保存配置信息到pacjage.json的dependencies节点中。

–save-dev:将保存配置信息到pacjage.json的devDependencies节点中。

dependencies:运行时的依赖,发布后,即生产环境下还需要用的模块

devDependencies:开发时的依赖。里面的模块是开发时用的,发布时用不到它。

// dependencies依赖的包不仅开发环境能使用,生产环境也能使用
"axios": "接口请求", 
"babel-polyfill": "语法的解析",
"vue": "vue框架",
"vue-router": "路由跳转",
"vuex": "状态管理器"
"file-saver“:"文件导出"
"vue-count-to": "数字滚动"
....
 // devDependencies  
 // Babel 是一个JavaScript 编译器
   "@babel/core": "7.0.0",  // es6+语法转换低版本js,以便能够运行在当前和旧版本的浏览器或其他环境中
   "@babel/register": "7.0.0", //另一个使用 Babel 的方法是通过 require 钩子(hook)。require 钩子 将自身绑定到 node 的 
   "@vue/cli-plugin-babel": "3.6.0",
   "@vue/cli-plugin-eslint": "^3.12.1",
   "@vue/cli-plugin-unit-jest": "3.6.3",
   "@vue/cli-service": "3.6.0",
   "@vue/test-utils": "1.0.0-beta.29",
   "autoprefixer": "^9.7.4", // CSS将仅包含实际的浏览器前缀
   "babel-core": "7.0.0-bridge.0",
   "babel-eslint": "10.0.1",
   "babel-jest": "23.6.0", // 单元测试
   "chalk": "2.4.2", // 颜色模块 chalk 这个包是为了使输出不再单调,添加文字背景什么的,改变字体颜色什么的,
   "connect": "3.6.6", // 其作用是基于Web服务器做中间件管理
   "eslint": "5.15.3",
   "eslint-plugin-vue": "5.2.2", // 自动修复eslint报错
   //html-webpack-plugin 该插件的两个主要作用:
//为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
// 可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口
   "html-webpack-plugin": "3.2.0", 
   "less": "^4.1.1",
   "less-loader": "^7.3.0", // 将 Less 编译为 CSS 的 loader
   "lodash": "^4.17.20",
   "mockjs": "1.0.1-beta3",
   "sass-loader": "^7.3.1",
   "script-ext-html-webpack-plugin": "2.1.3", // HTML Webpack 插件的脚本扩展
   "script-loader": "^0.7.2", //在全局上下文(global context)执行一次 JS 脚本。
   "serve-static": "^1.13.2", // 静态资源访问
   "svg-sprite-loader": "4.1.3", // 处理svg图片
   "svgo": "1.2.2", // 用于优化 SVG 矢量图形文件的工具
   "vue-skeleton-component": "^1.1.2", // 骨架屏
   "vue-template-compiler": "2.6.10", // 该模块可用于将 Vue 2.0 模板预编译为渲染函数(template => ast => render),以避免运行时编译开销和 CSP 限制。大都数场景下,与 vue-loader一起使用,只有在编写具有非常特定需求的构建工具时,才需要单独使用它
   "xterm": "^4.8.1" // 前端终端组件
   ...
    "5.0.3",
	"~5.0.3",
	"^5.0.3"5.0.3”表示安装指定的5.0.3版本,“~5.0.3”表示安装5.0.X中最新的版本,“^5.0.3”表示安装5.X.X中最新的版本。

4.webpack 相关

开发环境配置 --build/webpack.dev.config.js
生产环境配置 --build/webpack.prod.config.js
提取公共基础配置文件 --build/webpack.base.config.js
使用 webpack-merge合并配置文件

build/webpack.base.config.js基础文件内容如下

/*
1.配置webpack编译入口
2.配置webpack输出路径和命名规则
3.配置模块resolve规则
4.配置不同类型模块的处理规则 */

'use strict';
const path = require('path');
// node.js的文件路径,用来处理文件当中的路径问题
const baseconfig = require('../config');
//基础环境变量的配置信息
const utils = require('./utils');
//处理css的工具包
const isDev = process.env.NODE_ENV === 'development';
const vueLoaderConfig = require('./vue-loader.config');
// vue-loader.conf配置文件是用来解决各种css文件的,定义了诸如css,less,sass之类的和样式有关的loader

function resolve(dir) {
    return path.join(__dirname, '..', dir)
}
// 此函数是用来返回当前目录的平行目录的路径,因为有个'..'

const config = {
    context: path.resolve(__dirname, '../'),
    //基础目录(绝对路径),用于从配置中解析入口点和加载程序 以应用程序为根目录 普通字符串代表子目录 /代表绝对路径根目录
    //   指明入口函
    entry: {
        app: './src/main.js'
    },
    // 定义入口文件
 
  // 输出配置项
  output: {
    // 路径,从config/index读取的,值为:工程目录下的dist目录,需要的自定义的也可以去修改
    path: config.build.assetsRoot,
    // 发布路径,这里是的值为/,正式生产环境可能是服务器上的一个路径,也可以自定义
    publicPath: process.env.NODE_ENV === 'production' ?    config.build.assetsPublicPath : config.dev.assetsPublicPath,
    filename: '[name].js'
    },
   resolve: {
    // 当使用require或者import的时候,自动补全下面的扩展名文件的扩展名,也就是说引入的时候不需要使用扩展名
        extensions: ['.js', '.vue', '.json'],
        // 省略扩展名,比方说import index from '../js/index'会默认去找index文件,然后找index.js,index.vue,index.json文件
        // 当我们require的东西找不到的时候,可以去node_modules里面去找,
        fallback: [path.join(__dirname, '../node_modules')],
        // 别名 来缩短我们需要的路径的长度
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
            '@': resolve('src'),
        }
        // 使用别名  使用上面的resolve函数,意思就是用@代替src的绝对路径
    },
    
  // 对相应文件的编译使用什么工具的配置
    // loader之前的配置,会对.vue,.js的文件用eslint进行编译,include是包含的文件,exclude是排除的文件,可以使用的正则
 // 这里也是相应的配置,test就是匹配文件,loader是加载器,
    // query比较特殊,当大小超过10kb的时候,会单独生成一个文件,文件名的生成规则是utils提供的方法,当小于10kb的时候,就会生成一个base64串放入js文件中

    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: vueLoaderConfig
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                include: [resolve('src'), resolve('test')]
            },
            {
                test: /\.jsx$/,
                loader: 'babel-loader'
            },
            {
              test: /\.css$/,
              use: [
                'style-loader', //将css以js形式插入HTML中
                'css-loader', //专门处理css文件
              ]
            },
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,// 文件大小小于10000则编译成base64格式代码
                    name: utils.assetsPath('resources/images/[name].[hash:8].[ext]') //指定输出文件的名字
                },
            },
            {
                test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,// 文件大小小于10000则编译成base64格式代码
                    name: utils.assetsPath('resources/mp4/[name].[hash:8].[ext]')  //指定输出文件的名字
                }
            },
            {
                test: /\.(woff2?|eot|ttf|otf|ico)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,// 文件大小小于10000则编译成base64格式代码
                    name: utils.assetsPath('resources/icon/[name].[hash:8].[ext]')
                }
            }
        ]
    },
    // 不同文件模块使用不同的loader
    node: {
        setImmediate: false,
        dgram: 'empty',
        fs: 'empty',
        net: 'empty',
        tls: 'empty',
        child_process: 'empty',
    }
    //这些选项可以配置是否 polyfill 或 mock 某些 Node.js 全局变量和模块。这可以使最初为 Node.js 环境编写的代码,在其他环境(如浏览器)中运行.
};
module.exports = config;

build/webpack.dev.config.js开发环境配置文件:

/*
1.引入相关插件和配置
2.生成处理各种样式的规则
3.配置开发环境,如热更新、监听端口号,是否自动打开浏览器等都在webpack中的devServer中配置完成
4.寻找可利用的端口和添加显示程序编译运行时的错误信息。*/

'use strict';
const path = require('path');
//基础环境变量的配置信息
const utils = require('./utils');
//处理css的工具包
const webpack = require('webpack');
// 引入webpack模块
const merge = require('webpack-merge');
// 将基础配置和开发环境配置或者生产环境配置合并在一起的包管理
const baseWebpackConfig = require('./webpack.base.config');
// 引入基本webpack基本配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 文件名及时更改,自动打包并且生成响应的文件在index.html里面
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
//当前环境的host
const HOST = process.env.HOST;// processs为node的一个全局对象获取当前程序的环境变量,即host
//当前环境的port
const PORT = process.env.PORT && Number(process.env.PORT);
const baseconfig = require('../config');

const isDev = process.env.NODE_ENV === 'development';
const defaultPlugins = [
  //webpack编译过程中以及页面上判断环境,js代码中可以引用到,用于区分环境
  new webpack.DefinePlugin({
    'process.env': {
      NODE_ENV: isDev ? '"development"':'"production"'
    }
  }),
  new VueLoaderPlugin(),
  //HTMLPlugin:添加HTML入口,可以设置基础参数
  new HtmlWebpackPlugin({
    template: path.join(__dirname,'../index.html')
  })
];
const devServer = {
  port: PORT || baseconfig.dev.port, //启动监听端口
  disableHostCheck: true,
  host: HOST || baseconfig.dev.host,
  // 如果编译过程中有错误,将错误显示到网页上
  overlay: baseconfig.dev.errorOverlay
    ? { warnings: false, errors: true }
    : false,// warning 和 error 都要显示
  compress: true,// 一切服务都启动用gzip方式进行压缩代码
  hot: true, // 只重新渲染页面当前组件的效果,而不会刷新这个页面,每次渲染时数据依然存在
  //将没有做映射的url路由地址,都映射到index.html中,即当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html
  historyApiFallback: {
    rewrites: [
      { from: /.*/, to: path.posix.join(baseconfig.dev.assetsPublicPath, 'index.html') },
    ],
  },
  open: baseconfig.dev.autoOpenBrowser, // 启动webpack-dev-server时,自动打开网页
  proxy: baseconfig.dev.proxyTable,//接口代理
  // 如果你有单独的后端开发服务器API,并且希望在同域名下发送API请求,那么代理某些URL将很有用.简称就是API代理,中间件  需引入 http-proxy-middleware
  quiet: false, // necessary for FriendlyErrorsPlugin
  // 启用quiet后,除了初始启动信息之外的任何内容都不会被打印到控制台。这也意味着来自的WebPack的错误或警告在控制台不可见。
};

const devWebpackConfig = merge(baseWebpackConfig,{
  // devtool:'#cheap-module-eval-source-map', //帮助页面上调试代码
  module: {
    rules: [
      {
        test: /\.scss/, //css预处理器 后缀名.scss
        use: [
          'vue-style-loader', //将css以js形式插入HTML中
          'css-loader', //专门处理css文件
          {
            loader: "postcss-loader",
            options: {
              sourceMap: true, //直接使用前面生成的sourceMap,编译的效率会快点
            }
          },
          'sass-loader' //专门处理sass文件,转为css文件,不处理css
        ]
      }
    ]
  },
  devServer:devServer,
  plugins: defaultPlugins.concat([
    //启动hot加载的功能的plugin
    new webpack.HotModuleReplacementPlugin(),// 永远不能用在生产模式,模块热更新,修改文件的内容,允许在运行时更新各种模块,而无需进行完全刷新。
    new webpack.NamedModulesPlugin(), // 当进行热更新时,相关文件名会被展示出来
    new webpack.NoEmitOnErrorsPlugin(), // 跳过编译时出错的代码并记录,使编译后运行时的包不会发生错误。
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }),
    // 该插件可自动生成一个 html5 文件或使用模板文件将编译好的代码注入进去
    new CopyWebpackPlugin([//复制插件
      {
        from: path.resolve(__dirname, '../static'),
        to: baseconfig.dev.assetsSubDirectory,
        ignore: ['.*']//忽略.*的文件
      }
    ])
  ]),
});

module.exports = devWebpackConfig;

build/webpack.prod.config.js开发环境配置文件:

/*
1.合并基础的webpack配置
2.配置样式文件的处理规则,styleLoaders
3.配置webpack的输出
4.配置webpack插件
5.gzip模式下的webpack插件配置
6.webpack-bundle分析 */

'use strict';
const path = require('path');
// node.js的文件路径,用来处理文件当中的路径问题
const webpack = require('webpack');
// 引入webpack模块
const CopyWebpackPlugin = require('copy-webpack-plugin');
// 在webpack中拷贝文件和文件夹
const merge = require('webpack-merge');
// 将基础配置和开发环境配置或者生产环境配置合并在一起的包管理
const baseWebpackConfig = require('./webpack.base.config');
// 引入基本webpack基本配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 文件名即使更改,自动打包并且生成响应的文件在index.html里面
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');// 压缩css代码
const miniCssExtractPlugin=require("mini-css-extract-plugin"); // css单独提取打包
//一个用来压缩优化CSS大小的东西
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
// 一个用来压缩优化JS大小的东西
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const env = require('../config/prod.env');
const utils = require('./utils');
const baseconfig = require('../config');//导入基础配置
const serverConfig = require('../serverConfig.json');//导入,可修改的公共域名

const defaultPlugins = [
  //webpack编译过程中以及页面上判断环境,js代码中可以引用到,用于区分环境
  new webpack.DefinePlugin({
    'process.env': env
  }),
  new VueLoaderPlugin(),
  //HTMLPlugin:添加HTML入口,可以设置基础参数
  new HtmlWebpackPlugin({
    template: path.join(__dirname,'../index.html'),
    inject: true,
    minify: {//压缩
      removeComments: true,//删除注释
      collapseWhitespace: true,//删除空格
      removeAttributeQuotes: true//删除属性的引号
    },

    chunksSortMode: 'dependency'//模块排序,按照我们需要的顺序排序
  })
];

//让打包的时候输出可配置的文件
const GenerateAssetPlugin = require('generate-asset-webpack-plugin');
const createServerConfig = function(compilation){
  return JSON.stringify(serverConfig);
}

// 引入生产环境
const webpackConfig = merge(baseWebpackConfig,{
  // 这一部分会单独打包成类库文件,方便浏览器缓存 会生成一个vendor.js代码,包含类库代码
  entry: {
    app: path.join(__dirname, "../src/main.js"),
  },
  output: {
    filename: utils.assetsPath('js/[name].[chunkHash:8].js'),
    path: baseconfig.build.assetsRoot,
    chunkFilename: utils.assetsPath('js/[id].[chunkHash].js')
  },
  module: {
    rules: [
      {
        test: /\.scss/, //css预处理器 后缀名.scss
        use: [
          {
            loader:miniCssExtractPlugin.loader,
            options:{
              publicPath: '../'
            }
          },
          'css-loader', //专门处理css文件
          {
            loader: "postcss-loader",
            options: {
              sourceMap: true, //直接使用前面生成的sourceMap,编译的效率会快点
            }
          },
          'sass-loader' //专门处理sass文件,转为css文件,不处理css
        ]
      }
    ]
  },
  optimization: {
    minimizer: [
      new OptimizeCSSAssetsPlugin({}),
    ],
    splitChunks: {
      chunks: 'all'
    },
    runtimeChunk: true // webpack相关代码打包到一个文件中,好处:可以规避新的模块加入的时候,webpack给新的模块加id后,插入的顺序可能在中间,使后面模块id变化,会导致打包出的hash产生变化,这样hash就不能进行常缓存
  },
  plugins: defaultPlugins.concat([
    new miniCssExtractPlugin({filename: 'css/main.[contentHash:8].css'}),
    //让打包的时候输入可配置的文件
    new GenerateAssetPlugin({
      filename: 'serverconfig.json',
      fn: (compilation, cb) => {
        cb(null, createServerConfig(compilation));
      },
      extraFiles: []
    }),
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: path.join(__dirname, '../dist'),
        ignore: ['.*']
      },
    ]),
  ])
});
module.exports = webpackConfig;

build文件夹下utils.js文件是用来处理css的文件

/*utils是工具的意思,是一个用来处理css的文件*/
'use strict';
const path = require('path');
const baseconfig = require('../config');

//导出文件的位置,根据环境判断开发环境和生产环境,为config文件中index.js文件中定义的build.assetsSubDirectory或dev.assetsSubDirectory
exports.assetsPath = function (_path) {
  const assetsSubDirectory = process.env.NODE_ENV === 'production'
    ? baseconfig.build.assetsSubDirectory
    : baseconfig.dev.assetsSubDirectory
//Node.js path 模块提供了一些用于处理文件路径的小工具①
  return path.posix.join(assetsSubDirectory, _path)
}

config/index.js

'use strict';//严格模式
const path = require('path');

module.exports = {
  dev:{
    // 开发环境下面的配置
    assetsSubDirectory: './static',//子目录,一般存放css,js,image等文件
    assetsPublicPath: './',//根目录
    proxyTable: {},//可利用该属性解决跨域的问题
    host: 'localhost', // 地址
    port: 8080, //端口号设置,端口号占用出现问题可在此处修改
    autoOpenBrowser: false,//是否在编译(输入命令行npm run dev)后打开http://localhost:8080/页面,以前配置为true,近些版本改为false,个人偏向习惯自动打开页面
    errorOverlay: true,//浏览器错误提示
    notifyOnErrors: true,//跨平台错误提示
    poll: false, //使用文件系统(file system)获取文件改动的通知devServer.watchOptions
    devtool: 'cheap-module-eval-source-map',//增加调试,该属性为原始源代码(仅限行)不可在生产环境中使用
    cacheBusting: true,//使缓存失效
    cssSourceMap: true//代码压缩后进行调bug定位将非常困难,于是引入sourcemap记录压缩前后的位置信息记录,当产生错误时直接定位到未压缩前的位置,将大大的方便我们调试
  },
  build: {
    // 生产环境下面的配置
    index: path.resolve(__dirname, '../dist/index.html'),//index编译后生成的位置和名字,根据需要改变后缀,比如index.php
    assetsRoot: path.resolve(__dirname, '../dist'),//编译后存放生成环境代码的位置
    assetsSubDirectory: './static',//js,css,images存放文件夹名
    assetsPublicPath: './',//发布的根目录,通常本地打包dist后打开文件会报错,此处修改为./。如果是上线的文件,可根据文件存放位置进行更改路径
    productionSourceMap: true,
    devtool: '#source-map',//①
    //unit的gzip命令用来压缩文件,gzip模式下需要压缩的文件的扩展名有js和css
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    bundleAnalyzerReport: process.env.npm_config_report
  }
}

postcss.config.js:配置css在不同浏览器上的添加前缀

const autoprefixer = require('autoprefixer');
module.exports = {
    plugins: [
      require('autoprefixer')({
        "overrideBrowserslist": [
          "defaults",
          "not ie < 11",
          "last 2 versions",
          "> 1%",
          "iOS 7",
          "last 3 iOS versions"
        ]
      })
    ]
}

vue cli 3.xx
在使用vue-cli3创建项目后,因为webpack的配置均被隐藏了,当你需要覆盖原有的配置时,则需要在项目的根目录下,新建vue.config.js文件,来配置新的配置。

module.exports = {
    // 基本路径
    publicPath: '/',
    // 输出文件目录
    outputDir: 'dist',
    // eslint-loader 是否在保存的时候检查
    lintOnSave: false,
    // use the full build with in-browser compiler?
    // https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
    runtimeCompiler: false,
    // webpack配置
    // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
    chainWebpack: () => {},
    configureWebpack: () => {},
    // vue-loader 配置项
    // https://vue-loader.vuejs.org/en/options.html
    // vueLoader: {},
    // 生产环境是否生成 sourceMap 文件
    productionSourceMap: false,
    // css相关配置
    /*css: {
        // 是否使用css分离插件 ExtractTextPlugin
        extract: true,
        // 开启 CSS source maps?
        sourceMap: false,
        // css预设器配置项
        loaderOptions: {},
        // 启用 CSS modules for all css / pre-processor files.
        modules: false
    },*/
    // use thread-loader for babel & TS in production build
    // enabled by default if the machine has more than 1 cores
    parallel: require('os').cpus().length > 1,
    // 是否启用dll
    // See https://github.com/vuejs/vue-cli/blob/dev/docs/cli-service.md#dll-mode
    // dll: false,
    // PWA 插件相关配置
    // see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
    pwa: {},
    // webpack-dev-server 相关配置
    devServer: {
        // open: process.platform === 'darwin',
        //将服务启动后默认打开浏览器
        open: true,
        host: '0.0.0.0',
        port: 8080,
        https: false,
        hotOnly: false,
        proxy: {// 设置代理
            '/api': {
                target: 'http://www.lzzyaf.com',
                changeOrigin: true,
                pathRewrite: {
                    '^/api': '/'
                }
            }
        },
        before: app => {}
    },
    // 第三方插件配置
    pluginOptions: {
        // ...
    }
}

5 生命周期

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li>
        <a
          href="https://vuejs.org"
          target="_blank"
        >
          Core Docs
        </a>
      </li>
      <li>
        <a
          href="https://forum.vuejs.org"
          target="_blank"
        >
          Forum
        </a>
      </li>
      <li>
        <a
          href="https://chat.vuejs.org"
          target="_blank"
        >
          Community Chat
        </a>
      </li>
      <li>
        <a
          href="https://twitter.com/vuejs"
          target="_blank"
        >
          Twitter
        </a>
      </li>
      <br>
      <li>
        <a
          href="http://vuejs-templates.github.io/webpack/"
          target="_blank"
        >
          Docs for This Template
        </a>
      </li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li>
        <a
          href="http://router.vuejs.org/"
          target="_blank"
        >
          vue-router
        </a>
      </li>
      <li>
        <a
          href="http://vuex.vuejs.org/"
          target="_blank"
        >
          vuex
        </a>
      </li>
      <li>
        <a
          href="http://vue-loader.vuejs.org/"
          target="_blank"
        >
          vue-loader
        </a>
      </li>
      <li>
        <a
          href="https://github.com/vuejs/awesome-vue"
          target="_blank"
        >
          awesome-vue
        </a>
      </li>
    </ul>
     <span class="value">{{value}}</span>
     <el-button  class="search-btn" size="small"  type="primary" @click="handle">点我点我点我</el-button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      value: 0
    }
  },
  beforeCreate () {
    // 在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化,
    // 因此无法访问methods, data, computed等上的方法和数据。
    console.log('创建前 ')
  },
  created () {
    // 实例已经创建完成之后被调用,在这一步,实例已完成以下配置:数据观测、属性和方法的运算,
    // watch/event事件回调,完成了data 数据的初始化,el没有。 然而,挂在阶段还没有开始, $el属性目前不可见,
    // 这是一个常用的生命周期,因为你可以调用methods中的方法,改变data中的数据,
    // 并且修改可以通过vue的响应式绑定体现在页面上,
    // ,获取computed中的计算属性等等,通常我们可以在这里对实例进行预处理,也有一些童鞋喜欢在这里发ajax请求,值得注意的是,这个周期中是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不适合在这个方法发请求,
    // 建议在组件路由钩子beforeRouteEnter中完成
    console.log('创建后')
  },
  beforeMount () {
    // 挂在开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成以下的配置: 编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上
    console.log('beforeMount')
  },
  methods: {
    handle () {
      this.value += 1
    }
  },
  mounted () {
    // 挂在完成,也就是模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。
    console.log('mounted')
  },
  beforeUpdate () {
    // 在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程
    console.log('更新前')
  },
  updated () {
    // 在由于数据更改导致地虚拟DOM重新渲染和打补丁只会调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多是情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用
    console.log('更新后')
  },
  beforeDestroy () {
    //     在实例销毁之前调用,实例仍然完全可用,
    // 这一步还可以用this来获取实例,
    // 一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件
    console.log('销毁前')
  },
  destroyed () {
    // 在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁,
    // 该钩子在服务器端渲染期间不被调用
    console.log('销毁后')
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
.value{
  font-size: 24px;
}
</style>

new Vue()

init Event & Lifecycle: 先进行初始化生命周期、事件,但数据代理未开始

beforeCreate:无法通过vm 访问到data中的数据、methods中的方法

init Reactive & Injections : 初始化数据监听,数据代理

created : 可以通过vm 访问到data中的数据、methods中的方法

has ‘el’ option? has ‘template’ option? : 开始解析模板,生成虚拟dom(内存中),还没挂载到页面上(未将虚拟dom渲染成真实dom) 大致过程: 有el 直接挂载到el上 没有 找到 mount() 中挂载的对象,有template 属性直接将页面整个替换,不保留挂载元素,没有直接解析,保留挂载元素

beforeMount : 此时页面呈现的是未经过 vue 编译的dom 结构 (原始dom,例如:{{n}} 会原封不动的显示在页面上,等待vue渲染)

create ‘$el’ and replace ‘el’ with it : 将虚拟dom 转为真实 dom 并插入页面 自己保存一份 留着在比较算法中使用

mounted : 此时页面中显示的是经过 vue 编译的 dom , 至此初始化阶段结束,一般可以在这个阶段进行: 开启定时器、网络请求、绑定自定义事件、订阅消息等。

beforeUpdate : 数据已经改变 但是页面还没更新,页面尚未和数据保持一致

更新数据,生成新的虚拟dom 与旧的虚拟dom 进行比较,重复的复用,不同的更新。完成model -> view 的更新

update : 此时 数据是新的 页面也是新的

当调用 vm.$destroy 进入销毁流程 : 触发beforeDestroy 和 destroyed 钩子,清理当前销毁的实例和其他实例的链接,解绑他的所有指令和(自定义)事件监听器(@click 事件 已经初始化元素的点击事件(原生事件),销毁不了了),此时vm 不在工作, 页面还在,但继续操作各种绑定效果没了。

beforeDestroy : 将要要进行销毁,可以访问函数,但是不会触发更新环节。一般在这个阶段进行:关闭定时器、取消订阅消息、解绑自定义事件等收尾工作。

destroyed :销毁完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值