├── .babelrc ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── README.md ├── VUE-CLI-README.md ├── build ├── build.js ├── check-versions.js ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── docs ├── index.html └── static │ ├── css │ └── app.21dd314e3c336b6e35618685db2fe00d.css │ └── js │ ├── app.a379f00e7957f3d6eeb0.js │ ├── manifest.3ad1d5771e9b13dbdad2.js │ └── vendor.90187d1f6e914c0da3c8.js ├── index.html ├── package-lock.json ├── package.json ├── src ├── App.vue ├── assets │ ├── highlight.pack.js │ └── logo.png ├── components │ ├── code-tab.vue │ ├── custom-checks.vue │ └── my-input.vue ├── main.js ├── my-validators │ └── validators.js └── vue-validate-easy │ ├── errTip.js │ ├── formElements.js │ ├── index.js │ ├── validate.js │ ├── validateAll.js │ └── validatorStore.js ├── static └── .gitkeep ├── t.js ├── test.html └── test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": { 9 | browsers: ['last 30 versions','Android >= 4.0'] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-validate-easy 2 | ## 这是一个简单易用易扩展的vue表单验证插件 3 | ## [文档 document](https://lfyfly.github.io/vue-validate-easy/) 4 | ## [github](https://github.com/lfyfly/vue-validate-easy) 5 | -------------------------------------------------------------------------------- /VUE-CLI-README.md: -------------------------------------------------------------------------------- 1 | # activity-frame-2018 2 | 3 | > A Vue.js project 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | exports.assetsPath = function (_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 9 | ? config.build.assetsSubDirectory 10 | : config.dev.assetsSubDirectory 11 | 12 | return path.posix.join(assetsSubDirectory, _path) 13 | } 14 | 15 | exports.cssLoaders = function (options) { 16 | options = options || {} 17 | 18 | const cssLoader = { 19 | loader: 'css-loader', 20 | options: { 21 | sourceMap: options.sourceMap 22 | } 23 | } 24 | 25 | const postcssLoader = { 26 | loader: 'postcss-loader', 27 | options: { 28 | sourceMap: options.sourceMap 29 | } 30 | } 31 | 32 | // generate loader string to be used with extract text plugin 33 | function generateLoaders (loader, loaderOptions) { 34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 35 | 36 | if (loader) { 37 | loaders.push({ 38 | loader: loader + '-loader', 39 | options: Object.assign({}, loaderOptions, { 40 | sourceMap: options.sourceMap 41 | }) 42 | }) 43 | } 44 | 45 | // Extract CSS when that option is specified 46 | // (which is the case during production build) 47 | if (options.extract) { 48 | return ExtractTextPlugin.extract({ 49 | use: loaders, 50 | fallback: 'vue-style-loader' 51 | }) 52 | } else { 53 | return ['vue-style-loader'].concat(loaders) 54 | } 55 | } 56 | 57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 58 | return { 59 | css: generateLoaders(), 60 | postcss: generateLoaders(), 61 | less: generateLoaders('less'), 62 | sass: generateLoaders('sass', { indentedSyntax: true }), 63 | scss: generateLoaders('sass'), 64 | stylus: generateLoaders('stylus'), 65 | styl: generateLoaders('stylus') 66 | } 67 | } 68 | 69 | // Generate loaders for standalone style files (outside of .vue) 70 | exports.styleLoaders = function (options) { 71 | const output = [] 72 | const loaders = exports.cssLoaders(options) 73 | 74 | for (const extension in loaders) { 75 | const loader = loaders[extension] 76 | output.push({ 77 | test: new RegExp('\\.' + extension + '$'), 78 | use: loader 79 | }) 80 | } 81 | 82 | return output 83 | } 84 | 85 | exports.createNotifierCallback = () => { 86 | const notifier = require('node-notifier') 87 | 88 | return (severity, errors) => { 89 | if (severity !== 'error') return 90 | 91 | const error = errors[0] 92 | const filename = error.file && error.file.split('!').pop() 93 | 94 | notifier.notify({ 95 | title: packageConfig.name, 96 | message: severity + ': ' + error.name, 97 | subtitle: filename || '', 98 | icon: path.join(__dirname, 'logo.png') 99 | }) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | 12 | 13 | module.exports = { 14 | context: path.resolve(__dirname, '../'), 15 | entry: { 16 | app: './src/main.js' 17 | }, 18 | output: { 19 | path: config.build.assetsRoot, 20 | filename: '[name].js', 21 | publicPath: process.env.NODE_ENV === 'production' 22 | ? config.build.assetsPublicPath 23 | : config.dev.assetsPublicPath 24 | }, 25 | resolve: { 26 | extensions: ['.js', '.vue', '.json'], 27 | alias: { 28 | 'vue$': 'vue/dist/vue.esm.js', 29 | '@': resolve('src'), 30 | } 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /\.vue$/, 36 | loader: 'vue-loader', 37 | options: vueLoaderConfig 38 | }, 39 | { 40 | test: /\.js$/, 41 | loader: 'babel-loader', 42 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 43 | }, 44 | { 45 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 46 | loader: 'url-loader', 47 | options: { 48 | limit: 10000, 49 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 50 | } 51 | }, 52 | { 53 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 54 | loader: 'url-loader', 55 | options: { 56 | limit: 10000, 57 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 58 | } 59 | }, 60 | { 61 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 62 | loader: 'url-loader', 63 | options: { 64 | limit: 10000, 65 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 66 | } 67 | } 68 | ] 69 | }, 70 | node: { 71 | // prevent webpack from injecting useless setImmediate polyfill because Vue 72 | // source contains it (although only uses it if it's native). 73 | setImmediate: false, 74 | // prevent webpack from injecting mocks to Node native modules 75 | // that does not make sense for the client 76 | dgram: 'empty', 77 | fs: 'empty', 78 | net: 'empty', 79 | tls: 'empty', 80 | child_process: 'empty' 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const path = require('path') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 11 | const portfinder = require('portfinder') 12 | 13 | const HOST = process.env.HOST 14 | const PORT = process.env.PORT && Number(process.env.PORT) 15 | 16 | const devWebpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 19 | }, 20 | // cheap-module-eval-source-map is faster for development 21 | devtool: config.dev.devtool, 22 | 23 | // these devServer options should be customized in /config/index.js 24 | devServer: { 25 | clientLogLevel: 'warning', 26 | historyApiFallback: { 27 | rewrites: [ 28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, 29 | ], 30 | }, 31 | hot: true, 32 | contentBase: false, // since we use CopyWebpackPlugin. 33 | compress: true, 34 | host: HOST || config.dev.host, 35 | port: PORT || config.dev.port, 36 | open: config.dev.autoOpenBrowser, 37 | overlay: config.dev.errorOverlay 38 | ? { warnings: false, errors: true } 39 | : false, 40 | publicPath: config.dev.assetsPublicPath, 41 | proxy: config.dev.proxyTable, 42 | quiet: true, // necessary for FriendlyErrorsPlugin 43 | watchOptions: { 44 | poll: config.dev.poll, 45 | } 46 | }, 47 | plugins: [ 48 | new webpack.DefinePlugin({ 49 | 'process.env': require('../config/dev.env') 50 | }), 51 | new webpack.HotModuleReplacementPlugin(), 52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 53 | new webpack.NoEmitOnErrorsPlugin(), 54 | // https://github.com/ampedandwired/html-webpack-plugin 55 | new HtmlWebpackPlugin({ 56 | filename: 'index.html', 57 | template: 'index.html', 58 | inject: true 59 | }), 60 | // copy custom static assets 61 | new CopyWebpackPlugin([ 62 | { 63 | from: path.resolve(__dirname, '../static'), 64 | to: config.dev.assetsSubDirectory, 65 | ignore: ['.*'] 66 | } 67 | ]) 68 | ] 69 | }) 70 | 71 | module.exports = new Promise((resolve, reject) => { 72 | portfinder.basePort = process.env.PORT || config.dev.port 73 | portfinder.getPort((err, port) => { 74 | if (err) { 75 | reject(err) 76 | } else { 77 | // publish the new Port, necessary for e2e tests 78 | process.env.PORT = port 79 | // add port to devServer config 80 | devWebpackConfig.devServer.port = port 81 | 82 | // Add FriendlyErrorsPlugin 83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 84 | compilationSuccessInfo: { 85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 86 | }, 87 | onErrors: config.dev.notifyOnErrors 88 | ? utils.createNotifierCallback() 89 | : undefined 90 | })) 91 | 92 | resolve(devWebpackConfig) 93 | } 94 | }) 95 | }) 96 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 13 | 14 | const env = require('../config/prod.env') 15 | 16 | const webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true, 21 | usePostCSS: true 22 | }) 23 | }, 24 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 25 | output: { 26 | path: config.build.assetsRoot, 27 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 29 | }, 30 | plugins: [ 31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 32 | new webpack.DefinePlugin({ 33 | 'process.env': env 34 | }), 35 | new UglifyJsPlugin({ 36 | uglifyOptions: { 37 | compress: { 38 | warnings: false 39 | } 40 | }, 41 | sourceMap: config.build.productionSourceMap, 42 | parallel: true 43 | }), 44 | // extract css into its own file 45 | new ExtractTextPlugin({ 46 | filename: utils.assetsPath('css/[name].[contenthash].css'), 47 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 51 | allChunks: true, 52 | }), 53 | // Compress extracted CSS. We are using this plugin so that possible 54 | // duplicated CSS from different components can be deduped. 55 | new OptimizeCSSPlugin({ 56 | cssProcessorOptions: config.build.productionSourceMap 57 | ? { safe: true, map: { inline: false } } 58 | : { safe: true } 59 | }), 60 | // generate dist index.html with correct asset hash for caching. 61 | // you can customize output by editing /index.html 62 | // see https://github.com/ampedandwired/html-webpack-plugin 63 | new HtmlWebpackPlugin({ 64 | filename: config.build.index, 65 | template: 'index.html', 66 | inject: true, 67 | minify: { 68 | removeComments: true, 69 | collapseWhitespace: true, 70 | removeAttributeQuotes: true 71 | // more options: 72 | // https://github.com/kangax/html-minifier#options-quick-reference 73 | }, 74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 75 | chunksSortMode: 'dependency' 76 | }), 77 | // keep module.id stable when vendor modules does not change 78 | new webpack.HashedModuleIdsPlugin(), 79 | // enable scope hoisting 80 | new webpack.optimize.ModuleConcatenationPlugin(), 81 | // split vendor js into its own file 82 | new webpack.optimize.CommonsChunkPlugin({ 83 | name: 'vendor', 84 | minChunks (module) { 85 | // any required modules inside node_modules are extracted to vendor 86 | return ( 87 | module.resource && 88 | /\.js$/.test(module.resource) && 89 | module.resource.indexOf( 90 | path.join(__dirname, '../node_modules') 91 | ) === 0 92 | ) 93 | } 94 | }), 95 | // extract webpack runtime and module manifest to its own file in order to 96 | // prevent vendor hash from being updated whenever app bundle is updated 97 | new webpack.optimize.CommonsChunkPlugin({ 98 | name: 'manifest', 99 | minChunks: Infinity 100 | }), 101 | // This instance extracts shared chunks from code splitted chunks and bundles them 102 | // in a separate chunk, similar to the vendor chunk 103 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 104 | new webpack.optimize.CommonsChunkPlugin({ 105 | name: 'app', 106 | async: 'vendor-async', 107 | children: true, 108 | minChunks: 3 109 | }), 110 | 111 | // copy custom static assets 112 | new CopyWebpackPlugin([ 113 | { 114 | from: path.resolve(__dirname, '../static'), 115 | to: config.build.assetsSubDirectory, 116 | ignore: ['.*'] 117 | } 118 | ]) 119 | ] 120 | }) 121 | 122 | if (config.build.productionGzip) { 123 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 124 | 125 | webpackConfig.plugins.push( 126 | new CompressionWebpackPlugin({ 127 | asset: '[path].gz[query]', 128 | algorithm: 'gzip', 129 | test: new RegExp( 130 | '\\.(' + 131 | config.build.productionGzipExtensions.join('|') + 132 | ')$' 133 | ), 134 | threshold: 10240, 135 | minRatio: 0.8 136 | }) 137 | ) 138 | } 139 | 140 | if (config.build.bundleAnalyzerReport) { 141 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 143 | } 144 | 145 | module.exports = webpackConfig 146 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.3.1 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: { 14 | '/remote': { 15 | target: 'http://localhost:3000', 16 | pathRewrite: { 17 | // 地址重写 18 | '^/remote': '/remote' 19 | } 20 | } 21 | }, 22 | 23 | // Various Dev Server settings 24 | host: 'localhost', // can be overwritten by process.env.HOST 25 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 26 | autoOpenBrowser: false, 27 | errorOverlay: true, 28 | notifyOnErrors: true, 29 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 30 | 31 | 32 | /** 33 | * Source Maps 34 | */ 35 | 36 | // https://webpack.js.org/configuration/devtool/#development 37 | devtool: 'cheap-module-eval-source-map', 38 | 39 | // If you have problems debugging vue-files in devtools, 40 | // set this to false - it *may* help 41 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 42 | cacheBusting: true, 43 | 44 | cssSourceMap: true 45 | }, 46 | 47 | build: { 48 | // Template for index.html 49 | index: path.resolve(__dirname, '../docs/index.html'), 50 | 51 | // Paths 52 | assetsRoot: path.resolve(__dirname, '../docs'), 53 | assetsSubDirectory: 'static', 54 | assetsPublicPath: './', 55 | 56 | /** 57 | * Source Maps 58 | */ 59 | 60 | productionSourceMap: false, 61 | // https://webpack.js.org/configuration/devtool/#production 62 | devtool: '#source-map', 63 | 64 | // Gzip off by default as many popular static hosts such as 65 | // Surge or Netlify already gzip all static assets for you. 66 | // Before setting to `true`, make sure to: 67 | // npm install --save-dev compression-webpack-plugin 68 | productionGzip: false, 69 | productionGzipExtensions: ['js', 'css'], 70 | 71 | // Run the build command with an extra argument to 72 | // View the bundle analyzer report after build finishes: 73 | // `npm run build --report` 74 | // Set to `true` or `false` to always turn it on or off 75 | bundleAnalyzerReport: process.env.npm_config_report 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | vue-validate-easy
-------------------------------------------------------------------------------- /docs/static/css/app.21dd314e3c336b6e35618685db2fe00d.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";.fade-enter-active,.fade-leave-active{transition:opacity .5s}.fade-enter,.fade-leave-to{opacity:0}a{-webkit-tap-highlight-color:rgba(255,255,255,0)}#app,body,html{height:100%;margin:0}#app.is-mobile #main>*{max-width:auto;min-width:auto}#app.is-mobile #catalog{position:fixed!important;width:100%;z-index:2}#app.is-mobile #catalog .close{position:fixed;top:-4px;right:0;width:40px;height:40px;font-size:30px;line-height:40px;z-index:1;text-align:right}#app.is-mobile #catalog .close:after{content:"\D7";color:rgba(0,0,0,.5);font-size:50px;font-weight:300}#app{box-sizing:border-box;font-family:Microsoft YaHei,黑体,verdana,sans-serif}#app a{color:#24292e}#app #main>*{max-width:1000px;min-width:600px}#app #main{padding:20px}#app #main ul{padding-left:0}#app #main #catalog-btn{position:fixed;right:0;z-index:1;top:10px;right:3px;width:30px;background:#ccc;border-top:3px solid rgba(0,0,0,.5);border-bottom:3px solid rgba(0,0,0,.5);background:rgba(0,0,0,.5);padding:5px 0;box-sizing:content-box;height:3px;background-clip:content-box}#app #catalog{float:left}#app>*{overflow:auto;height:100%;box-sizing:border-box}#app #catalog{padding:0 20px 20px;background:hsla(0,0%,100%,.9);box-shadow:0 1px 2px rgba(0,0,0,.3);line-height:1.6}#app #catalog a{color:#551a8b;display:block;text-decoration:none}#app #catalog a:hover{text-decoration:underline}#app #catalog a:active{color:#551a8b}#app #catalog a.h1{margin-top:10px;font-weight:700}#app #catalog a.h3{font-size:12px;padding-left:20px}#app form{box-shadow:0 1px 2px rgba(0,0,0,.3);border-radius:4px;padding:10px;margin-top:20px;margin-bottom:20px}#app button,#app input,#app select{outline:none}#app option,#app select{font-size:16px}#app select{min-height:24px}#app .btn-group{margin-bottom:10px}#app .btn-group>*{margin-right:10px}#app .my-btn{line-height:24px;background:#fff;border:1px solid #919191;border-radius:4px;transition:background .5s}#app .my-btn:hover{background:#f3f3f3;cursor:pointer}#app .my-form-group{margin-bottom:20px}#app .my-form-group .label{font-weight:700;margin-bottom:2px}#app .my-form-group input.input{height:30px;width:100%;outline:none;box-sizing:border-box;padding-left:6px;border:1px solid #919191;border-radius:4px}#app .my-form-group label.checkbox,#app .my-form-group label.radio{margin-right:10px}#app .my-form-group label.checkbox input,#app .my-form-group label.radio input{margin-right:4px}#app .my-form-group input::-webkit-input-placeholder{color:#ccc}#app .my-form-group input:-moz-placeholder,#app .my-form-group input::-moz-placeholder{color:#ccc}#app .my-form-group input:-ms-input-placeholder{color:#ccc}#app .err__ input.input{border:1px solid red}#app .succ__ input.input{border:1px solid green}#app .err__msg{color:red;display:block;font-size:14px}.my-input{margin:20px 0}.my-input input{height:36px;border:1px solid #919191;padding:0 16px;border-radius:18px;width:300px}.my-input .label{margin-left:16px;margin-bottom:2px;font-weight:700}.my-input.err__ input{border:1px solid red}.my-input.succ__ input{border:1px solid green}.my-input .err__msg{color:red;font-size:14px;margin-left:10px}.code-tab li{list-style:none}.code-tab li,.code-tab ul{margin:0;padding:0}.code-tab .nav>*{display:inline-block;padding:4px 10px;border-bottom:2px solid transparent;cursor:pointer;transition:border-color .3s,color .3s}.code-tab .nav>.active{border-color:green;color:green}.custom-checks{overflow:hidden}.custom-checks .check-item{margin:10px;padding-left:10px;cursor:pointer;border:1px solid transparent}.custom-checks .check-item.checked{border-radius:4px;border:1px solid green}.hljs{display:block;overflow-x:auto;padding:.5em;background:#fff;color:#000}.hljs-comment,.hljs-quote{color:#006a00}.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#aa0d91}.hljs-name{color:#008}.hljs-template-variable,.hljs-variable{color:#660}.hljs-string{color:#c41a16}.hljs-link,.hljs-regexp{color:#080}.hljs-bullet,.hljs-meta,.hljs-number,.hljs-symbol,.hljs-tag,.hljs-title{color:#1c00cf}.hljs-attr,.hljs-built_in,.hljs-builtin-name,.hljs-class .hljs-title,.hljs-params,.hljs-section,.hljs-type{color:#5c2699}.hljs-attribute,.hljs-subst{color:#000}.hljs-formula{background-color:#eee;font-style:italic}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-selector-class,.hljs-selector-id{color:#9b703f}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic}@font-face{font-family:octicons-link;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format("woff")}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#24292e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body .pl-c{color:#6a737d}.markdown-body .pl-c1,.markdown-body .pl-s .pl-v{color:#005cc5}.markdown-body .pl-e,.markdown-body .pl-en{color:#6f42c1}.markdown-body .pl-s .pl-s1,.markdown-body .pl-smi{color:#24292e}.markdown-body .pl-ent{color:#22863a}.markdown-body .pl-k{color:#d73a49}.markdown-body .pl-pds,.markdown-body .pl-s,.markdown-body .pl-s .pl-pse .pl-s1,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre{color:#032f62}.markdown-body .pl-smw,.markdown-body .pl-v{color:#e36209}.markdown-body .pl-bu{color:#b31d28}.markdown-body .pl-ii{color:#fafbfc;background-color:#b31d28}.markdown-body .pl-c2{color:#fafbfc;background-color:#d73a49}.markdown-body .pl-c2:before{content:"^M"}.markdown-body .pl-sr .pl-cce{font-weight:700;color:#22863a}.markdown-body .pl-ml{color:#735c0f}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{font-weight:700;color:#005cc5}.markdown-body .pl-mi{font-style:italic;color:#24292e}.markdown-body .pl-mb{font-weight:700;color:#24292e}.markdown-body .pl-md{color:#b31d28;background-color:#ffeef0}.markdown-body .pl-mi1{color:#22863a;background-color:#f0fff4}.markdown-body .pl-mc{color:#e36209;background-color:#ffebda}.markdown-body .pl-mi2{color:#f6f8fa;background-color:#005cc5}.markdown-body .pl-mdr{font-weight:700;color:#6f42c1}.markdown-body .pl-ba{color:#586069}.markdown-body .pl-sg{color:#959da5}.markdown-body .pl-corl{text-decoration:underline;color:#032f62}.markdown-body .octicon{display:inline-block;vertical-align:text-top;fill:currentColor}.markdown-body a{background-color:transparent}.markdown-body a:active,.markdown-body a:hover{outline-width:0}.markdown-body strong{font-weight:inherit;font-weight:bolder}.markdown-body h1{margin:.67em 0}.markdown-body img{border-style:none}.markdown-body code,.markdown-body kbd,.markdown-body pre{font-family:monospace,monospace;font-size:1em}.markdown-body hr{box-sizing:content-box;overflow:visible}.markdown-body input{font:inherit;margin:0;overflow:visible}.markdown-body [type=checkbox]{box-sizing:border-box;padding:0}.markdown-body *{box-sizing:border-box}.markdown-body input{font-family:inherit;font-size:inherit;line-height:inherit}.markdown-body a{color:#0366d6;text-decoration:none}.markdown-body a:hover{text-decoration:underline}.markdown-body strong{font-weight:600}.markdown-body hr{height:0;margin:15px 0;overflow:hidden;background:transparent;border-bottom:1px solid #dfe2e5}.markdown-body hr:after,.markdown-body hr:before{display:table;content:""}.markdown-body hr:after{clear:both}.markdown-body table{border-spacing:0;border-collapse:collapse}.markdown-body td,.markdown-body th{padding:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:0;margin-bottom:0}.markdown-body h1{font-size:32px;font-weight:600}.markdown-body h2{font-size:24px;font-weight:600}.markdown-body h3{font-size:20px;font-weight:600}.markdown-body h4{font-size:16px;font-weight:600}.markdown-body h5{font-size:14px;font-weight:600}.markdown-body h6{font-size:12px;font-weight:600}.markdown-body p{margin-top:0;margin-bottom:10px}.markdown-body blockquote{margin:0}.markdown-body ol,.markdown-body ul{padding-left:0;margin-top:0;margin-bottom:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code,.markdown-body pre{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0}.markdown-body .octicon{vertical-align:text-bottom}.markdown-body .pl-0{padding-left:0!important}.markdown-body .pl-1{padding-left:4px!important}.markdown-body .pl-2{padding-left:8px!important}.markdown-body .pl-3{padding-left:16px!important}.markdown-body .pl-4{padding-left:24px!important}.markdown-body .pl-5{padding-left:32px!important}.markdown-body .pl-6{padding-left:40px!important}.markdown-body:after,.markdown-body:before{display:table;content:""}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1}.markdown-body .anchor:focus{outline:none}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body hr{height:.25em;padding:0;margin:24px 0;background-color:#e1e4e8;border:0}.markdown-body blockquote{padding:0 1em;color:#6a737d;border-left:.25em solid #dfe2e5}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd{font-size:11px;border:1px solid #c6cbd1;border-bottom-color:#959da5;box-shadow:inset 0 -1px 0 #959da5}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:24px;margin-bottom:16px;font-weight:600;line-height:1.25}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1{font-size:2em}.markdown-body h1,.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid #eaecef}.markdown-body h2{font-size:1.5em}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h6{font-size:.85em;color:#6a737d}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li{word-wrap:break-all}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:600}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body table{display:block;width:100%;overflow:auto}.markdown-body table th{font-weight:600}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #dfe2e5}.markdown-body table tr{background-color:#fff;border-top:1px solid #c6cbd1}.markdown-body table tr:nth-child(2n){background-color:#f6f8fa}.markdown-body img{max-width:100%;box-sizing:content-box;background-color:#fff}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body code{padding:.2em .4em;margin:0;font-size:85%;background-color:rgba(27,31,35,.05);border-radius:3px}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:transparent;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f6f8fa;border-radius:3px}.markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body .full-commit .btn-outline:not(:disabled):hover{color:#005cc5;border-color:#005cc5}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px 0 #c6cbd1}.markdown-body :checked+.radio-label{position:relative;z-index:1;border-color:#0366d6}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{margin:0 .2em .25em -1.6em;vertical-align:middle}.markdown-body hr{border-bottom-color:#eee} -------------------------------------------------------------------------------- /docs/static/js/app.a379f00e7957f3d6eeb0.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([1],{ETNL:function(e,t){},NHnr:function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=a("ju79"),r=a.n(n),s=a("7+uW"),i=a("Xxa5"),l=a.n(i),c=a("exGp"),o=a.n(c),u=a("mvHQ"),d=a.n(u),v=a("mtWM"),p=a.n(v),m={render:function(){var e=this.$createElement,t=this._self._c||e;return t("div",{staticClass:"my-input",attrs:{"data-type":"input"}},[t("label",[t("div",{staticClass:"label"},[this._v(this._s(this.label))]),t("div",[t("input",{attrs:{placeholder:this.placeholder,spellcheck:"false",type:this.type},domProps:{value:this.value}})])])])},staticRenderFns:[]};var b=a("VU/8")({name:"my-input",props:["value","label","placeholder","type"],data:function(){return{msg:"this is from my-input.vue"}}},m,!1,function(e){a("mTPd")},null,null).exports,_={name:"code-tab",props:["nav"],data:function(){return{msg:"this is from code-tab.vue",activeIndex:0}},methods:{test:function(e){alert(e)}}},h={render:function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticClass:"code-tab"},[a("ul",{staticClass:"nav"},e._l(e.nav,function(t,n){return a("li",{staticClass:"nav-item",class:{active:n==e.activeIndex},on:{click:function(t){e.activeIndex=n}}},[e._v(e._s(t.text?t.text:t.name))])})),a("div",{staticClass:"content"},e._l(e.nav,function(t,n){return a("div",{directives:[{name:"show",rawName:"v-show",value:n==e.activeIndex,expression:"i==activeIndex"}],staticClass:"content-item"},[e._t(t.name)],2)}))])},staticRenderFns:[]};var f=a("VU/8")(_,h,!1,function(e){a("hSb9")},null,null).exports,y={name:"custom-checks",props:{data:{type:Array,default:[{text:"text",value:"value"}]},scope:String,name:String,question:String},data:function(){return{msg:"this is from custom-checks.vue",innerData:this.data.map(function(e){return e.checked=!1,e})}},computed:{value:function(){var e=[];return this.innerData.forEach(function(t){t.checked&&e.push(t.value?t.value:t.text)}),e}},methods:{checkFn:function(e,t){this.innerData[t].checked=!this.innerData[t].checked,this.$el.value=this.value},bindEvent:function(e){var t=this;this.$el.onclick=function(){e(t.$el,t.$el.value)}},reset:function(){this.$el.value=[],this.innerData=this.data.map(function(e){return e.checked=!1,e})},getValue:function(){return this.$el.value}},mounted:function(){this.$el.bindEvent=this.bindEvent,this.$el.reset=this.reset,this.$el.getValue=this.getValue}},g={render:function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticClass:"custom-checks",attrs:{"data-type":"custom"}},[a("h4",{staticClass:"question"},[e._v(e._s(e.question))]),a("div",{staticClass:"checks-container"},e._l(e.innerData,function(t,n){return a("div",{staticClass:"check-item",class:{checked:t.checked},on:{click:function(t){e.checkFn(t,n)}}},[e._v(e._s(t.text))])}))])},staticRenderFns:[]};var x,C,k=a("VU/8")(y,g,!1,function(e){a("Q89W")},null,null).exports,w=a("fZjL"),N=a.n(w),E=a("OvRC"),q=a.n(E),$=a("pFYg"),S=a.n($);x=function(e){function t(e){return e.replace(/&/g,"&").replace(//g,">")}function a(e){return e.nodeName.toLowerCase()}function n(e,t){var a=e&&e.exec(t);return a&&0===a.index}function r(e){return g.test(e)}function s(e){var t,a={},n=Array.prototype.slice.call(arguments,1);for(t in e)a[t]=e[t];return n.forEach(function(e){for(t in e)a[t]=e[t]}),a}function i(e){var t=[];return function e(n,r){for(var s=n.firstChild;s;s=s.nextSibling)3===s.nodeType?r+=s.nodeValue.length:1===s.nodeType&&(t.push({event:"start",offset:r,node:s}),r=e(s,r),a(s).match(/br|hr|img|input/)||t.push({event:"stop",offset:r,node:s}));return r}(e,0),t}function l(e,n,r){function s(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function l(e){u+=""}function c(e){("start"===e.event?i:l)(e.node)}for(var o=0,u="",d=[];e.length||n.length;){var v=s();if(u+=t(r.substring(o,v[0].offset)),o=v[0].offset,v===e){d.reverse().forEach(l);do{c(v.splice(0,1)[0]),v=s()}while(v===e&&v.length&&v[0].offset===o);d.reverse().forEach(i)}else"start"===v[0].event?d.push(v[0].node):d.pop(),c(v.splice(0,1)[0])}return u+t(r.substr(o))}function c(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(t){return s(e,{v:null},t)})),e.cached_variants||e.eW&&[s(e)]||[e]}function o(e){function t(e){return e&&e.source||e}function a(a,n){return new RegExp(t(a),"m"+(e.cI?"i":"")+(n?"g":""))}!function n(r,s){if(!r.compiled){if(r.compiled=!0,r.k=r.k||r.bK,r.k){var i={},l=function(t,a){e.cI&&(a=a.toLowerCase()),a.split(" ").forEach(function(e){var a=e.split("|");i[a[0]]=[t,a[1]?Number(a[1]):1]})};"string"==typeof r.k?l("keyword",r.k):h(r.k).forEach(function(e){l(e,r.k[e])}),r.k=i}r.lR=a(r.l||/\w+/,!0),s&&(r.bK&&(r.b="\\b("+r.bK.split(" ").join("|")+")\\b"),r.b||(r.b=/\B|\b/),r.bR=a(r.b),r.e||r.eW||(r.e=/\B|\b/),r.e&&(r.eR=a(r.e)),r.tE=t(r.e)||"",r.eW&&s.tE&&(r.tE+=(r.e?"|":"")+s.tE)),r.i&&(r.iR=a(r.i)),null==r.r&&(r.r=1),r.c||(r.c=[]),r.c=Array.prototype.concat.apply([],r.c.map(function(e){return c("self"===e?r:e)})),r.c.forEach(function(e){n(e,r)}),r.starts&&n(r.starts,s);var o=r.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([r.tE,r.i]).map(t).filter(Boolean);r.t=o.length?a(o.join("|"),!0):{exec:function(){return null}}}}(e)}function u(e,a,r,s){function i(e,t){var a,r;for(a=0,r=t.c.length;r>a;a++)if(n(t.c[a].bR,e))return t.c[a]}function l(e,t){if(n(e.eR,t)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?l(e.parent,t):void 0}function c(e,t){return!r&&n(t.iR,e)}function v(e,t){var a=y.cI?t[0].toLowerCase():t[0];return e.k.hasOwnProperty(a)&&e.k[a]}function p(e,t,a,n){var r='')+t+(a?"":k)}function m(){N+=null!=x.sL?function(){var e="string"==typeof x.sL;if(e&&!f[x.sL])return t(E);var a=e?u(x.sL,E,!0,C[x.sL]):d(E,x.sL.length?x.sL:void 0);return x.r>0&&($+=a.r),e&&(C[x.sL]=a.top),p(a.language,a.value,!1,!0)}():function(){var e,a,n,r;if(!x.k)return t(E);for(r="",a=0,x.lR.lastIndex=0,n=x.lR.exec(E);n;)r+=t(E.substring(a,n.index)),(e=v(x,n))?($+=e[1],r+=p(e[0],t(n[0]))):r+=t(n[0]),a=x.lR.lastIndex,n=x.lR.exec(E);return r+t(E.substr(a))}(),E=""}function _(e){N+=e.cN?p(e.cN,"",!0):"",x=q()(e,{parent:{value:x}})}function h(e,t){if(E+=e,null==t)return m(),0;var a=i(t,x);if(a)return a.skip?E+=t:(a.eB&&(E+=t),m(),a.rB||a.eB||(E=t)),_(a),a.rB?0:t.length;var n=l(x,t);if(n){var r=x;r.skip?E+=t:(r.rE||r.eE||(E+=t),m(),r.eE&&(E=t));do{x.cN&&(N+=k),x.skip||($+=x.r),x=x.parent}while(x!==n.parent);return n.starts&&_(n.starts),r.rE?0:t.length}if(c(t,x))throw new Error('Illegal lexeme "'+t+'" for mode "'+(x.cN||"")+'"');return E+=t,t.length||1}var y=b(e);if(!y)throw new Error('Unknown language: "'+e+'"');o(y);var g,x=s||y,C={},N="";for(g=x;g!==y;g=g.parent)g.cN&&(N=p(g.cN,"",!0)+N);var E="",$=0;try{for(var S,V,A=0;x.t.lastIndex=A,S=x.t.exec(a);)V=h(a.substring(A,S.index),S[0]),A=S.index+V;for(h(a.substr(A)),g=x;g.parent;g=g.parent)g.cN&&(N+=k);return{r:$,value:N,language:e,top:x}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{r:0,value:t(a)};throw e}}function d(e,a){a=a||w.languages||h(f);var n={r:0,value:t(e)},r=n;return a.filter(b).forEach(function(t){var a=u(t,e,!1);a.language=t,a.r>r.r&&(r=a),a.r>n.r&&(r=n,n=a)}),r.language&&(n.second_best=r),n}function v(e){return w.tabReplace||w.useBR?e.replace(C,function(e,t){return w.useBR&&"\n"===e?"
":w.tabReplace?t.replace(/\t/g,w.tabReplace):""}):e}function p(e){var t,a,n,s,c,o=function(e){var t,a,n,s,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",a=x.exec(i))return b(a[1])?a[1]:"no-highlight";for(t=0,n=(i=i.split(/\s+/)).length;n>t;t++)if(r(s=i[t])||b(s))return s}(e);r(o)||(w.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"):t=e,c=t.textContent,n=o?u(o,c,!0):d(c),(a=i(t)).length&&((s=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=n.value,n.value=l(a,i(s),c)),n.value=v(n.value),e.innerHTML=n.value,e.className=function(e,t,a){var n=t?y[t]:a,r=[e.trim()];return e.match(/\bhljs\b/)||r.push("hljs"),-1===e.indexOf(n)&&r.push(n),r.join(" ").trim()}(e.className,o,n.language),e.result={language:n.language,re:n.r},n.second_best&&(e.second_best={language:n.second_best.language,re:n.second_best.r}))}function m(){if(!m.called){m.called=!0;var e=document.querySelectorAll("pre code");_.forEach.call(e,p)}}function b(e){return e=(e||"").toLowerCase(),f[e]||f[y[e]]}var _=[],h=N.a,f={},y={},g=/^(no-?highlight|plain|text)$/i,x=/\blang(?:uage)?-([\w-]+)\b/i,C=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,k="
",w={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=u,e.highlightAuto=d,e.fixMarkup=v,e.highlightBlock=p,e.configure=function(e){w=s(w,e)},e.initHighlighting=m,e.initHighlightingOnLoad=function(){addEventListener("DOMContentLoaded",m,!1),addEventListener("load",m,!1)},e.registerLanguage=function(t,a){var n=f[t]=a(e);n.aliases&&n.aliases.forEach(function(e){y[e]=t})},e.listLanguages=function(){return h(f)},e.getLanguage=b,e.inherit=s,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(t,a,n){var r=e.inherit({cN:"comment",b:t,e:a,c:[]},n||{});return r.c.push(e.PWM),r.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),r},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e},C="object"==("undefined"==typeof window?"undefined":S()(window))&&window||"object"==("undefined"==typeof self?"undefined":S()(self))&&self,"undefined"!=typeof exports?x(exports):C&&(C.hljs=x({}),"function"==typeof define&&a("nErl")&&define([],function(){return C.hljs})),hljs.registerLanguage("css",function(e){var t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:"[a-zA-Z-][a-zA-Z0-9_-]*",r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}}),hljs.registerLanguage("javascript",function(e){var t="[A-Za-z$_][0-9A-Za-z$_]*",a={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},n={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},r={cN:"subst",b:"\\$\\{",e:"\\}",k:a,c:[]},s={cN:"string",b:"`",e:"`",c:[e.BE,r]};r.c=[e.ASM,e.QSM,s,n,e.RM];var i=r.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:a,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,s,e.CLCM,e.CBCM,n,{b:/[{,]\s*/,r:0,c:[{b:t+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:t,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+t+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:t},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:a,c:i}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:t}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:i}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}}),hljs.registerLanguage("xml",function(e){var t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},e.C("\x3c!--","--\x3e",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"<\/script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}}),hljs.registerLanguage("json",function(e){var t={literal:"true false null"},a=[e.QSM,e.CNM],n={e:",",eW:!0,eE:!0,c:a,k:t},r={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(n,{b:/:/})],i:"\\S"},s={b:"\\[",e:"\\]",c:[e.inherit(n)],i:"\\S"};return a.splice(a.length,0,r,s),{c:a,k:t,i:"\\S"}});a("b+CC"),a("ETNL");var V=navigator.userAgent.match(/(iPhone|iPod|ipad|Android|ios)/i),A={name:"app",components:{myInput:b,codeTab:f,customChecks:k},data:function(){return{msg:"this is from app.vue",catalogShow:!V,isMobile:V}},methods:{clickCatalog:function(){this.isMobile&&(this.catalogShow=!1)},test:function(e){console.log("test: "+e)},validatorAll:function(e){this.V.$validateAll(e)},validateLoginUsername:function(){this.V.$validateSingle(document.querySelector("#loginUsername"))},resetLoginUsername:function(){this.V.$resetSingle(document.querySelector("#loginUsername"))},reset:function(e){this.V.$reset(e)},submit:function(e){this.V.$submit(e,function(e,t,a){e&&(alert("验证通过,数据如下\n"+d()(t)),p()({url:"/test",data:t,method:"post"}).then(function(){}).catch(function(){}))})},createTitle:function(e,t){for(var a=document.querySelectorAll(e),n=0;n'+s+""}},createCatalog:function(){var e=document.querySelectorAll(".catalog-title>a"),t=document.querySelector("#catalog");t.innerHTML=t.innerHTML+'

vue-validate-easy(github)

',t.id="catalog";for(var a=0;ah1",1),this.createTitle("#content>h2",2),this.createTitle("#content>h3",3),this.createCatalog()},beforeCreate:function(){var e;this.V.$addValidateMethod("remote_code",(e=o()(l.a.mark(function e(t){var a,n;return l.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return console.log("进行远程验证中"),e.prev=1,e.next=4,p.a.post("http://localhost:3000/remote",{code:t});case 4:if(a=e.sent,n=a.data,console.log("进行远程验证==结束"),n.validateResult){e.next=9;break}return e.abrupt("return",n.message?n.message:"校验失败");case 9:e.next=15;break;case 11:return e.prev=11,e.t0=e.catch(1),console.log("进行远程验证==错误",e.t0),e.abrupt("return","请求错误");case 15:case"end":return e.stop()}},e,this,[[1,11]])})),function(t){return e.apply(this,arguments)})),this.V.$addValidateMethod("password",function(e){if(!/^(\w|[~`!@#$%^&()\[\]:;"'|\?/><.,{}=*\\+-])+$/.test(e))return"密码只能由非空格,字母和常用字符"}),this.V.$addErrorOption("alert",{show:function(e,t,a){console.log({err:e,el:t,errContent:a}),e&&alert(a)},reset:function(){console.log('data-error-option="alert" reset')}})}},L={render:function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{class:{"is-mobile":e.isMobile},attrs:{id:"app"}},[a("transition",{attrs:{name:"fade"}},[a("div",{directives:[{name:"show",rawName:"v-show",value:e.catalogShow,expression:"catalogShow"}],attrs:{id:"catalog"},on:{click:e.clickCatalog}},[a("div",{staticClass:"close"})])]),a("div",{staticClass:"markdown-body",attrs:{id:"main"}},[e.isMobile?a("div",{attrs:{id:"catalog-btn"},on:{click:function(t){e.catalogShow=!0}}}):e._e(),a("div",{attrs:{id:"content"}},[a("h1",[e._v("实例教程")]),e._v(" "),a("h2",[e._v("1. 开始")]),e._v(" "),a("h3",[e._v("1.1 安装")]),e._v(" "),e._m(0),e._v(" "),a("h3",[e._v("1.2 引用")]),e._v(" "),a("p",[e._v("在main.js文件中引用")]),e._v(" "),e._m(1),e._v(" "),a("h2",[e._v("2. 实例")]),e._v(" "),a("h3",[e._v("2.1 基本示例")]),e._v(" "),a("code-tab",{attrs:{id:"example_1",nav:[{name:"demo"},{name:"html"},{name:"javascript"},{name:"css"}]}},[a("template",{slot:"demo"},[a("form",{staticClass:"example_1"},[a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","邮箱为必填项目"],["email"]],expression:"[['required','邮箱为必填项目'],['email']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_1","data-name":"email","data-type":"input"}},[a("label",[a("div",{staticClass:"label"},[e._v("邮箱")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"请输入邮箱"}})])]),a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy"}],staticClass:"my-form-group",attrs:{"data-scope":"example_1","data-name":"any","data-type":"input"}},[a("label",[a("div",{staticClass:"label"},[e._v("随便写点什么")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"该字段不做验证"}})])]),a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["number"]],expression:"[['number']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_1","data-name":"number","data-type":"input"}},[a("label",[a("div",{staticClass:"label"},[e._v("数字(非必须但有值需要验证)")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"输入一段数字"}})])]),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_1")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_1")}}},[e._v("重置表单")])])])]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v(' \x3c!-- 快速使用步骤 --\x3e\n \x3c!-- 1.给.my-form-group元素data-scope属性是必填的,代表着是同一组的表单。 --\x3e\n \x3c!-- 2.给.my-form-group元素data-name是必填的,代表字段的键值。 --\x3e\n \x3c!-- 3.给.my-form-group元素data-type是必填的,说明原生表单的元素类别。 --\x3e\n \x3c!-- 4.给.my-form-group元素 v-validate-easy 指令的值。 指令参数详情见:2.2 指令参数。 --\x3e\n\n \x3c!-- 约定:--\x3e\n \x3c!-- v-validate-easy指令必须在原生表单元素的上层元素上使用 --\x3e\n \x3c!-- 且 data-scope data-name data-type 只能在使用v-validate-easy指令的元素上使用 --\x3e\n
\n
\n \n
\n\n
\n \n
\n\n
\n \n
\n\n
\n \n \n
\n
\n')])])]),a("template",{slot:"javascript"},[a("pre",[a("code",{staticClass:"language-js"},[e._v(" // 重置表单方法:this.V.$reset(scope)\n // 提交表单方法: this.V.$submit(scope,(canSumit,data)=>{}) 回调函数会在该scope所有的表单元素全部验证完成后执行\n methods: {\n reset(scope) {\n this.V.$reset(scope)\n },\n submit(scope) {\n this.V.$submit(scope, (canSumit,data) => {\n // canSumit为true时,则所有该scope的所有表单验证通过\n if(!canSumit) return\n\n // 只有验证全部通过才会执行\n console.log('验证通过的数据'+data)\n alert('验证通过,数据如下\\n' + JSON.stringify(data))\n\n // 发送请求\n axios({ url: '/test',data, method: 'post'})\n .then(() => {\n // 成功响应处理\n })\n .catch(() => {\n // 错误处理\n })\n })\n }\n },\n")])])]),a("template",{slot:"css"},[a("pre",[a("code",{staticClass:"language-css"},[e._v(" /* 赋予验证错误的样式和验证成功的样式 */\n /* 验证成功时时,会对使用指令的元素加上className succ__ */\n /* 验证错误时,会对使用指令的元素加上className err__ */\n /* 验证错误时,默认在使用指令的元素子元素末尾追加一个错误提示元素,是一个span元素,className为 err__msg */\n /* 如果你在使用指令元素内部,预设了一个className为 err__msg 的元素,那么它将作为错误信息的容器元素 */\n .err__ input.input {\n border: 1px solid red;\n }\n .succ__ input.input {\n border: 1px solid green;\n }\n .err__msg {\n color: red;\n display: block;\n font-size: 14px;\n }\n")])])])],2),a("h3",[e._v("2.2 指令参数书写规则")]),e._v(" "),e._m(2),e._v(" "),a("code-tab",{attrs:{id:"example_2",nav:[{name:"demo"},{name:"html"}]}},[a("template",{slot:"demo"},[a("form",{staticClass:"example_2"},[a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required"],["number"],["minLength",[10]]],expression:"[['required'],['number'],['minLength',[10]]]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_2","data-name":"sid1","data-type":"input"}},[a("label",[a("div",{staticClass:"label"},[e._v("学号1(默认错误提示语和传递验证参数)")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"请输入学号"}})])]),a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","学号为必填项"],["number","学号为全数字构成"],["minLength",[10],"学号最小长度为10位"]],expression:"[['required','学号为必填项'],['number','学号为全数字构成'],['minLength',[10],'学号最小长度为10位']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_2","data-name":"sid2","data-type":"input"}},[a("label",[a("div",{staticClass:"label"},[e._v("学号2(自定义错误提示语)")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"请输入学号"}})])]),a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required",""],["number",""],["minLength",[10],""]],expression:"[['required',''],['number',''],['minLength',[10],'']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_2","data-name":"sid3","data-type":"input"}},[a("label",[a("div",{staticClass:"label"},[e._v("学号3(隐藏错误提示语)")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"请输入学号"}})])]),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_2")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_2")}}},[e._v("重置表单")])])])]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v(' \x3c!-- 指令参数的完整结构为 [[验证方法名,[验证方法参数1,验证方法参数2,..],自定义错误提示语],[],..] --\x3e\n \x3c!-- 当验证方法无需参数时,可写成 [[验证方法名,自定义错误提示语],[],..] --\x3e\n \x3c!-- 根据数组顺序对表单值进行验证,并且显示第一个验证错误的提示语 --\x3e\n \x3c!-- 指令的值并不是都必须填写完整的,可以看下面三个例子 --\x3e\n
\n \x3c!-- 默认验证错误提示语来自验证方法的返回值 --\x3e\n
\n \n
\n\n \x3c!-- 传入自定义错误提示语 --\x3e\n
\n \n
\n\n \x3c!-- 当自定义提示语为空字符串时,那么错误提示语会被隐藏 --\x3e\n
\n \n
\n\n
\n \n \n
\n
\n')])])])],2),a("h3",[e._v("2.3 指令修饰符(懒验证,延时验证)")]),e._v(" "),a("code-tab",{attrs:{id:"example_3",nav:[{name:"demo"},{name:"html"}]}},[a("template",{slot:"demo"},[a("form",{staticClass:"example_3"},[a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy.lazy",value:[["required","学号为必填项"],["number","学号为全数字构成"],["minLength",[10],"学号最小长度为10位"]],expression:"[['required','学号为必填项'],['number','学号为全数字构成'],['minLength',[10],'学号最小长度为10位']]",modifiers:{lazy:!0}}],staticClass:"my-form-group",attrs:{"data-scope":"example_3","data-name":"sid1","data-type":"input"}},[a("label",[a("div",{staticClass:"label"},[e._v("学号1(.lazy修饰符,blur事件才触发验证)")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"请输入学号"}})])]),a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy.delay",value:[["required","学号为必填项"],["number","学号为全数字构成"],["minLength",[10],"学号最小长度为10位"]],expression:"[['required','学号为必填项'],['number','学号为全数字构成'],['minLength',[10],'学号最小长度为10位']]",modifiers:{delay:!0}}],staticClass:"my-form-group",attrs:{"data-scope":"example_3","data-name":"sid2","data-type":"input"}},[a("label",[a("div",{staticClass:"label"},[e._v("学号2(.delay修饰符,输入时每隔500ms触发验证)")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"请输入学号"}})])]),a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","学号为必填项"],["number","学号为全数字构成"],["minLength",[10],"学号最小长度为10位"]],expression:"[['required','学号为必填项'],['number','学号为全数字构成'],['minLength',[10],'学号最小长度为10位']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_3","data-name":"sid3","data-type":"input","data-delay":"2000"}},[a("label",[a("div",{staticClass:"label"},[e._v("学号3(使用data-delay属性定义触发间隔时间,输入时每隔2s触发验证)")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"请输入学号"}})])]),a("div",{staticClass:"my-form-group"},[a("label",{directives:[{name:"validate-easy",rawName:"v-validate-easy.lazy.delay",value:[["required","学号为必填项"],["number","学号为全数字构成"],["minLength",[10],"学号最小长度为10位"]],expression:"[['required','学号为必填项'],['number','学号为全数字构成'],['minLength',[10],'学号最小长度为10位']]",modifiers:{lazy:!0,delay:!0}}],attrs:{"data-scope":"example_3","data-name":"sid4","data-type":"input"}},[a("div",{staticClass:"label"},[e._v("学号4(.lazy.delay同时使用时,只有.lazy生效)")]),a("input",{staticClass:"input",attrs:{type:"text",spellcheck:"false",placeholder:"请输入学号"}})])]),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_3")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_3")}}},[e._v("重置表单")])])])]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v('
\n
\n \n
\n\n
\n \n
\n\n
\n \n
\n\n
\n \n
\n\n
\n \n \n
\n
\n')])])])],2),a("h2",[e._v("3. 其他表单元素写法")]),e._v(" "),a("h3",[e._v("3.1 checkbox radio")]),e._v(" "),a("code-tab",{attrs:{id:"example_4",nav:[{name:"demo"},{name:"html"}]}},[a("template",{slot:"demo"},[a("form",{staticClass:"example_4"},[a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","性别必须选择一个"]],expression:"[['required','性别必须选择一个']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_4","data-name":"sex","data-type":"radio"}},[a("div",{staticClass:"label"},[e._v("性别(单选框)")]),a("div",[a("label",{staticClass:"radio"},[a("input",{attrs:{type:"radio","data-name":"sex",value:"0"}}),e._v("男")]),a("label",{staticClass:"radio"},[a("input",{staticClass:"radio",attrs:{type:"radio","data-name":"sex",value:"1"}}),e._v("女")])])]),a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","性别必须选择一个"]],expression:"[['required','性别必须选择一个']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_4","data-name":"hobby","data-type":"checkbox"}},[a("div",{staticClass:"label"},[e._v("爱好(多选框)")]),a("div",[a("label",{staticClass:"checkbox"},[a("input",{attrs:{type:"checkbox","data-name":"hobby",value:"看书"}}),e._v("看书")]),a("label",{staticClass:"checkbox"},[a("input",{attrs:{type:"checkbox","data-name":"hobby",value:"睡觉"}}),e._v("睡觉")]),a("label",{staticClass:"checkbox"},[a("input",{attrs:{type:"checkbox","data-name":"hobby",value:"游戏"}}),e._v("游戏")]),a("label",{staticClass:"checkbox"},[a("input",{attrs:{type:"checkbox","data-name":"hobby",value:"运动"}}),e._v("运动")])])]),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_4")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_4")}}},[e._v("重置表单")])])])]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v('
\n
\n
性别(单选框)
\n
\n \n \n
\n
\n
\n
爱好(多选框)
\n
\n \n \n \n \n
\n
\n
\n \n \n
\n
\n\n')])])])],2),a("h3",[e._v("3.2 select")]),e._v(" "),a("code-tab",{attrs:{id:"example_5",nav:[{name:"demo"},{name:"html"}]}},[a("template",{slot:"demo"},[a("form",{staticClass:"example_5"},[a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","选择一个身份"]],expression:"[['required','选择一个身份']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_5","data-name":"identity","data-type":"select"}},[a("div",{staticClass:"label"},[e._v("身份(单选列表)")]),a("select",[a("option",[e._v("学生")]),a("option",[e._v("工作")])])]),a("div",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","喜欢吃的必须选择一个"]],expression:"[['required','喜欢吃的必须选择一个']]"}],staticClass:"my-form-group",attrs:{"data-scope":"example_5","data-name":"eat","data-type":"select"}},[a("div",{staticClass:"label"},[e._v("爱吃的(多选列表)")]),a("select",{attrs:{multiple:"multiple"}},[a("option",[e._v("鸡")]),a("option",[e._v("鸭")]),a("option",[e._v("鱼")]),a("option",[e._v("肉")])])]),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_5")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_5")}}},[e._v("重置表单")])])])]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v(' \x3c!-- 指令写在select元素,给select元素指定scope,name属性 --\x3e\n
\n
\n
身份(单选列表)
\n \n
\n\n
\n
爱吃的(多选列表)
\n \n
\n\n
\n \n \n
\n
\n')])])])],2),a("h3",[e._v("3.3 自定义组件")]),e._v(" "),e._m(3),e._v(" "),a("code-tab",{attrs:{id:"example_6",nav:[{name:"demo"},{name:"html"},{name:"myInput",text:"my-input.vue"},{name:"javascript"}]}},[a("template",{slot:"demo"},[a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","用户名不能为空"]],expression:"[['required','用户名不能为空']]"}],attrs:{label:"用户名","data-scope":"example_6","data-name":"username"}}),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_6")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_6")}}},[e._v("重置表单")])])],1),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v(' \x3c!-- 这里data-type属性在my-input.vue中已经指定了 --\x3e\n \n\n
\n \n \n
\n')])])]),a("template",{slot:"myInput"},[a("a",{staticStyle:{background:"#f6f8fa",padding:"0 20px",display:"block"},attrs:{href:"https://github.com/lfyfly/vue-validate-easy/blob/master/src/components/my-input.vue",target:"_blank"}},[e._v("my-input.vue")])]),a("template",{slot:"javascript"},[a("pre",[a("code",{staticClass:"language-js"},[e._v(" // 引用自定义组件\n // 下面例子将使用自定义组件,不再展示引用代码\n import myInput from '@/components/my-input'\n // ...\n components:{\n myInput\n }\n")])])])],2),a("h2",[e._v("4. 新增验证方法")]),e._v(" "),a("h3",[e._v("4.1 新增验证方法(this.V.$addValidateMethod)")]),e._v(" "),a("code-tab",{attrs:{id:"example_7",nav:[{name:"demo"},{name:"html"},{name:"javascript"}]}},[a("template",{slot:"demo"},[a("form",{staticClass:"example_7"},[a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","密码不能为空"],["password"],["maxLength",[32],"密码最长为32位"]],expression:"[['required','密码不能为空'],['password'],['maxLength',[32],'密码最长为32位']]"}],attrs:{id:"pwd",label:"密码","data-scope":"example_7","data-name":"pwd",type:"password",placeholder:"请输入密码"}}),a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","确认密码不能为空"],["equalTo",["#pwd"],"密码输入不一致"]],expression:"[['required','确认密码不能为空'],['equalTo',['#pwd'],'密码输入不一致']]"}],attrs:{label:"确认密码","data-scope":"example_7","data-name":"repeatpwd",type:"password",placeholder:"请输入确认密码"}}),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_7")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_7")}}},[e._v("重置表单")])])],1)]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v('
\n \n \n \n \n\n
\n \n \n
\n
\n')])])]),a("template",{slot:"javascript"},[a("pre",[a("code",{staticClass:"language-js"},[e._v(" beforeCreate() {\n this.V.$addValidateMethod('password', function (val) {\n var p = /^(\\w|[~`!@#$%^&()\\[\\]:;\"'|\\?/><.,{}=*\\\\+-])+$/.test(val)\n if(!p) return '密码只能由非空格,字母和常用字符组成'\n })\n\n // 也可传入对象批量新增\n this.V.$addValidateMethod({\n validator1(){},\n validator2(){},\n validator3(){},\n ....\n })\n }\n")])])]),a("template",{slot:"myInput"},[a("a",{staticStyle:{background:"#f6f8fa",padding:"0 20px",display:"block"},attrs:{href:"/my-input.vue",target:"_blank"}},[e._v("github地址/my-input.vue")])])],2),a("h3",[e._v("4.2 远程校验方法写法")]),e._v(" "),a("code-tab",{attrs:{id:"example_8",nav:[{name:"demo"},{name:"html"},{name:"javascript"}]}},[a("template",{slot:"demo"},[a("form",{staticClass:"example_8"},[a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","验证码不能为空"],["length",["6"],"验证码长度为6位"],["remote_code"]],expression:"[['required','验证码不能为空'],['length',['6'],'验证码长度为6位'],['remote_code']]"}],attrs:{label:"远程校验验证码","data-scope":"example_8","data-name":"code"}}),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_8")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_8")}}},[e._v("重置表单")])])],1)]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v('
\n \n\n
\n \n \n
\n
')])])]),a("template",{slot:"javascript"},[a("pre",[a("code",{staticClass:"language-js"},[e._v(" // 因为是异步请求,这里讲验证方法定义成 async 函数\n // async内 await 请求结果\n // return 值为验证错误的提示语,可以由后端响应的错误提示语\n this.V.$addValidateMethod('remote_code', async function (val) {\n console.log('进行远程验证中')\n try {\n // 这个接口非真实接口,所以会请求错误\n var { data } = await axios.post('http://localhost:3000/remote', { code: val })\n console.log('进行远程验证==结束')\n if (!data.validateResult) return data.message ? data.message : '校验失败'\n } catch (err) {\n console.log('进行远程验证==错误', err)\n return '请求错误'\n }\n })\n")])])])],2),a("h3",[e._v("4.3 Vue.use的时候批量增加验证方法")]),e._v(" "),a("code-tab",{attrs:{id:"example_9",nav:[{name:"demo"},{name:"html"},{name:"validators",text:"validators.js"},{name:"main",text:"main.js"}]}},[a("template",{slot:"demo"},[a("form",{staticClass:"example_9"},[a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required"],["aaa"]],expression:"[['required'],['aaa']]"}],attrs:{label:"aaa","data-scope":"example_9","data-name":"aaa"}}),a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required"],["bbb"]],expression:"[['required'],['bbb']]"}],attrs:{label:"bbb","data-scope":"example_9","data-name":"bbb"}}),a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required"],["ccc"]],expression:"[['required'],['ccc']]"}],attrs:{label:"ccc","data-scope":"example_9","data-name":"ccc"}}),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("example_9")}}},[e._v("提交表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("example_9")}}},[e._v("重置表单")])])],1)]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v('
\n \n \n \n\n
\n \n \n
\n
\n')])])]),a("template",{slot:"validators"},[a("pre",[a("code",{staticClass:"language-js"},[e._v(" export default {\n // 以下方法只是做测试用\n aaa(val) {\n return val != 'aaa' && '要等于aaa'\n },\n bbb(val) {\n return val != 'bbb' && '要等于bbb'\n },\n ccc(val) {\n return val != 'ccc' && '要等于ccc'\n },\n }\n")])])]),a("template",{slot:"main"},[a("pre",[a("code",{staticClass:"language-js"},[e._v(" import vueValidateEasy from 'vue-validate-easy'\n import validators from './my-validators/validators'\n Vue.use(vueValidateEasy,{validators})\n")])])])],2),a("h3",[e._v("4.3 内置验证方法")]),e._v(" "),a("a",{staticStyle:{background:"#f6f8fa",padding:"0 20px",display:"block"},attrs:{href:"https://github.com/lfyfly/vue-validate-easy/blob/master/src/vue-validate-easy/validatorStore.js",target:"_blank"}},[e._v("validatorStores.js")]),a("h2",[e._v("5. 调用方法主动验证")]),e._v(" "),a("code-tab",{attrs:{id:"example_10",nav:[{name:"demo"},{name:"html"},{name:"javascript"}]}},[a("template",{slot:"demo"},[a("form",{attrs:{id:"example_10"}},[a("h3",[e._v("用户登录")]),a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required"]],expression:"[['required']]"}],attrs:{id:"loginUsername",label:"用户名","data-scope":"login","data-name":"username"}}),a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required"]],expression:"[['required']]"}],attrs:{label:"密码","data-scope":"login",type:"password","data-name":"pwd"}}),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.validatorAll("login")}}},[e._v("主动验证登录表单")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.validateLoginUsername(t)}}},[e._v("主动验证 用户名(单字段验证)")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.resetLoginUsername(t)}}},[e._v("重置用户名表单(单字段重置)")])]),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("login")}}},[e._v("登录")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("login")}}},[e._v("重置")])])],1)]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v('
\n

