Vue CLI 2.x搭建vue(目录最全分析)


Posted in Javascript onFebruary 27, 2019

一、vue-cli介绍

vue-cli是一个用于快速搭建vue项目的 脚手架。

二、vue-cli安装、更新

安装过nodeJs 、cnpm 后,全局安装vue-cli(以后其他项目可直接使用):

cnpm install -g vue-cli

更新:

cnpm update vue-cli

查看安装成功否(有版本号就是成功,V大写)

vue -V

查看npm注册表里vue-cli版本号:

cnpm view vue-cli

三、vue-cli 使用

安装过webpack 、vue-cli后,可以开始搭建vue项目:

vue init webpack <Project Name>

eg:右击Git Base Here(如果你没有用git ,你也可以按住shift键右击选择“在此处打开命令窗口”,或者 cmd :cd \project/lfxProject),如图:

Vue CLI 2.x搭建vue(目录最全分析)or

ps:ESLint(一个javascript代码检测工具)、unit tests(单元测试)、Nightwatch(一个e2e用户界面测试工具)。

四、项目完成

项目结构如下:

Vue CLI 2.x搭建vue(目录最全分析)

各文件作用解析,如下:

1、build文件夹:

build文件夹的结构:

Vue CLI 2.x搭建vue(目录最全分析)

(1)build.js

'use strict'
require('./check-versions')() //调用版本检查

process.env.NODE_ENV = 'production' //将环境配置为生产环境
const ora = require('ora') //npm包 loading插件
const rm = require('rimraf') //npm包 用于删除文件
const path = require('path')//npm包 文件路径工具
const chalk = require('chalk')//npm包 在终端输出带颜色的文字
const webpack = require('webpack')//引入webpack.js
const config = require('../config')//引入配置文件
const webpackConfig = require('./webpack.prod.conf')//引入生产环境配置文件
// 在终端显示loading效果,并输出提示
const spinner = ora('building for production...')
spinner.start()
//先递归删除dist文件再生成新文件,避免冗余
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
 if (err) throw err
 webpack(webpackConfig, (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')

  if (stats.hasErrors()) {
   console.log(chalk.red(' Build failed with errors.\n'))
   process.exit(1)
  }

  console.log(chalk.cyan(' Build complete.\n'))
  console.log(chalk.yellow(
   ' Tip: built files are meant to be served over an HTTP server.\n' +
   ' Opening index.html over file:// won\'t work.\n'
  ))
 })
})

ps:require/export是一种nodeJs(commonJs规范)的依赖注入的方法,import/export是ES6语法,用于引入模块,在nodeJs中使用的ES6语法最终会使用babel工具(babel-loader)转化为ES5

(2)check-version.js:检测node和npm的版本,实现版本依赖

'use strict'
const chalk = require('chalk')
const semver = require('semver')//检查版本
const packageConfig = require('../package.json')
const shell = require('shelljs')//shelljs 模块重新包装了 child_process,调用系统命令更加方便

function exec (cmd) {//返回通过child_process模块的新建子进程,执行 Unix 系统命令后转成没有空格的字符串
 return require('child_process').execSync(cmd).toString().trim()
}

const versionRequirements = [
 {
  name: 'node',
  currentVersion: semver.clean(process.version),//使用semver格式化版本
  versionRequirement: packageConfig.engines.node //获取package.json中设置的node版本
 }
]

if (shell.which('npm')) {
 versionRequirements.push({
  name: 'npm',
  currentVersion: exec('npm --version'),// 自动调用npm --version命令,并且把参数返回给exec函数,从而获取纯净的版本号
  versionRequirement: packageConfig.engines.npm
 })
}

module.exports = function () {
 const warnings = []
 for (let i = 0; i < versionRequirements.length; i++) {
  const mod = versionRequirements[i]
  //若版本号不符合package.json文件中指定的版本号,就报错
  if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
   warnings.push(mod.name + ': ' +
    chalk.red(mod.currentVersion) + ' should be ' +
    chalk.green(mod.versionRequirement)
   )
  }
 }

 if (warnings.length) {
  console.log('')
  console.log(chalk.yellow('To use this template, you must update following to modules:'))
  console.log()
  for (let i = 0; i < warnings.length; i++) {
   const warning = warnings[i]
   console.log(' ' + warning)
  }
  console.log()
  process.exit(1)
 }
}

(3)utils.js:utils是工具的意思,是一个用来处理css的文件,这个文件包含了三个工具函数:

  • 生成静态资源的路径
  • 生成 ExtractTextPlugin对象或loader字符串
  • 生成 style-loader的配置
var path = require('path')// node自带的文件路径工具
var config = require('../config')// 配置文件
var ExtractTextPlugin = require('extract-text-webpack-plugin')// 提取css的插件

/** @method assertsPath 生成静态资源的路径(判断开发环境和生产环境,为config文件中index.js文件中定义assetsSubDirectory)
 * @param {String}  _path 相对于静态资源文件夹的文件路径
 * @return {String}     静态资源完整路径
 */
exports.assetsPath = function (_path) {
 var assetsSubDirectory = process.env.NODE_ENV === 'production'
  ? config.build.assetsSubDirectory
  : config.dev.assetsSubDirectory
 //nodeJs path提供用于处理文件路径的工具;path.posix提供对路径方法的POSIX(可移植性操作系统接口)特定实现的访问(可跨平台); path.posix.join与path.join一样,不过总是以 posix 兼容的方式交互
 return path.posix.join(assetsSubDirectory, _path)
}

/**@method cssLoaders 生成处理css的loaders配置,使用css-loader和postcssLoader,通过options.usePostCSS属性来判断是否使用postcssLoader中压缩等方法
 * @param {Object} option = {sourceMap: true,// 是否开启 sourceMapextract: true // 是否提取css}生成配置
 * @return {Object} 处理css的loaders配置对象
 */
exports.cssLoaders = function (options) {
 options = options || {}

 var cssLoader = {
  loader: 'css-loader',
  options: {
   minimize: process.env.NODE_ENV === 'production',
   sourceMap: options.sourceMap
  }
 }
 /**@method generateLoaders 生成 ExtractTextPlugin对象或loader字符串
  * @param {Array}    loaders loader名称数组
  * @return {String|Object}    ExtractTextPlugin对象或loader字符串
  */
 function generateLoaders (loader, loaderOptions) {
  var loaders = [cssLoader]
  if (loader) {
   loaders.push({  
    loader: loader + '-loader',
    options: Object.assign({}, loaderOptions, {
     sourceMap: options.sourceMap
    })
   })
  }
  // ExtractTextPlugin提取css(当上面的loaders未能正确引入时,使用vue-style-loader)
  if (options.extract) {// 生产环境中,默认为true
   return ExtractTextPlugin.extract({
    use: loaders,
    fallback: 'vue-style-loader'
   })
  } else {//返回vue-style-loader连接loaders的最终值
   return ['vue-style-loader'].concat(loaders)
  }
 }

 return {
  css: generateLoaders(),//需要css-loader 和 vue-style-loader
  postcss: generateLoaders(),//需要css-loader、postcssLoader 和 vue-style-loader
  less: generateLoaders('less'),//需要less-loader 和 vue-style-loader
  sass: generateLoaders('sass', { indentedSyntax: true }),//需要sass-loader 和 vue-style-loader
  scss: generateLoaders('sass'),//需要sass-loader 和 vue-style-loader
  stylus: generateLoaders('stylus'),//需要stylus-loader 和 vue-style-loader
  styl: generateLoaders('stylus')//需要stylus-loader 和 vue-style-loader
 }
}
 
/**@method styleLoaders 生成 style-loader的配置
 * @param {Object}   options 生成配置
 * @return {Array}   style-loader的配置
 */