用户登录

\n \n \n\n
\n \n \n \n
\n
\n \n \n
\n
\n')])])]),a("template",{slot:"javascript"},[a("pre",[a("code",{staticClass:"language-js"},[e._v(" methods:{\n // 主动验证所有scope为register的表单元素\n validatorAll(scope){\n this.V.$validateAll(scope)\n },\n // 主动验证登录用户名\n // 传入的参数为使用了 v-validate-easy指令的元素\n validateLoginUsername(){\n this.V.$validateSingle(document.querySelector('#loginUsername'))\n },\n resetLoginUsername() {\n this.V.$resetSingle(document.querySelector('#loginUsername'))\n },\n }\n")])])])],2),a("h2",[e._v("6. 自定义错误提示方法")]),e._v(" "),a("code-tab",{attrs:{id:"example_11",nav:[{name:"demo"},{name:"html"},{name:"javascript"}]}},[a("template",{slot:"demo"},[a("form",{attrs:{id:"example_11"}},[a("h3",[e._v("用户注册")]),a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy.lazy",value:[["required","邮箱不能为空"],["email"]],expression:"[['required','邮箱不能为空'],['email']]",modifiers:{lazy:!0}}],attrs:{label:"邮箱(alert方式提示错误)","data-error-option":"alert","data-scope":"register","data-name":"email"}}),a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required"]],expression:"[['required']]"}],attrs:{id:"register_pwd",label:"密码","data-scope":"register",type:"password","data-name":"pwd"}}),a("my-input",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required"],["equalTo",["#register_pwd"]]],expression:"[['required'],['equalTo',['#register_pwd']]]"}],attrs:{label:"再次输入密码","data-scope":"register",type:"password","data-name":"repeatPwd"}}),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("register")}}},[e._v("注册")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("register")}}},[e._v("重置")])])],1)]),a("template",{slot:"html"},[a("pre",[a("code",{staticClass:"language-html"},[e._v('
\n

用户注册

\n \x3c!-- 首先你要使用this.V.$addErrorOption方法添加一个名为alert错误处理对象 --\x3e\n \x3c!-- 再通过设置data-error-option="alert", email字段采用了alert进行错误提示 --\x3e\n \n \n \n
\n \n \n
\n
\n')])])]),a("template",{slot:"javascript"},[a("pre",[a("code",{staticClass:"language-js"},[e._v(" beforeCreate(){\n // 使用了data-error-option=\"alert\"表单元素,当验证错误的时候会,弹出错误信息\n this.V.$addErrorOption('alert', {\n show(err, directiveEl, errContent) {\n console.log({err, directiveEl, errContent})\n if (err) {\n alert(errContent)\n }\n },\n reset(el) {\n console.log('data-error-option=\"alert\" reset')\n }\n })\n }\n")])])])],2),a("h2",[e._v("7. 自定义表单元素(不借助原生实现)")]),e._v(" "),a("code-tab",{attrs:{id:"example_1",nav:[{name:"demo"},{name:"custom",text:"自定义表单元素"}]}},[a("template",{slot:"demo"},[a("form",[a("custom-checks",{directives:[{name:"validate-easy",rawName:"v-validate-easy",value:[["required","请选择你的答案"]],expression:"[['required','请选择你的答案']]"}],attrs:{question:"这是一个问题?(多选)","data-scope":"examination","data-custom":"wahaha","data-name":"answer",data:[{text:"A.选项1",value:"A"},{text:"B.选项2",value:"B"},{text:"C.选项3",value:"C"},{text:"D.选项4",value:"D"}]}}),a("div",{staticClass:"btn-group"},[a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.submit("examination")}}},[e._v("提交答案")]),a("button",{staticClass:"my-btn",on:{click:function(t){t.preventDefault(),e.reset("examination")}}},[e._v("重置")])])],1)]),a("template",{slot:"custom"},[a("a",{attrs:{href:"https://github.com/lfyfly/vue-validate-easy/blob/master/src/components/custom-checks.vue",target:"_blank"}},[e._v("custom-checks.vue")])])],2),a("h1",[e._v("Api")]),e._v(" "),a("h2",[e._v("8. options")]),e._v(" "),a("h3",[e._v("8.1 options.validators")]),e._v(" "),a("p",[e._v("用于批量新增自定义验证方法")]),e._v(" "),e._m(4),e._v(" "),a("h2",[e._v("9. 属性")]),e._v(" "),a("h3",[e._v("9.1 scope data-type name delay data-error-option")]),e._v(" "),e._m(5),e._v(" "),e._m(6),e._v(" "),a("h2",[e._v("10. v-validate-easy指令")]),e._v(" "),a("h3",[e._v("10.1 指令值")]),e._v(" "),a("p",[e._v("v-validate-easy 的值是一个数组,最多只有三个元素。")]),e._v(" "),e._m(7),e._v(" "),a("h3",[e._v("10.2 指令修饰符")]),e._v(" "),e._m(8),e._v(" "),e._m(9),e._v(" "),a("h2",[e._v("11. 方法")]),e._v(" "),a("h3",[e._v("V.$submit")]),e._v(" "),a("h4",[e._v("语法")]),e._v(" "),e._m(10),e._v(" "),a("h4",[e._v("参数")]),e._v(" "),e._m(11),e._v(" "),a("h4",[e._v("回调参数")]),e._v(" "),e._m(12),e._v(" "),a("h3",[e._v("V.$reset")]),e._v(" "),a("p",[e._v("重置当前scope的所有表单")]),e._v(" "),a("h4",[e._v("语法")]),e._v(" "),e._m(13),e._v(" "),a("h3",[e._v("V.$resetSingle")]),e._v(" "),a("p",[e._v("重置单个表单字段")]),e._v(" "),a("h4",[e._v("语法")]),e._v(" "),e._m(14),e._v(" "),a("h3",[e._v("V.$validateAll")]),e._v(" "),a("p",[e._v("主动调用验证当前scope的所有元素")]),e._v(" "),a("h4",[e._v("语法")]),e._v(" "),e._m(15),e._v(" "),a("h4",[e._v("返回值")]),e._v(" "),e._m(16),e._v(" "),a("h3",[e._v("V.$validateSingle")]),e._v(" "),a("p",[e._v("主动调用验证当前表单元素的字段")]),e._v(" "),a("h4",[e._v("语法")]),e._v(" "),e._m(17),e._v(" "),a("h4",[e._v("返回值")]),e._v(" "),e._m(18),e._v(" "),a("h3",[e._v("V.$addValidateMethod")]),e._v(" "),a("p",[e._v("新增验证方法")]),e._v(" "),a("h4",[e._v("语法")]),e._v(" "),e._m(19),e._v(" "),a("h4",[e._v("实例如下")]),e._v(" "),e._m(20),e._v(" "),a("h3",[e._v("V.$addErrorOption")]),e._v(" "),e._m(21),e._v(" "),a("h3",[e._v("关于自定义验证方法书写规则")]),e._v(" "),e._m(22)],1)])],1)},staticRenderFns:[function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",{staticClass:"language-nohighlight"},[this._v(" npm install vue-validate-easy --save\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",{staticClass:"language-js"},[this._v(" import vueValidateEasy from 'vue-validate-easy'\n Vue.use(vueValidateEasy)\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("p",[t("code",[this._v("v-validate-easy指令必须在原生表单元素的上层元素上使用")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("p",[t("code",[this._v("在vue组件上添加data-*属性时,会此属性原样渲染到该组件的根元素上")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",{staticClass:"language-js"},[this._v(" import validators from './my-validators/validators'\n var validators ={\n validateMethod1(val){\n\n },\n validateMethod1(val){\n\n },\n ....\n }\n Vue.use(vueValidateEasy,{validators})\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("p",[t("code",[this._v("以下属性只能使用在使用了v-validate-easy指令的元素上")])])},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("table",[a("thead",[a("tr",[a("th",[e._v("属性")]),e._v(" "),a("th",[e._v("必填")]),e._v(" "),a("th",[e._v("属性值")]),e._v(" "),a("th",[e._v("描述")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("data-scope")]),e._v(" "),a("td",[e._v("必填")]),e._v(" "),a("td",[e._v("自定义")]),e._v(" "),a("td",[e._v("用于标识为同一组表单,作为 $submit 和 $reset 的方法的参数传入")])]),e._v(" "),a("tr",[a("td",[e._v("data-name")]),e._v(" "),a("td",[e._v("必填")]),e._v(" "),a("td",[e._v("自定义")]),e._v(" "),a("td",[e._v("表单数据字段键值")])]),e._v(" "),a("tr",[a("td",[e._v("data-type")]),e._v(" "),a("td",[e._v("可选")]),e._v(" "),a("td",[e._v("'checkbox' 'radio' 'select' 'input' 'textarea'")]),e._v(" "),a("td",[e._v("指定表单类型")])]),e._v(" "),a("tr",[a("td",[e._v("data-delay")]),e._v(" "),a("td",[e._v("可选")]),e._v(" "),a("td",[e._v("整数,如'1000'")]),e._v(" "),a("td",[e._v("单位(ms),当输入框为oninput事件触发的时候,用于限制触发频率")])]),e._v(" "),a("tr",[a("td",[e._v("data-error-option")]),e._v(" "),a("td",[e._v("可选")]),e._v(" "),a("td",[e._v("通过V.$addErrorOption添加的错误处理方法名")]),e._v(" "),a("td",[e._v("处理错误的提示,需要手动添加,默认值为 'default'")])])])])},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("table",[a("thead",[a("tr",[a("th",[e._v("数组中的元素")]),e._v(" "),a("th",[e._v("类型")]),e._v(" "),a("th",[e._v("必填")]),e._v(" "),a("th",[e._v("描述")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("第一个数组元素")]),e._v(" "),a("td",[e._v("String")]),e._v(" "),a("td",[e._v("必填")]),e._v(" "),a("td",[e._v("验证的方法名")])]),e._v(" "),a("tr",[a("td",[e._v("第二个数组元素")]),e._v(" "),a("td",[e._v("Arrary | String")]),e._v(" "),a("td",[e._v("可选")]),e._v(" "),a("td",[e._v("为Arrary类型时值的是验证方法的接收参数,String类型时为自定义错误信息")])]),e._v(" "),a("tr",[a("td",[e._v("第三个数组元素")]),e._v(" "),a("td",[e._v("String")]),e._v(" "),a("td",[e._v("可选")]),e._v(" "),a("td",[e._v("自定义错误信息,只有当第二个元素为Array类型时才生效。")])])])])},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("table",[a("thead",[a("tr",[a("th",[e._v("修饰符")]),e._v(" "),a("th",[e._v("作用")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("v-validate-easy.delay")]),e._v(" "),a("td",[e._v("输入框为oninput事件触发的时候,用于限制触发频率,触发间隔500ms。delay属性可自定义该时间。")])]),e._v(" "),a("tr",[a("td",[e._v("v-validate-easy.lazy")]),e._v(" "),a("td",[e._v("只会blur事件之后才会触发验证")])])])])},function(){var e=this.$createElement,t=this._self._c||e;return t("p",[t("strong",[this._v("注意")]),this._v(": 如果两个修饰符同时使用(v-validate-easy.lazy.delay),"),t("strong",[this._v("只有.lazy修饰符起作用")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",{staticClass:"language-js"},[this._v(" this.V.$submit(scope, (canSumit,data) => {\n //- 对验证结果进行处理\n })\n")])])},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("table",[a("thead",[a("tr",[a("th",[e._v("参数")]),e._v(" "),a("th",[e._v("必填")]),e._v(" "),a("th",[e._v("类型")]),e._v(" "),a("th",[e._v("描述")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("scope")]),e._v(" "),a("td",[e._v("必填")]),e._v(" "),a("td",[e._v("String")]),e._v(" "),a("td",[e._v("同一组表单标识")])]),e._v(" "),a("tr",[a("td",[e._v("callBack")]),e._v(" "),a("td",[e._v("必填")]),e._v(" "),a("td",[e._v("function")]),e._v(" "),a("td",[e._v("对验证结果进行处理")])])])])},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("table",[a("thead",[a("tr",[a("th",[e._v("参数")]),e._v(" "),a("th",[e._v("类型")]),e._v(" "),a("th",[e._v("描述")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("canSumit")]),e._v(" "),a("td",[e._v("Boolean")]),e._v(" "),a("td",[e._v("为true是,说明当前scope的表单数据全部验证通过")])]),e._v(" "),a("tr",[a("td",[e._v("data")]),e._v(" "),a("td",[e._v("Object")]),e._v(" "),a("td",[e._v("当前scope表单的数据")])]),e._v(" "),a("tr",[a("td",[e._v("errData")]),e._v(" "),a("td",[e._v("Object")]),e._v(" "),a("td",[e._v("当前scope表单验证错误的数据,canSumit为true时,errData为null")])])])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v("this.V.$reset(scope)\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v(" this.V.$resetSingle(directiveEl)\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v(" this.V.$validateAll(scope)\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v("// this.V.$validateAll是个async函数,想要取得返回值需用async函数嵌套\nmethod:{\n async validateAll(scope){\n var { canSumit, data, errData } = await validateAll(scope)\n // 获得的值与 this.V.$submit方法的参数一致\n }\n}\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v(" this.V.$validateSingle(directiveEl)\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v("// this.V.$validate是个async函数,想要取得返回值需用async函数嵌套\nmethod:{\n async validate(el){\n var { err,value } = await validate(el)\n // err代表是否验证错误\n // value是该字段的值\n }\n}\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v(" // 新增一个名为methodName的验证方法\n this.V.$addValidateMethod(methodName, method)\n // 新增多个验证方法\n // validators是一个对象,可以包含多个验证方法\n this.V.$addValidateMethod(validators)\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v(" beforeCreate(){\n // this.V.$addValidateMethod(methodName,method)\n this.V.$addValidateMethod('password', function (val) {\n var p = /^(\\w|[~`!@#$%^&()\\[\\]:;\"'|\\?/><.,{}=*\\\\+-])+$/.test(val)\n if(!p) return '密码只能由非空格,字母和常用字符'\n })\n\n // 也可传入对象批量新增\n this.V.$addValidateMethod({\n validator1(){},\n validator2(){},\n validator3(){},\n // ....\n })\n }\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v(" this.V.$addErrorOption('data-error-option-name', {\n show(err, directiveEl, errContent) {\n if (err) {\n console.log(errContent)\n }\n },\n reset() {\n console.log('reset')\n }\n})\n\n")])])},function(){var e=this.$createElement,t=this._self._c||e;return t("pre",[t("code",[this._v(" // val为当前表单的值\n // len为验证所需参数,是由指令传如值的元素数组中的第二个数组元素\n // v-validate-easy=\"[['length',[6]]]\" ,6是传给length验证方法的的第二个参数(也就是len)\n // 注意参数是个数组类型,要写成['length',[6]], 不能写成['length',6]\n // 返回值是验证不通过时的默认错误提示语\n this.V.$addValidateMethod({\n length (val, len) {\n if (len != val.length) return `长度必须为${len}位`\n }\n })\n\n")])])}]};var M,j=a("VU/8")(A,L,!1,function(e){a("auNa")},null,null).exports,R=a("Gu7T"),D=a.n(R),B={required:function(e){if("[]"==d()(e)||!e&&0!==e)return"必填项不能为空"},maxLength:function(e,t){if(e.length>t)return"长度不得超过"+t+"位"},minLength:function(e,t){if(e.lengtha)return"输入长度必须在"+t+"位和"+a+"位之间"},equalTo:function(e,t){var a=document.querySelector(t);if(e!=(a="input"==a.tagName.toLocaleLowerCase()?a:a.querySelector("input")).value)return"与目标值不一致"},length:function(e,t){if(t!=e.length)return"长度必须为"+t+"位"},email:function(e){if(!/^([\w\.\-]+)@([\w\.\-]+)\.([\w]{2,4})$/.test(e))return"邮箱格式不正确"},number:function(e){if(!/^\d+$/.test(e))return"必须为数字"}},T=function(e){if(!B[e])throw"没有名"+e+"的验证方法";return B[e]},I=function(e,t){B[e]=t},U={default:{insertAfter:function(e,t){var a=t.parentNode;a.lastChild==t?a.appendChild(e):a.insertBefore(e,t.nextSibling)},show:function(e,t,a){var n;e?(t.className=t.className.replace(" succ__",""),-1==t.className.indexOf("err__")&&(t.className=t.className+" err__"),(n=t.querySelector(".err__msg"))?n.textContent=a:((n=document.createElement("span")).className="err__msg",n.textContent=a,t.appendChild(n))):((n=t.querySelector(".err__msg"))&&(n.textContent=""),-1==t.className.indexOf("succ__")&&(t.className=t.className+" succ__"))},reset:function(e){e.className=e.className.replace(" err__",""),e.className=e.className.replace(" succ__","");var t=e.querySelector(".err__msg");t&&(t.textContent="")}}},z={getErrorOption:function(e){return U[e||"default"]},resetErrorTip:function(e){for(var t=document.querySelectorAll("[data-scope="+e+"]"),a=0;a"})},Q89W:function(e,t){},auNa:function(e,t){},"b+CC":function(e,t){},hSb9:function(e,t){},mTPd:function(e,t){}},["NHnr"]); -------------------------------------------------------------------------------- /docs/static/js/manifest.3ad1d5771e9b13dbdad2.js: -------------------------------------------------------------------------------- 1 | !function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a 2 | 3 | 4 | 5 | 6 | 7 | vue-validate-easy 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-validate-easy", 3 | "version": "1.0.5", 4 | "description": "Vue form validation plug-in", 5 | "author": "lfyfly <410793635@qq.com>", 6 | "github":"https://github.com/lfyfly/vue-validate-easy", 7 | "main": "./src/vue-validate-easy/index.js", 8 | "keywords": [ 9 | "vue", 10 | "validate", 11 | "validator", 12 | "vue-validate", 13 | "vue-validator", 14 | "form" 15 | ], 16 | "scripts": { 17 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 18 | "start": "npm run dev", 19 | "build": "node build/build.js" 20 | }, 21 | "dependencies": { 22 | "github-markdown-css": "^2.10.0", 23 | "highlight.js": "^9.12.0", 24 | "highlightjs": "^9.10.0", 25 | "jstransformer-markdown-it": "^2.0.0", 26 | "vue": "^2.5.2" 27 | }, 28 | "devDependencies": { 29 | "autoprefixer": "^7.1.2", 30 | "axios": "^0.18.0", 31 | "babel-core": "^6.22.1", 32 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 33 | "babel-loader": "^7.1.1", 34 | "babel-plugin-syntax-jsx": "^6.18.0", 35 | "babel-plugin-transform-runtime": "^6.22.0", 36 | "babel-plugin-transform-vue-jsx": "^3.5.0", 37 | "babel-preset-env": "^1.3.2", 38 | "babel-preset-stage-2": "^6.22.0", 39 | "chalk": "^2.0.1", 40 | "copy-webpack-plugin": "^4.0.1", 41 | "css-loader": "^0.28.0", 42 | "es6-promise": "^4.2.4", 43 | "extract-text-webpack-plugin": "^3.0.0", 44 | "file-loader": "^1.1.4", 45 | "friendly-errors-webpack-plugin": "^1.6.1", 46 | "html-webpack-plugin": "^2.30.1", 47 | "node-notifier": "^5.1.2", 48 | "node-sass": "^4.7.2", 49 | "optimize-css-assets-webpack-plugin": "^3.2.0", 50 | "ora": "^1.2.0", 51 | "portfinder": "^1.0.13", 52 | "postcss-import": "^11.0.0", 53 | "postcss-loader": "^2.0.8", 54 | "postcss-url": "^7.2.1", 55 | "promise-polyfill": "^6.1.0", 56 | "pug": "^2.0.0-rc.4", 57 | "rimraf": "^2.6.0", 58 | "sass-loader": "^6.0.6", 59 | "semver": "^5.3.0", 60 | "shelljs": "^0.7.6", 61 | "uglifyjs-webpack-plugin": "^1.1.1", 62 | "url-loader": "^0.5.8", 63 | "vee-validate": "^2.0.6", 64 | "vue-loader": "^13.3.0", 65 | "vue-style-loader": "^3.0.1", 66 | "vue-template-compiler": "^2.5.2", 67 | "webpack": "^3.6.0", 68 | "webpack-bundle-analyzer": "^2.9.0", 69 | "webpack-dev-server": "^2.9.1", 70 | "webpack-merge": "^4.1.0" 71 | }, 72 | "engines": { 73 | "node": ">= 6.0.0", 74 | "npm": ">= 3.0.0" 75 | }, 76 | "browserslist": [ 77 | "> 1%", 78 | "last 2 versions", 79 | "not ie <= 8" 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 203 | 204 | 205 | 1082 | 1083 | 1084 | 1226 | -------------------------------------------------------------------------------- /src/assets/highlight.pack.js: -------------------------------------------------------------------------------- 1 | /*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ 2 | !function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}}); -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfyfly/vue-validate-easy/3e57b1237ac4432cb79ac685a7269a3eac3fd888/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/code-tab.vue: -------------------------------------------------------------------------------- 1 | 2 | 27 | 28 | 29 | 39 | 40 | 41 | 60 | -------------------------------------------------------------------------------- /src/components/custom-checks.vue: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 31 | 32 | 33 | 95 | -------------------------------------------------------------------------------- /src/components/my-input.vue: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 33 | 40 | 41 | 42 | 54 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | // var Promise = require('es6-promise').Promise; 4 | 5 | // // To add to window 6 | // if (!window.Promise) { 7 | // window.Promise = Promise 8 | // } 9 | 10 | 11 | import Promise from 'promise-polyfill' 12 | // To add to window 13 | if (!window.Promise) { 14 | window.Promise = Promise 15 | } 16 | import Vue from 'vue' 17 | import App from './App' 18 | 19 | Vue.config.productionTip = false 20 | import validators from './my-validators/validators' 21 | import vueValidateEasy from './vue-validate-easy' 22 | Vue.use(vueValidateEasy,{validators}) 23 | 24 | 25 | 26 | 27 | /* eslint-disable no-new */ 28 | new Vue({ 29 | el: '#app', 30 | components: { App }, 31 | template: '' 32 | }) 33 | -------------------------------------------------------------------------------- /src/my-validators/validators.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // 以下方法只是做测试用 3 | aaa(val) { 4 | return val != 'aaa' && '要等于aaa' 5 | }, 6 | bbb(val) { 7 | return val != 'bbb' && '要等于bbb' 8 | }, 9 | ccc(val) { 10 | return val != 'ccc' && '要等于ccc' 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /src/vue-validate-easy/errTip.js: -------------------------------------------------------------------------------- 1 | 2 | var errOptions = { 3 | default: { 4 | insertAfter(newElement, targetElement) { 5 | var parent = targetElement.parentNode; 6 | // 如果最后的节点是目标元素,则直接添加 7 | if (parent.lastChild == targetElement) { 8 | parent.appendChild(newElement) 9 | } else { 10 | // 如果不是,则插入在目标元素的下一个兄弟节点 的前面 11 | parent.insertBefore(newElement, targetElement.nextSibling) 12 | } 13 | }, 14 | show(err, el, errContent) { 15 | 16 | if (err) { 17 | // 如果有的 .succ__ 话,就清除 18 | el.className = el.className.replace(' succ__', '') 19 | 20 | // 如果有的 .err__ 话,不重复添加 21 | if (el.className.indexOf('err__') == -1) { 22 | el.className = el.className + ' err__' 23 | } 24 | // 如果用户预先写了.err_msg元素 或者 已经在元素的子元素尾部添加了.err__msg元素,那么久不在添加新的元素 25 | var errMsgEl = el.querySelector('.err__msg') 26 | if (errMsgEl) { 27 | errMsgEl.textContent = errContent 28 | } else { 29 | // 首次创建错误元素 30 | var errMsgEl = document.createElement('span') 31 | errMsgEl.className = 'err__msg' 32 | errMsgEl.textContent = errContent 33 | el.appendChild(errMsgEl) 34 | } 35 | 36 | } else { // 验证成功 37 | var errMsgEl = el.querySelector('.err__msg') 38 | if(errMsgEl) errMsgEl.textContent ='' 39 | if (el.className.indexOf('succ__') == -1) { // 防止重复添加 40 | el.className = el.className + ' succ__' 41 | } 42 | } 43 | }, 44 | reset(el) { 45 | el.className = el.className.replace(' err__', '') 46 | el.className = el.className.replace(' succ__', '') 47 | var errMsgEl = el.querySelector('.err__msg') 48 | if(errMsgEl) errMsgEl.textContent ='' 49 | } 50 | } 51 | } 52 | 53 | export default { 54 | getErrorOption(errOptionName) { 55 | return errOptions[errOptionName ? errOptionName : 'default'] 56 | }, 57 | resetErrorTip(scope) { 58 | var formEles = document.querySelectorAll(`[data-scope=${scope}]`) 59 | for (var i = 0; i < formEles.length; i++) { 60 | var el = formEles[i] 61 | this.resetSingleErrorTip(el) 62 | } 63 | }, 64 | resetSingleErrorTip(el) { 65 | 66 | var errOptionName = el.getAttribute('data-error-option') 67 | var errOption = errOptions[errOptionName ? errOptionName : 'default'] 68 | if (!errOption) throw `没有这个名为${errOptionName}错误处理方法` 69 | 70 | errOption.reset && errOption.reset(el) 71 | }, 72 | 73 | /** 74 | * 新增错误处理方法 75 | * 76 | * @param {any} errOptionName 77 | * @param {any} option {show(){}, reset(){}} 78 | */ 79 | addErrorOption(errOptionName, option) { // 通过传入参数指定,哪种错误类型 80 | errOptions[errOptionName] = option 81 | }, 82 | } 83 | -------------------------------------------------------------------------------- /src/vue-validate-easy/formElements.js: -------------------------------------------------------------------------------- 1 | import validate from './validate' 2 | 3 | var formElements = { 4 | input: { 5 | condition(directiveEl) { 6 | if (directiveEl.type_ == 'input' || directiveEl.type_ == 'textarea') { 7 | directiveEl.eventEl_ = directiveEl.querySelector(directiveEl.type_) 8 | return true 9 | } 10 | }, 11 | bindEvent(directiveEl) { 12 | 13 | var eventEl = directiveEl.eventEl_ 14 | var delay_ = parseInt(directiveEl.getAttribute('data-delay')) 15 | var { delay, lazy } = directiveEl.binding.modifiers 16 | if (delay_) { 17 | delay = delay_ 18 | } else { 19 | delay = delay ? 500 : false 20 | } 21 | var delaying = false 22 | 23 | // ie10 11 使用placeholder时,进入页面会主动触发一次input事件 24 | // 这里采用延时绑定规避这一情况 25 | eventEl.onfocus = () => { 26 | eventEl.onfocus = null 27 | eventEl.onblur = eventEl.oninput = (e) => { 28 | // .lazy修饰符 29 | if (lazy && e.type == 'input') return 30 | // .delay修饰符 31 | if (delay && e.type == 'input') { 32 | if (delaying) { 33 | return 34 | } 35 | delaying = true 36 | setTimeout(() => { 37 | delaying = false 38 | }, delay); 39 | } 40 | var value = this.getValue(directiveEl) 41 | validate(directiveEl, value) 42 | } 43 | } 44 | }, 45 | getValue(directiveEl) { 46 | return directiveEl.eventEl_.value.replace(/^\s+|\s+$/g, "") 47 | }, 48 | resetValue(directiveEl) { 49 | directiveEl.eventEl_.value = '' 50 | } 51 | }, 52 | checks: { 53 | condition(directiveEl) { 54 | if (directiveEl.type_ == 'checkbox' || directiveEl.type_ == 'radio') { 55 | directiveEl.checks_ = directiveEl.querySelectorAll(`[type=${directiveEl.type_}]`) 56 | return true 57 | } 58 | }, 59 | bindEvent(directiveEl) { 60 | 61 | var checks = directiveEl.checks_ 62 | for (var i = 0; i < checks.length; i++) { 63 | checks[i].onchange = (e) => { 64 | var value = this.getValue(directiveEl) 65 | validate(directiveEl, value) 66 | } 67 | } 68 | }, 69 | getValue(directiveEl) { 70 | var value = directiveEl.type_ == 'radio' ? '' : [] 71 | var checks = directiveEl.checks_ 72 | for (var i = 0; i < checks.length; i++) { 73 | if (checks[i].checked) { 74 | if (value === '') { 75 | value = checks[i].value 76 | break 77 | } else { 78 | value.push(checks[i].value) 79 | } 80 | } 81 | } 82 | return value 83 | }, 84 | resetValue(directiveEl) { 85 | var checks = directiveEl.checks_ 86 | for (var i = 0; i < checks.length; i++) { 87 | checks[i].checked = false 88 | } 89 | } 90 | }, 91 | select: { 92 | condition(directiveEl) { 93 | 94 | if (directiveEl.type_ == 'select') { 95 | directiveEl.eventEl_ = directiveEl.querySelector('select') 96 | return true 97 | } 98 | }, 99 | bindEvent(directiveEl, binding) { 100 | var eventEl = directiveEl.eventEl_ || directiveEl 101 | eventEl.onchange = (e) => { 102 | var value = this.getValue(directiveEl) 103 | validate(directiveEl, value) 104 | } 105 | }, 106 | getValue(directiveEl) { 107 | var eventEl = directiveEl.eventEl_ || directiveEl 108 | var multiple = eventEl.getAttribute('multiple') 109 | var optionEls = eventEl.querySelectorAll('option') 110 | var value = !multiple ? '' : [] 111 | for (var i = 0; i < optionEls.length; i++) { 112 | if (optionEls[i].selected) { 113 | if (value === '') { 114 | value = optionEls[i].value 115 | break 116 | } else { 117 | value.push(optionEls[i].value) 118 | } 119 | } 120 | } 121 | return value 122 | }, 123 | resetValue(directiveEl) { 124 | var eventEl = directiveEl.eventEl_ || directiveEl 125 | eventEl.value = '' 126 | var multiple = eventEl.getAttribute('multiple') 127 | if (!multiple) eventEl.querySelector('option').selected = true // 单选重置后默认选择第一个值 128 | } 129 | }, 130 | custom: { // 自定义元素 131 | condition(directiveEl) { 132 | return directiveEl.type_ == 'custom' 133 | }, 134 | bindEvent(directiveEl) { 135 | directiveEl.bindEvent(validate) 136 | }, 137 | getValue(directiveEl) { 138 | return directiveEl.getValue() 139 | }, 140 | resetValue(directiveEl) { 141 | directiveEl.reset() 142 | } 143 | }, 144 | } 145 | 146 | export default { 147 | bindEvent(directiveEl, binding) { 148 | var eles = Object.keys(formElements) 149 | for (var i = 0; i < eles.length; i++) { 150 | if (formElements[eles[i]].condition(directiveEl)) { 151 | formElements[eles[i]].bindEvent(directiveEl, binding) 152 | return 153 | } 154 | } 155 | }, 156 | 157 | resetSingleValue(directiveEl) { 158 | 159 | var formElementsKeys = Object.keys(formElements) 160 | for (var j = 0; j < formElementsKeys.length; j++) { 161 | if (formElements[formElementsKeys[j]].condition(directiveEl)) { // 符合条件的元素进行清除 162 | formElements[formElementsKeys[j]].resetValue(directiveEl) 163 | break 164 | } 165 | } 166 | }, 167 | resetValue(scope) { 168 | var els = document.querySelectorAll(`[data-scope=${scope}]`) 169 | for (var i = 0; i < els.length; i++) { 170 | this.resetSingleValue(els[i]) 171 | } 172 | }, 173 | getValue(directiveEl) { 174 | var formElementsKeys = Object.keys(formElements) 175 | for (var i = 0; i < formElementsKeys.length; i++) { 176 | if (formElements[formElementsKeys[i]].condition(directiveEl)) { // 符合条件的元素进行清除 177 | return formElements[formElementsKeys[i]].getValue(directiveEl) 178 | } 179 | } 180 | }, 181 | } 182 | -------------------------------------------------------------------------------- /src/vue-validate-easy/index.js: -------------------------------------------------------------------------------- 1 | 2 | import validate from './validate' 3 | import validateAll from './validateAll' 4 | import validatorStore from './validatorStore' 5 | import errTip from './errTip' 6 | 7 | import formElements from './formElements' 8 | 9 | var vueValidateEasy = {} 10 | vueValidateEasy.install = function (Vue, options) { 11 | // 批量加载验证方法 12 | if (options && options.validators) { 13 | for (name in options.validators) { 14 | validatorStore.addValidator(name, options.validators[name]) 15 | } 16 | } 17 | 18 | Vue.directive('validate-easy', { 19 | inserted(directiveEl, binding, vnode) { 20 | // 判断v-validate-easy data-scope data-name data-type 21 | 22 | 23 | var scope = directiveEl.getAttribute('data-scope') 24 | var name = directiveEl.getAttribute('data-name') 25 | var type = directiveEl.getAttribute('data-type') 26 | 27 | // 参数的检测,报错提醒 28 | if (!scope || !name || !type) { 29 | console.log('错误元素:', directiveEl) 30 | } 31 | if (!scope) throw '使用v-validate-easy指令的元素缺少必要属性data-scope' 32 | if (!name) throw '使用v-validate-easy指令的元素缺少必要属性data-name' 33 | if (!type) throw '使用v-validate-easy指令的元素缺少必要属性data-type' 34 | 35 | if (binding.value) { 36 | if (!(binding.value instanceof Array)) { 37 | console.log('错误元素:', directiveEl) 38 | throw '使用v-validate-easy指令的值应是一个数组' 39 | } 40 | 41 | binding.value.forEach(validator => { 42 | if (!(validator instanceof Array)) { 43 | console.log('错误元素:', directiveEl) 44 | throw '使用v-validate-easy指令值的子元素应是一个数组' 45 | } 46 | if (!validator[0]) { 47 | console.log('错误元素:', directiveEl) 48 | throw '使用v-validate-easy指令值中验证方法名不能缺失' 49 | } 50 | }) 51 | } 52 | 53 | 54 | // 当指令元素被从Dom中移除时,这些同时会被销毁,不占用内存 55 | directiveEl.scope_ = scope 56 | directiveEl.name_ = name 57 | directiveEl.type_ = type 58 | 59 | // 无需验证参数,使用该指令只是为了提取值 60 | directiveEl.binding = binding 61 | if (!binding.value) return 62 | 63 | 64 | // 绑定事件触发验证 65 | formElements.bindEvent(directiveEl) 66 | 67 | } 68 | }) 69 | Vue.prototype.V = {} 70 | 71 | Vue.prototype.V.$validateSingle = async function (directiveEl, value) { 72 | return await validate(directiveEl, value) 73 | } 74 | Vue.prototype.V.$validateAll = async function (scope) { 75 | return await validateAll(scope) 76 | } 77 | Vue.prototype.V.$submit = async function (scope, cb) { 78 | var { canSumit, data, errData } = await validateAll(scope) 79 | cb && cb(canSumit, data, errData) 80 | } 81 | Vue.prototype.V.$reset = function (scope) { 82 | errTip.resetErrorTip(scope) 83 | formElements.resetValue(scope) 84 | }, 85 | 86 | Vue.prototype.V.$resetSingle = function (directiveEl) { 87 | 88 | errTip.resetSingleErrorTip(directiveEl) 89 | formElements.resetSingleValue(directiveEl) 90 | }, 91 | /** 92 | * 新增验证方法 93 | * 94 | * @param {String|Object} param 95 | * String类型时,为方法名,此时第二个参数是必须的 96 | * Object类型时,为批量新增验证方法,此时第二参数不需要传 97 | * @param {function} validator 98 | */ 99 | Vue.prototype.V.$addValidateMethod = function (param, validator) { 100 | if ((typeof param).toLowerCase() == 'object') { // name代表合并一个对象 {a(){},b(){}} 101 | for (name in param) { 102 | validatorStore.addValidator(name, param[name]) 103 | } 104 | } else { 105 | validatorStore.addValidator(param, validator) 106 | } 107 | } 108 | 109 | Vue.prototype.V.$addErrorOption = function (errOptionName, option) { // {show,remove} 110 | errTip.addErrorOption(errOptionName, option) 111 | } 112 | } 113 | export default vueValidateEasy 114 | -------------------------------------------------------------------------------- /src/vue-validate-easy/validate.js: -------------------------------------------------------------------------------- 1 | // validate function 2 | import validatorStore from './validatorStore' 3 | import errTip from './errTip' 4 | import formElements from './formElements' 5 | 6 | /** 7 | * 验证表单值方法 8 | * 9 | * @param {any} directiveEl 指令元素 10 | * @param {String} value 表单元素的值 11 | * 12 | * @return {err,value} err true说明验证错误,value为表单的值 13 | */ 14 | export default async function (directiveEl, value) { 15 | 16 | var err, errContent 17 | 18 | value = value ? value : formElements.getValue(directiveEl) 19 | 20 | 21 | var key = directiveEl.getAttribute('data-name') 22 | var validator = directiveEl.binding.value 23 | 24 | if (validator[0][0] != 'required') { 25 | if (validatorStore.getValidator('required')(value)) { 26 | return { err: false, value } 27 | } 28 | } 29 | 30 | for (var i = 0; i < validator.length; i++) { 31 | // 参数解析 32 | var validatorName = validator[i][0] // 当前验证方法 33 | var secondItem = validator[i][1] 34 | var args = [] 35 | var errMsg // 当前验证的参数,错误消息 36 | if (secondItem instanceof Array) { 37 | args = secondItem 38 | errMsg = validator[i][2] 39 | } else { 40 | errMsg = validator[i][1] 41 | } 42 | // 验证失败 43 | var validateFn = validatorStore.getValidator(validatorName) 44 | var validateResult = await validateFn(value, ...args) 45 | 46 | if (validateResult) { 47 | err = true 48 | errContent = errMsg || errMsg === '' ? errMsg : validateResult 49 | break 50 | } 51 | 52 | } 53 | 54 | var errOptionName = directiveEl.getAttribute('data-error-option') 55 | var errOption = errTip.getErrorOption(errOptionName ? errOptionName : 'default') 56 | 57 | if (!errOption) throw `没有这个名为${errOptionName}错误处理(data-error-option)方法` 58 | errOption.show(err, directiveEl, errContent) 59 | 60 | return { err, value } // 验证通过返回value值 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/vue-validate-easy/validateAll.js: -------------------------------------------------------------------------------- 1 | import validate from './validate' 2 | import formElements from './formElements'; 3 | 4 | export default async function (scope) { 5 | var canSumit = true // 是否验证通过 6 | var data = {} 7 | var errData = null 8 | var scopeInputs = document.querySelectorAll(`[data-scope=${scope}]`) 9 | if (scopeInputs.length == 0) throw `该scope(${scope})对应的表单不存在` 10 | 11 | for (let i = 0; i < scopeInputs.length; i++) { 12 | var key = scopeInputs[i].name_ 13 | var validationParams = scopeInputs[i].binding.value 14 | 15 | // 只有指令参数的值才会被进行验证,否者只是提取值表单值进行提交 16 | if(validationParams) { 17 | var { err, value } = await validate(scopeInputs[i]) 18 | }else{ 19 | // 无需验证,直接取值 20 | var value = formElements.getValue(scopeInputs[i]) 21 | } 22 | data[key] = value 23 | if (err) { 24 | // 验证通过返回 value 25 | canSumit = false 26 | if (!errData) errData = {} 27 | errData[key] = value 28 | } 29 | } 30 | return { canSumit, data, errData } 31 | } 32 | -------------------------------------------------------------------------------- /src/vue-validate-easy/validatorStore.js: -------------------------------------------------------------------------------- 1 | var validatorStore = { 2 | // 验证方法 3 | required(val) { 4 | if (JSON.stringify(val) == "[]" || (!val && val !== 0)) return '必填项不能为空' 5 | }, 6 | maxLength(val, len) { 7 | if (val.length > len) return '长度不得超过' + len + '位' 8 | }, 9 | minLength(val, len) { 10 | if (val.length < len) return '长度不得小于' + len + '位' 11 | }, 12 | between(val, min, max) { 13 | if (val.length < min || val.length > max) return `输入长度必须在${min}位和${max}位之间` 14 | }, 15 | equalTo(val, selector) { // 可以是目标input元素,或者指令元素 16 | var targetEl = document.querySelector(selector) 17 | var tagName = targetEl.tagName.toLocaleLowerCase() 18 | targetEl = tagName == 'input' ? targetEl : targetEl.querySelector('input') 19 | if (val != targetEl.value) return '与目标值不一致' 20 | }, 21 | length(val, len) { 22 | if (len != val.length) return `长度必须为${len}位` 23 | }, 24 | email(val) { 25 | var p = /^([\w\.\-]+)@([\w\.\-]+)\.([\w]{2,4})$/ 26 | if (!p.test(val)) return '邮箱格式不正确' 27 | }, 28 | number(val) { 29 | if (!/^\d+$/.test(val)) return '必须为数字' 30 | } 31 | } 32 | 33 | export default { 34 | getValidator(name) { 35 | if (!validatorStore[name]) throw `没有名${name}的验证方法` 36 | return validatorStore[name] 37 | }, 38 | addValidator(name, validator) { 39 | validatorStore[name] = validator 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfyfly/vue-validate-easy/3e57b1237ac4432cb79ac685a7269a3eac3fd888/static/.gitkeep -------------------------------------------------------------------------------- /t.js: -------------------------------------------------------------------------------- 1 | var test = require('./test') 2 | test.t() 3 | test.t1= function(){ 4 | console.log(this.a) 5 | } 6 | test.t1() 7 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
身份(单选列表)
18 |
19 |
爱吃的(多选列表)
20 |
21 |
22 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var a=1 2 | module.exports ={ 3 | a:222, 4 | t(){ 5 | console.log(a) 6 | } 7 | } 8 | --------------------------------------------------------------------------------