exports.styleLoaders = function (options) {
 var output = []
 var loaders = exports.cssLoaders(options)
 //将各种css,less,sass等综合在一起得出结果输出output
 for (var extension in loaders) {
  var loader = loaders[extension]
  output.push({
   test: new RegExp('\\.' + extension + '$'),
   use: loader
  })
 }
 return output
}

(4)vue-loader.conf.js:处理.vue文件,解析这个文件中的每个语言块(template、script、style),转换成js可用的js模块。

'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
//生产环境,提取css样式到单独文件
const sourceMapEnabled = isProduction
 ? config.build.productionSourceMap
 : config.dev.cssSourceMap
module.exports = {
 loaders: utils.cssLoaders({
  sourceMap: sourceMapEnabled,
  extract: isProduction
 }),
 cssSourceMap: sourceMapEnabled,
 cacheBusting: config.dev.cacheBusting,
 //编译时将“引入路径”转换为require调用,使其可由webpack处理
 transformToRequire: {
  video: ['src', 'poster'],
  source: 'src',
  img: 'src',
  image: 'xlink:href'
 }
}

(5)webpack.base.conf.js:开发、测试、生产环境的公共基础配置文件,配置输出环境,配置模块resolve和插件等

'use strict'
const path = require('path')// node自带的文件路径工具
const utils = require('./utils')// 工具函数集合
const config = require('../config')// 配置文件
const vueLoaderConfig = require('./vue-loader.conf')// 工具函数集合
/**
 * 获取"绝对路径"
 * @method resolve
 * @param {String} dir 相对于本文件的路径
 * @return {String}   绝对路径
 */
function resolve(dir) {
 return path.join(__dirname, '..', dir)
}

module.exports = {
 context: path.resolve(__dirname, '../'),
 //入口js文件(默认为单页面所以只有app一个入口)
 entry: {
  app: './src/main.js'
 },
 //配置出口
 output: {
  path: config.build.assetsRoot,//打包编译的根路径(dist)
  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'),// eg:"src/components" => "@/components"
  }
 },
 module: {
  rules: [
   //使用vue-loader将vue文件编译转换为js
   {
    test: /\.vue$/,
    loader: 'vue-loader',
    options: vueLoaderConfig
   },
   //通过babel-loader将ES6编译压缩成ES5
   {
    test: /\.js$/,
    loader: 'babel-loader',
    include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
   },
   //使用url-loader处理(图片、音像、字体),超过10000编译成base64
   {
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    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]')
    }
   }
  ]
 },
 //nodeJs全局变量/模块,防止webpack注入一些nodeJs的东西到vue中
 node: {
  setImmediate: false,
  dgram: 'empty',
  fs: 'empty',
  net: 'empty',
  tls: 'empty',
  child_process: 'empty'
 }
}

(6)webpack.dev.conf.js:webpack配置开发环境中的入口

'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')//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')//webpack的提示错误和日志信息的插件
const portfinder = require('portfinder')// 查看空闲端口位置,默认情况下搜索8000这个端口

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 })
 },
 devtool: config.dev.devtool,//调试模式
 devServer: {
  clientLogLevel: 'warning',
  historyApiFallback: {//使用 HTML5 History API 时, 404 响应替代为 index.html
   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,//npm run dev 时自动打开浏览器
  overlay: config.dev.errorOverlay
   ? { warnings: false, errors: true }
   : false,// 显示warning 和 error 信息
  publicPath: config.dev.assetsPublicPath,
  proxy: config.dev.proxyTable,//api代理
  quiet: true, //控制台打印警告和错误(用FriendlyErrorsPlugin 为 true)
  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(),//webpack编译错误的时候,中断打包进程,防止错误代码打包到文件中
  // 将打包编译好的代码插入index.html
  new HtmlWebpackPlugin({
   filename: 'index.html',
   template: 'index.html',
   inject: true
  }),
  // 提取static assets 中css 复制到dist/static文件
  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 {
   //端口被占用时就重新设置evn和devServer的端口
   process.env.PORT = port
   devWebpackConfig.devServer.port = port
   // npm run dev成功的友情提示
   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)
  }
 })
})

(7)webpack.dev.prod.js:webpack配置生产环境中的入口

'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 UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const env = require('../config/prod.env')

const webpackConfig = merge(baseWebpackConfig, {
 module: {
  rules: utils.styleLoaders({
   sourceMap: config.build.productionSourceMap,
   extract: true,
   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 UglifyJsPlugin({//压缩js
   uglifyOptions: {
    compress: {
     warnings: false
    }
   },
   sourceMap: config.build.productionSourceMap,
   parallel: true
  }),
  new ExtractTextPlugin({//提取静态文件,减少请求
   filename: utils.assetsPath('css/[name].[contenthash].css'),
   allChunks: true,
  }),
  new OptimizeCSSPlugin({//提取优化压缩后(删除来自不同组件的冗余代码)的css
   cssProcessorOptions: config.build.productionSourceMap
    ? { safe: true, map: { inline: false } }
    : { safe: true }
  }),
  new HtmlWebpackPlugin({ //html打包压缩到index.html
   filename: config.build.index,
   template: 'index.html',
   inject: true,
   minify: {
    removeComments: true,//删除注释
    collapseWhitespace: true,//删除空格
    removeAttributeQuotes: true//删除属性的引号
   },
   chunksSortMode: 'dependency'//模块排序,按照我们需要的顺序排序
  }),

  new webpack.HashedModuleIdsPlugin(),
  new webpack.optimize.ModuleConcatenationPlugin(),
  new webpack.optimize.CommonsChunkPlugin({  // node_modules中的任何所需模块都提取到vendor
   name: 'vendor',
   minChunks (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([//复制static中的静态资源(默认到dist里面)
   {
    from: path.resolve(__dirname, '../static'),
    to: config.build.assetsSubDirectory,
    ignore: ['.*']
   }
  ])
 ]
})

if (config.build.productionGzip) {
 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,
   minRatio: 0.8
  })
 )
}

if (config.build.bundleAnalyzerReport) {
 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
 webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig

2、config文件夹:

config文件夹的结构:

Vue CLI 2.x搭建vue(目录最全分析)

(1) dev.env.js和prod.env.js:分别配置:开发环境和生产环境。这个可以根据公司业务结合后端需求配置需要区分开发环境和测试环境的属性

'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
 NODE_ENV: '"development"'
})

ps:webpack-merge用于实现合并类似于ES6的Object.assign()

'use strict'
module.exports = {
 NODE_ENV: '"production"'
}

(*注意属性值要用“‘'”双层引住),访问(获取值)时直接用:

process.env.属性名

ps:process(进程)是nodejs的一个全局变量,process.env 属性返回一个用户环境信息的对象

(2)index.js配置解析:

'use strict';
const path = require('path');

module.exports = {

 // ===================开发环境配置

 dev: {
  assetsSubDirectory: 'static',//静态资源文件夹(一般存放css、js、image等文件)
  assetsPublicPath: '/',//根目录
  proxyTable: {},//配置API代理,可利用该属性解决跨域的问题
  host: 'localhost', // 可以被 process.env.HOST 覆盖
  port: 3030, // 可以被 process.env.PORT 覆盖
  autoOpenBrowser: true,//编译后自动打开浏览器页面 http://localhost:3030/("port + host",默认"false"),设置路由重定向自动打开您的默认页面
  errorOverlay: true,//浏览器错误提示
  notifyOnErrors: true,//跨平台错误提示
  poll: false, //webpack提供的使用文件系统(file system)获取文件改动的通知devServer.watchOptions(监控文件改动)
  devtool: 'cheap-module-eval-source-map',//webpack提供的用来调试的模式,有多个不同值代表不同的调试模式
  cacheBusting: true,// 配合devtool的配置,当给文件名插入新的hash导致清除缓存时是否生成source-map
  cssSourceMap: true //记录代码压缩前的位置信息,当产生错误时直接定位到未压缩前的位置,方便调试
 },

// ========================生产环境配置

 build: {
  index: path.resolve(__dirname, '../dist/index.html'),//编译后"首页面"生成的绝对路径和名字
  assetsRoot: path.resolve(__dirname, '../dist'),//打包编译的根路径(默认dist,存放打包压缩后的代码)
  assetsSubDirectory: 'static',//静态资源文件夹(一般存放css、js、image等文件)
  assetsPublicPath: '/',//发布的根目录(dist文件夹所在路径)
  productionSourceMap: true,//是否开启source-map
  devtool: '#source-map',//(详细参见:https://webpack.docschina.org/configuration/devtool)
  productionGzip: false,//是否压缩
  productionGzipExtensions: ['js', 'css'],//unit的gzip命令用来压缩文件(gzip模式下需要压缩的文件的扩展名有js和css)
  bundleAnalyzerReport: process.env.npm_config_report //是否开启打包后的分析报告
 }
};

3、node_modules文件夹:

存放npm install时根据package.json配置生成的npm安装包的文件夹

4、src文件夹:

我们需要在src文件夹中开发代码,打包时webpack会根据build中的规则(build规则依赖于config中的配置)将src打包压缩到dist文件夹在浏览器中运行

(1)assets文件:用于存放静态资源(css、image),assets打包时路径会经过webpack中的file-loader编译(因此,assets需要使用绝对路径)成js

(2)components文件夹:用来存放 .vue 组件(实现复用等功能,如:过滤器,列表项等)

(3)router文件夹:在router/index.js文件中配置页面路由

(4)App.vue:是整个项目的主组件,所有页面都是通过使用<router-view/>开放入口在App.vue下进行切换的(所有的路由都是App.vue的子组件)

(5)main.js:入口js文件(全局js,你可以在这里:初始化vue实例、require/import需要的插件、注入router路由、引入store状态管理)

5、static文件夹:

webpack默认存放静态资源(css、image)的文件夹,与assets不同的是:static在打包时会直接复制一个同名文件夹到dist文件夹里(不会经过编译,可使用相对路径)

6、其他文件:

(1).babelrc:浏览器解析的兼容配置,该文件主要是对预设(presets)和插件(plugins)进行配置,因此不同的转译器作用不同的配置项,大致可分为:语法转义器、补丁转义器、sx和flow插件

(2).editorconfig:用于配置代码格式(配合代码检查工具使用,如:ESLint,团队开发时可统一代码风格),这里配置的代码规范规则优先级高于编辑器默认的代码格式化规则 。

3).gitignore:配置git提交时需要忽略的文件

(4)postcssrc.js: autoprefixer(自动补全css样式的浏览器前缀);postcss-import(@import引入语法)、CSS Modules(规定样式作用域)

(5)index.html:项目入口页面,编译之后所有代码将插入到这来

6)package.json:npm的配置文件(npm install根据package.json下载对应版本的安装包)

(7)package.lock.json:npm install(安装)时锁定各包的版本号

(8)README.md:项目使用说明

五、运行项目

在webStorm中打开项目,首先赶紧右击Project进行如下操作(否则会卡死,还有各种其他方法参见:

Vue CLI 2.x搭建vue(目录最全分析)

1、启动安装:cnpm install

Vue CLI 2.x搭建vue(目录最全分析)

2、然后npm run dev:跑起来~

Vue CLI 2.x搭建vue(目录最全分析)

3、生成打包文件 :npm run build 

然后你会发现项目多了个dist文件夹(用于部署到生产环境用,是打包压缩之后的src文件夹)

Vue CLI 2.x搭建vue(目录最全分析)

了解 vue cli 3 参见本人博客:https://3water.com/article/148100.htm

了解 node 、npm 安装/更新/使用,参见本人博客 :https://3water.com/article/157050.htm

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
代码生成器 document.write()
Apr 15 Javascript
EasySlider 基于jQuery功能强大简单易用的滑动门插件
Jun 11 Javascript
ExtJS PropertyGrid中使用Combobox选择值问题
Jun 13 Javascript
让你的博文自动带上缩址的实现代码,方便发到微博客上
Dec 28 Javascript
js随机生成网页背景颜色的方法
Feb 26 Javascript
JavaScript动态修改弹出窗口大小的方法
Apr 06 Javascript
JavaScript实现表格快速变色效果代码
Aug 19 Javascript
JS获取字符串实际长度(包含汉字)的简单方法
Aug 11 Javascript
AngularJs bootstrap详解及示例代码
Sep 01 Javascript
Vue 按键修饰符处理事件的方法
May 04 Javascript
使用electron制作满屏心特效的示例代码
Nov 27 Javascript
ES6数组与对象的解构赋值详解
Jun 14 Javascript
JavaScript中filter的用法实例分析
Feb 27 #Javascript
jQuery中each和js中forEach的区别分析
Feb 27 #jQuery
简单了解node npm cnpm的具体使用方法
Feb 27 #Javascript
js中对象与对象创建方法的各种方法
Feb 27 #Javascript
vue router带参数页面刷新或回退参数消失的解决方法
Feb 27 #Javascript
react的滑动图片验证码组件的示例代码
Feb 27 #Javascript
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
Feb 27 #jQuery
You might like
世界第一个无线广播电台 KDKA
2021/03/01 无线电
isset和empty的区别
2007/01/15 PHP
php 遍历数据表数据并列表横向排列的代码
2009/09/05 PHP
php5 图片验证码实现代码
2009/12/11 PHP
php配合jquery实现增删操作具体实例
2013/12/12 PHP
PHP使用标准库spl实现的观察者模式示例
2018/08/04 PHP
使用javascript获取flash加载的百分比的实现代码
2011/05/25 Javascript
基于json的jquery地区联动效果代码
2011/07/06 Javascript
CSS(js)限制页面显示的文本字符长度
2012/12/27 Javascript
js解析与序列化json数据(二)序列化探讨
2013/02/01 Javascript
提示$ is not defined错误分析及解决
2013/04/09 Javascript
解析javascript系统错误:-1072896658的解决办法
2013/07/08 Javascript
javascript break指定标签打破多层循环示例
2014/01/20 Javascript
javascript匿名函数应用示例介绍
2014/03/07 Javascript
JavaScript自学笔记(必看篇)
2016/06/23 Javascript
微信小程序 利用css实现遮罩效果实例详解
2017/01/21 Javascript
vue实现app页面切换动画效果实例
2017/05/23 Javascript
vue引入js数字小键盘的实现代码
2018/05/14 Javascript
angularjs的单选框+ng-repeat的实现方法
2018/09/12 Javascript
Python中使用HTMLParser解析html实例
2015/02/08 Python
python实现停车管理系统
2018/11/30 Python
Python图像滤波处理操作示例【基于ImageFilter类】
2019/01/03 Python
python傅里叶变换FFT绘制频谱图
2019/07/19 Python
Pytorch 实现自定义参数层的例子
2019/08/17 Python
使用 Python 遍历目录树的方法
2020/02/29 Python
基于python实现音乐播放器代码实例
2020/07/01 Python
如何解决pycharm调试报错的问题
2020/08/06 Python
python 如何利用argparse解析命令行参数
2020/09/11 Python
python实现sm2和sm4国密(国家商用密码)算法的示例
2020/09/26 Python
python中的对数log函数表示及用法
2020/12/09 Python
python实现图片转字符画
2021/02/19 Python
html5跨域通讯之postMessage的用法总结
2013/11/07 HTML / CSS
新手上路标语
2014/06/20 职场文书
2014国庆节餐厅促销活动策划方案
2014/09/16 职场文书
2014年人事科工作总结
2014/11/19 职场文书
检讨书范文2000字
2015/01/28 职场文书