Browse Source

第三次

master
xiezhenghui 4 years ago
commit
d5d39f61cc

+ 12
- 0
.babelrc View File

@@ -0,0 +1,12 @@
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
+}

+ 9
- 0
.editorconfig View File

@@ -0,0 +1,9 @@
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

+ 14
- 0
.gitignore View File

@@ -0,0 +1,14 @@
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

+ 10
- 0
.postcssrc.js View File

@@ -0,0 +1,10 @@
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
+  }
10
+}

+ 21
- 0
README.md View File

@@ -0,0 +1,21 @@
1
+# mydemo
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).

+ 41
- 0
build/build.js View File

@@ -0,0 +1,41 @@
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
+})

+ 54
- 0
build/check-versions.js View File

@@ -0,0 +1,54 @@
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
+}

BIN
build/logo.png View File


+ 101
- 0
build/utils.js View File

@@ -0,0 +1,101 @@
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
+}

+ 22
- 0
build/vue-loader.conf.js View File

@@ -0,0 +1,22 @@
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
+}

+ 86
- 0
build/webpack.base.conf.js View File

@@ -0,0 +1,86 @@
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: /\.less$/,
36
+        loader: 'style-loader!css-loader!less-loader'
37
+      },
38
+      {
39
+        test: /\.vue$/,
40
+        loader: 'vue-loader',
41
+        options: vueLoaderConfig
42
+      },
43
+      {
44
+        test: /\.js$/,
45
+        loader: 'babel-loader',
46
+        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
47
+      },
48
+      {
49
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
50
+        loader: 'url-loader',
51
+        options: {
52
+          limit: 10000,
53
+          name: utils.assetsPath('img/[name].[hash:7].[ext]')
54
+        }
55
+      },
56
+      {
57
+        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
58
+        loader: 'url-loader',
59
+        options: {
60
+          limit: 10000,
61
+          name: utils.assetsPath('media/[name].[hash:7].[ext]')
62
+        }
63
+      },
64
+      {
65
+        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
66
+        loader: 'url-loader',
67
+        options: {
68
+          limit: 10000,
69
+          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
70
+        }
71
+      }
72
+    ]
73
+  },
74
+  node: {
75
+    // prevent webpack from injecting useless setImmediate polyfill because Vue
76
+    // source contains it (although only uses it if it's native).
77
+    setImmediate: false,
78
+    // prevent webpack from injecting mocks to Node native modules
79
+    // that does not make sense for the client
80
+    dgram: 'empty',
81
+    fs: 'empty',
82
+    net: 'empty',
83
+    tls: 'empty',
84
+    child_process: 'empty'
85
+  }
86
+}

+ 95
- 0
build/webpack.dev.conf.js View File

@@ -0,0 +1,95 @@
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
+})

+ 145
- 0
build/webpack.prod.conf.js View File

@@ -0,0 +1,145 @@
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

+ 7
- 0
config/dev.env.js View File

@@ -0,0 +1,7 @@
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
+})

+ 69
- 0
config/index.js View File

@@ -0,0 +1,69 @@
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
+
15
+    // Various Dev Server settings
16
+    host: 'localhost', // can be overwritten by process.env.HOST
17
+    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18
+    autoOpenBrowser: false,
19
+    errorOverlay: true,
20
+    notifyOnErrors: true,
21
+    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22
+
23
+    
24
+    /**
25
+     * Source Maps
26
+     */
27
+
28
+    // https://webpack.js.org/configuration/devtool/#development
29
+    devtool: 'cheap-module-eval-source-map',
30
+
31
+    // If you have problems debugging vue-files in devtools,
32
+    // set this to false - it *may* help
33
+    // https://vue-loader.vuejs.org/en/options.html#cachebusting
34
+    cacheBusting: true,
35
+
36
+    cssSourceMap: true
37
+  },
38
+
39
+  build: {
40
+    // Template for index.html
41
+    index: path.resolve(__dirname, '../dist/index.html'),
42
+
43
+    // Paths
44
+    assetsRoot: path.resolve(__dirname, '../dist'),
45
+    assetsSubDirectory: 'static',
46
+    assetsPublicPath: '/',
47
+
48
+    /**
49
+     * Source Maps
50
+     */
51
+
52
+    productionSourceMap: true,
53
+    // https://webpack.js.org/configuration/devtool/#production
54
+    devtool: '#source-map',
55
+
56
+    // Gzip off by default as many popular static hosts such as
57
+    // Surge or Netlify already gzip all static assets for you.
58
+    // Before setting to `true`, make sure to:
59
+    // npm install --save-dev compression-webpack-plugin
60
+    productionGzip: false,
61
+    productionGzipExtensions: ['js', 'css'],
62
+
63
+    // Run the build command with an extra argument to
64
+    // View the bundle analyzer report after build finishes:
65
+    // `npm run build --report`
66
+    // Set to `true` or `false` to always turn it on or off
67
+    bundleAnalyzerReport: process.env.npm_config_report
68
+  }
69
+}

+ 4
- 0
config/prod.env.js View File

@@ -0,0 +1,4 @@
1
+'use strict'
2
+module.exports = {
3
+  NODE_ENV: '"production"'
4
+}

+ 12
- 0
index.html View File

@@ -0,0 +1,12 @@
1
+<!DOCTYPE html>
2
+<html>
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
6
+    <title>mydemo</title>
7
+  </head>
8
+  <body>
9
+    <div id="app"></div>
10
+    <!-- built files will be auto injected -->
11
+  </body>
12
+</html>

+ 12318
- 0
package-lock.json
File diff suppressed because it is too large
View File


+ 65
- 0
package.json View File

@@ -0,0 +1,65 @@
1
+{
2
+  "name": "mydemo",
3
+  "version": "1.0.0",
4
+  "description": "A Vue.js project",
5
+  "author": "lipenghui <1040605621@qq.com>",
6
+  "private": true,
7
+  "scripts": {
8
+    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9
+    "start": "npm run dev",
10
+    "build": "node build/build.js"
11
+  },
12
+  "dependencies": {
13
+    "less": "^3.9.0",
14
+    "less-loader": "^5.0.0",
15
+    "view-design": "^4.2.0",
16
+    "vue": "^2.5.2",
17
+    "vue-router": "^3.0.1"
18
+  },
19
+  "devDependencies": {
20
+    "autoprefixer": "^7.1.2",
21
+    "babel-core": "^6.22.1",
22
+    "babel-helper-vue-jsx-merge-props": "^2.0.3",
23
+    "babel-loader": "^7.1.1",
24
+    "babel-plugin-syntax-jsx": "^6.18.0",
25
+    "babel-plugin-transform-runtime": "^6.22.0",
26
+    "babel-plugin-transform-vue-jsx": "^3.5.0",
27
+    "babel-preset-env": "^1.3.2",
28
+    "babel-preset-stage-2": "^6.22.0",
29
+    "chalk": "^2.0.1",
30
+    "copy-webpack-plugin": "^4.0.1",
31
+    "css-loader": "^0.28.0",
32
+    "extract-text-webpack-plugin": "^3.0.0",
33
+    "file-loader": "^1.1.4",
34
+    "friendly-errors-webpack-plugin": "^1.6.1",
35
+    "html-webpack-plugin": "^2.30.1",
36
+    "node-notifier": "^5.1.2",
37
+    "optimize-css-assets-webpack-plugin": "^3.2.0",
38
+    "ora": "^1.2.0",
39
+    "portfinder": "^1.0.13",
40
+    "postcss-import": "^11.0.0",
41
+    "postcss-loader": "^2.0.8",
42
+    "postcss-url": "^7.2.1",
43
+    "rimraf": "^2.6.0",
44
+    "semver": "^5.3.0",
45
+    "shelljs": "^0.7.6",
46
+    "uglifyjs-webpack-plugin": "^1.1.1",
47
+    "url-loader": "^0.5.8",
48
+    "vue-loader": "^13.3.0",
49
+    "vue-style-loader": "^3.0.1",
50
+    "vue-template-compiler": "^2.5.2",
51
+    "webpack": "^3.6.0",
52
+    "webpack-bundle-analyzer": "^2.9.0",
53
+    "webpack-dev-server": "^2.9.1",
54
+    "webpack-merge": "^4.1.0"
55
+  },
56
+  "engines": {
57
+    "node": ">= 6.0.0",
58
+    "npm": ">= 3.0.0"
59
+  },
60
+  "browserslist": [
61
+    "> 1%",
62
+    "last 2 versions",
63
+    "not ie <= 8"
64
+  ]
65
+}

+ 26
- 0
src/App.vue View File

@@ -0,0 +1,26 @@
1
+<template>
2
+  <div id="app">
3
+    <!-- <router-view/> -->
4
+    <home/>
5
+  </div>
6
+</template>
7
+
8
+<script>
9
+import home from "./views/home"
10
+export default {
11
+  name: 'App',
12
+  components: {
13
+    "home":home
14
+  }
15
+}
16
+</script>
17
+
18
+<style>
19
+#app {
20
+  font-family: 'Avenir', Helvetica, Arial, sans-serif;
21
+  -webkit-font-smoothing: antialiased;
22
+  -moz-osx-font-smoothing: grayscale;
23
+  text-align: center;
24
+  color: #2c3e50;
25
+}
26
+</style>

BIN
src/assets/Key.png View File


BIN
src/assets/User.png View File


BIN
src/assets/avatar.jpeg View File


BIN
src/assets/login-background.png View File


BIN
src/assets/logo copy.png View File


BIN
src/assets/logo.png View File


BIN
src/assets/native.png View File


BIN
src/assets/radius.png View File


BIN
src/assets/renw.png View File


BIN
src/assets/toux.png View File


BIN
src/assets/want-key-active.png View File


BIN
src/assets/want-key.png View File


+ 68
- 0
src/components/home/topNative.vue View File

@@ -0,0 +1,68 @@
1
+<template>
2
+    <div class="layout">
3
+        <div class="layout-ceiling">
4
+            <div class="layout-left">显现英语</div>
5
+            <div class="layout-ceiling-main">
6
+                <div class="user-nav">
7
+                    <img src="../../assets/avatar.jpeg" class="user-avatar">
8
+                    <Tooltip placement="bottom">
9
+                        <a href="#">SHAW-小岩</a>
10
+                         <div slot="content">
11
+                            <p>显示多行信息</p>
12
+                            <p><i>可以自定义样式</i></p>
13
+                        </div>
14
+                    </Tooltip> |
15
+                    <a href="#">退出</a>
16
+                 </div>
17
+            </div>
18
+        </div>
19
+    </div>
20
+</template>
21
+<script>
22
+export default {
23
+    name:"topNative"
24
+}
25
+</script>
26
+<style scoped>
27
+    .layout[data-v-7eb2bc79]{
28
+        border:none;
29
+        border-radius: 0;
30
+    }
31
+    .layout{
32
+        background: #f5f7f9;
33
+        position: relative;
34
+    }
35
+    .layout-ceiling{
36
+        background-image: url("../../assets/native.png");
37
+        background-size: 211px 100%;
38
+        background-color: #3D8EFE;
39
+        padding: 10px 26px;
40
+        background-repeat: no-repeat;
41
+        overflow: hidden;
42
+    }
43
+    .layout-left{
44
+        float: left;
45
+        font-size: 19px;
46
+        color:#ffffff;
47
+        margin: 4px 222px;
48
+    }
49
+    .layout-ceiling-main{
50
+        float: right;
51
+        color: #ffffff;
52
+    }
53
+    .layout-ceiling-main a{
54
+        color: #ffffff;
55
+        margin:0 10px;
56
+        font-size: 12px;
57
+    }
58
+    .user-avatar{
59
+        width: 36px;
60
+        height: 36px;
61
+        border-radius: 50%;
62
+    }
63
+    .user-nav{
64
+        display: flex;
65
+        justify-content: center;
66
+        align-items: center;
67
+    }
68
+</style>

+ 18
- 0
src/main.js View File

@@ -0,0 +1,18 @@
1
+import Vue from 'vue';
2
+import App from './App';
3
+import router from './router';
4
+import ViewUI from 'view-design';
5
+import 'view-design/dist/styles/iview.css';
6
+
7
+
8
+Vue.use(ViewUI);
9
+
10
+Vue.config.productionTip = false
11
+
12
+/* eslint-disable no-new */
13
+new Vue({
14
+  el: '#app',
15
+  router,
16
+  components: { App },
17
+  template: '<App/>'
18
+})

+ 34
- 0
src/router/index.js View File

@@ -0,0 +1,34 @@
1
+import Vue from 'vue'
2
+import Router from 'vue-router'
3
+// import home from '@/views/home'
4
+import firstPage from "@/views/home/firstPage"
5
+import news from '@/views/home/news'
6
+import student from '@/views/home/student'
7
+import login from '@/views/login/login'
8
+
9
+Vue.use(Router)
10
+
11
+export default new Router({
12
+  routes: [
13
+    {
14
+      path: '/',
15
+      name: 'firstPage',
16
+      component: firstPage
17
+    },
18
+    {
19
+      path: '/news',
20
+      name: 'news',
21
+      component: news
22
+    },
23
+    {
24
+      path: '/student',
25
+      name: 'student',
26
+      component: student
27
+    },
28
+    {
29
+      path: '/login',
30
+      name: 'login',
31
+      component: login
32
+    }
33
+  ]
34
+})

+ 87
- 0
src/views/home.vue View File

@@ -0,0 +1,87 @@
1
+<template>
2
+    <div class="layout">
3
+        <Layout>
4
+            <top-native></top-native>
5
+            <Layout>
6
+                <Sider hide-trigger :style="{background: '#fff'}">
7
+                    <Menu active-name="1-2" theme="light" width="auto" :open-names="['1']">
8
+                        <Submenu name="1">
9
+                            <template slot="title">
10
+                                <Icon type="ios-navigate"></Icon>
11
+                                <router-link to="/">首页</router-link>
12
+                            </template>
13
+                            <!-- 路由渲染部分 -->
14
+                            
15
+                        </Submenu>
16
+                        <Submenu name="2">
17
+                            <template slot="title">
18
+                                <Icon type="ios-keypad"></Icon>
19
+                                基本信息
20
+                            </template>
21
+                            <MenuItem name="2-1" to="/news">
22
+                              news
23
+                            </MenuItem>
24
+                            <MenuItem name="2-2" to="/student">
25
+                              student
26
+                            </MenuItem>
27
+                        </Submenu>
28
+                    </Menu>
29
+                </Sider>
30
+                <Layout :style="{padding: '0 24px 24px'}">
31
+                    <Breadcrumb :style="{margin: '24px 0'}">
32
+                        <BreadcrumbItem>Home</BreadcrumbItem>
33
+                        <BreadcrumbItem>Components</BreadcrumbItem>
34
+                        <BreadcrumbItem>Layout</BreadcrumbItem>
35
+                    </Breadcrumb>
36
+                    <Content :style="{padding: '24px', minHeight: '280px', background: '#fff'}">
37
+                        <!-- 添加 -->
38
+                        <router-view>
39
+                          <!-- 内容渲染在这里 -->
40
+                        </router-view>
41
+                    </Content>
42
+                </Layout>
43
+            </Layout>
44
+        </Layout>
45
+    </div>
46
+</template>
47
+<script>
48
+    import topNative from "../components/home/topNative"
49
+    import student from "../views/home/student"
50
+    import news from "../views/home/news"
51
+    export default {
52
+        components:{
53
+            "topNative":topNative
54
+        }
55
+    }
56
+</script>
57
+<style scoped>
58
+.layout[data-v-7eb2bc79]{
59
+    border:none;
60
+    border-radius: 0;
61
+}
62
+.layout{
63
+    border: 1px solid #d7dde4;
64
+    background: #f5f7f9;
65
+    position: relative;
66
+    border-radius: 4px;
67
+    overflow: hidden;
68
+}
69
+.layout-logo{
70
+    width: 100px;
71
+    height: 30px;
72
+    background: #5b6270;
73
+    border-radius: 3px;
74
+    float: left;
75
+    position: relative;
76
+    top: 15px;
77
+    left: 20px;
78
+}
79
+.layout-nav{
80
+    width: 420px;
81
+    margin: 0 auto;
82
+    margin-right: 20px;
83
+}
84
+.ivu-breadcrumb{
85
+    text-align: left;
86
+}
87
+</style>

+ 301
- 0
src/views/home/firstPage.vue View File

@@ -0,0 +1,301 @@
1
+<template>
2
+    <div class="index">
3
+        <!-- 顶部搜索栏 start -->
4
+        <div style="text-align:left">
5
+            <DatePicker format="yyyy-MM-dd" type="date" placeholder="Select date" style="width: 200px"></DatePicker>
6
+            <Button type="primary" icon="ios-search">
7
+                <span>搜索</span>
8
+            </Button>
9
+        </div>
10
+        <!-- 顶部搜索栏 end -->
11
+        <!-- 学生考勤栏 start -->
12
+        <div class="index-title">
13
+            <span class="index-text">学生考勤</span>
14
+            <span class="index-details">详情</span>
15
+        </div>
16
+        <div class="index-work">
17
+            <i-Circle
18
+                :size="300"
19
+                :trail-width="15"
20
+                :stroke-width="15"
21
+                :percent="75"
22
+                stroke-linecap="square"
23
+                stroke-color="#43a3fb">
24
+                <div class="demo-Circle-custom">
25
+                    <h1>86%</h1>
26
+                    <p>
27
+                        学生实到率
28
+                    </p>
29
+                </div>
30
+            </i-Circle>
31
+            <div class="work-total">
32
+                <div class="work-total-div">
33
+                    <span class="work-total-title">应到学生</span>
34
+                    <span class="work-total-num">775</span>
35
+                </div>
36
+                <div class="work-total-div">
37
+                    <span class="work-total-title">实到学生</span>
38
+                    <span class="work-total-num">705</span>
39
+                </div>
40
+            </div>
41
+            <div class="workList-card">
42
+                <Row type="flex" align="middle">
43
+                    <Col span="8" v-for="(work,index) in workList" :key="index" shadow="true">
44
+                        <div class="workList-text-div workList-text">
45
+                            <span class="workList-title">{{work.title}}</span>
46
+                            <span class="workList-num" :class="{'workList-num-err':index==1||index==5}">{{work.num}}</span>
47
+                        </div>
48
+                    </Col>
49
+                </Row>
50
+            </div>
51
+        </div>
52
+        <!-- 学生考勤栏 end -->
53
+        <!-- 老师课耗栏 star -->
54
+        <div>
55
+           <div class="index-title">
56
+                <span class="index-text">老师课耗</span>
57
+                <span class="index-details">详情</span>
58
+            </div> 
59
+        </div>
60
+        <Row class="add-padding">
61
+            <Col span="11">
62
+                <div>
63
+                    <i-Circle 
64
+                        :size="240"
65
+                        :trail-width="4"
66
+                        :stroke-width="6"
67
+                        :percent="19"
68
+                        stroke-color="#7DDFC9">
69
+                        <span class="demo-Circle-inner">40<span>人</span></span>
70
+                    </i-Circle>
71
+                    <div class="teacher-num">
72
+                        上课教师数量
73
+                    </div>
74
+                </div>
75
+            </Col>
76
+            <Col span="2"><div class="line"></div></Col>
77
+            <Col span="11">
78
+                <div>
79
+                    <i-Circle 
80
+                        :size="240"
81
+                        :trail-width="4"
82
+                        :stroke-width="6"
83
+                        :percent="19">
84
+                        <span class="demo-Circle-inner blue">73<span>节</span></span>
85
+                    </i-Circle>
86
+                    <div class="teacher-num">
87
+                        教师上课教课时
88
+                    </div>
89
+                </div>
90
+            </Col>
91
+        </Row>
92
+        <!-- 缴费情况栏 start -->
93
+        <div class="index-title">
94
+            <span class="index-text">应缴费用情况</span>
95
+            <span class="index-details">详情</span>
96
+        </div>
97
+       <Row class="add-padding">
98
+            <Col v-for="(cost,i) in costList" :key="i" :span="24/costList.length">
99
+                <div class="cost-pirce">
100
+                    <sup class="sign">¥</sup>{{cost.price}}
101
+                </div>
102
+                <div class="teacher-num">
103
+                    {{cost.title}}
104
+                </div>
105
+                <div class="cost-carl-div" :class="{'cost-carl-div-flex':cost.length>1}">
106
+                    <div v-for="(list,ind) in cost.list" :key="ind" class="cost-carl">
107
+                        <img :src="ind==1?require('../../assets/renw.png'):require('../../assets/toux.png')" class="cost-avatar">
108
+                        <div>
109
+                            <div class="cost-num">{{list.num}}</div>
110
+                            <div class="cost-title">{{list.title}}</div>
111
+                        </div>
112
+                    </div>
113
+                </div>
114
+            </Col>
115
+        </Row>
116
+    </div>
117
+</template>
118
+<script>
119
+export default {
120
+    data(){
121
+        return {
122
+            workList:[
123
+                {"title":"请假","num":2},
124
+                {"title":"旷课","num":1},
125
+                {"title":"停课","num":7},
126
+                {"title":"退费","num":3},
127
+                {"title":"转学","num":0},
128
+                {"title":"流失","num":2},
129
+            ],
130
+            costList:[
131
+                {
132
+                    "title":"缴费总金额",
133
+                    "price":"13600.00",
134
+                    "list":[
135
+                        {"title":"新学员人数","num":"38"},
136
+                        {"title":"缴费学生人数","num":"60"}
137
+                    ]
138
+                },
139
+                {
140
+                    "title":"退费总金额",
141
+                    "price":"3600.00",
142
+                    "list":[
143
+                        {"title":"新学员人数","num":"38"}
144
+                    ]
145
+                }
146
+            ]
147
+        }
148
+    }
149
+}
150
+</script>
151
+<style scoped lang="less">
152
+.index{
153
+    color: #000000;
154
+    .ivu-btn{
155
+        padding: 0 3px;
156
+    }
157
+    .index-title{
158
+        display: flex;
159
+        justify-content: space-between;
160
+        align-items: center;
161
+        border-bottom:1px solid #EFEFEF;
162
+        margin-top: 34px;
163
+        .index-text{
164
+            font-size: 26px;
165
+            padding: 8px 0;
166
+        }
167
+        .index-details{
168
+            font-size: 23px;
169
+            color: #3DA4FF;
170
+        }
171
+    }
172
+    .index-work{
173
+        padding:45px 39px 0 39px;
174
+        display: flex;
175
+        align-items: center;
176
+        justify-content: space-between;
177
+        .demo-Circle-custom{
178
+            & h1{
179
+                color: #4BCCEE;
180
+                font-size: 40px;
181
+            }
182
+            & p{
183
+                color: #657180;
184
+                font-size: 24px;
185
+                margin: 19px 0 15px;
186
+            }
187
+        }
188
+    }
189
+
190
+
191
+    .work-total{
192
+        .work-total-div{
193
+            padding: 20px 10px 20px 10px;
194
+            display: flex;
195
+            justify-content: center;
196
+            align-items: center;
197
+            .work-total-title{
198
+                font-size: 24px;
199
+                color: #657180;
200
+                margin-right: 16px;
201
+            }
202
+            .work-total-num{
203
+                font-size: 49px;
204
+                color: #4597FF;
205
+            }
206
+        }
207
+    }
208
+    .workList-card{
209
+        width: 787px;
210
+        height: 100%;
211
+        .workList-text-div{ 
212
+            display: flex;
213
+            justify-content: space-between;
214
+            align-items: center;
215
+            margin:0 0 36px 20px;
216
+            height: 120px;
217
+            border: 1px solid #D7D6DB;
218
+            border-radius: 5px;  
219
+            padding:38px 33px; 
220
+            box-shadow: 0px 0px 4px 2px #EBEBEB;        
221
+            .workList-title{
222
+                font-size: 30px;
223
+            }
224
+            .workList-num{
225
+                font-size: 45px;
226
+                color:#3DA4FF;
227
+            }
228
+            .workList-num-err{
229
+                color:#FF0000;
230
+            }
231
+        }
232
+    }
233
+
234
+    .demo-Circle-inner{
235
+        color: #7DDFC9;
236
+        font-size: 50px;
237
+        font-weight: bold;
238
+        & span{
239
+            color: #000000;
240
+            font-size: 43px;
241
+            font-weight: normal;
242
+        }
243
+    }
244
+    .blue{
245
+        color: #4A88F0;
246
+    }
247
+    .line{
248
+        height: 240px;
249
+        border-right: 1px solid #F4F4F5;
250
+        display: inline-block;
251
+        text-align: center;
252
+    }
253
+    .add-padding{
254
+        padding-top: 45px;
255
+        .teacher-num{
256
+            font-size: 30px;
257
+        }
258
+        .cost-pirce{
259
+            font-size: 56px;
260
+            color: #3DA4FF;
261
+            .sign{
262
+                font-size: 33px;
263
+                color: #000000;
264
+            }
265
+        }
266
+        .cost-carl-div-flex{
267
+            justify-content: space-between;
268
+        }
269
+        .cost-carl-div{
270
+            display: flex;
271
+            justify-content: center;
272
+            align-content: center;
273
+            width: 100%;
274
+            .cost-carl{
275
+                margin: 69px 16px 0;
276
+                width: 323px;
277
+                height: 141px;
278
+                border: 1px solid #D7D6DB;
279
+                border-radius: 5px;  
280
+                padding:38px 33px; 
281
+                box-shadow: 0px 0px 4px 2px #EBEBEB; 
282
+                display: flex;
283
+                align-items: center;
284
+                .cost-avatar{
285
+                    width: 43px;
286
+                    height: 49px;
287
+                    margin-right: 42px;
288
+                }
289
+                .cost-num{
290
+                    font-size: 36px;
291
+                    font-weight: 600;
292
+                    color: #FD753C;
293
+                }
294
+                .cost-title{
295
+                    font-size: 25px;
296
+                }
297
+            }
298
+        }
299
+    }
300
+}
301
+</style>

+ 71
- 0
src/views/home/newStudentAdmin.vue View File

@@ -0,0 +1,71 @@
1
+<template>
2
+    <i-table border :content="self" :columns="columns7" :data="data6"></i-table>
3
+</template>
4
+<script>
5
+    export default {
6
+        data () {
7
+            return {
8
+                self: this,
9
+                columns7: [
10
+                    {
11
+                        title: '姓名',
12
+                        key: 'name',
13
+                        render (row, column, index) {
14
+                            return `<Icon type="person"></Icon> <strong>${row.name}</strong>`;
15
+                        }
16
+                    },
17
+                    {
18
+                        title: '年龄',
19
+                        key: 'age'
20
+                    },
21
+                    {
22
+                        title: '地址',
23
+                        key: 'address'
24
+                    },
25
+                    {
26
+                        title: '操作',
27
+                        key: 'action',
28
+                        width: 150,
29
+                        align: 'center',
30
+                        render (row, column, index) {
31
+                            return `<i-button type="primary" size="small" @click="show(${index})">查看</i-button> <i-button type="error" size="small" @click="remove(${index})">删除</i-button>`;
32
+                        }
33
+                    }
34
+                ],
35
+                data6: [
36
+                    {
37
+                        name: '王小明',
38
+                        age: 18,
39
+                        address: '北京市朝阳区芍药居'
40
+                    },
41
+                    {
42
+                        name: '张小刚',
43
+                        age: 25,
44
+                        address: '北京市海淀区西二旗'
45
+                    },
46
+                    {
47
+                        name: '李小红',
48
+                        age: 30,
49
+                        address: '上海市浦东新区世纪大道'
50
+                    },
51
+                    {
52
+                        name: '周小伟',
53
+                        age: 26,
54
+                        address: '深圳市南山区深南大道'
55
+                    }
56
+                ]
57
+            }
58
+        },
59
+        methods: {
60
+            show (index) {
61
+                this.$Modal.info({
62
+                    title: '用户信息',
63
+                    content: `姓名:${this.data6[index].name}<br>年龄:${this.data6[index].age}<br>地址:${this.data6[index].address}`
64
+                })
65
+            },
66
+            remove (index) {
67
+                this.data6.splice(index, 1);
68
+            }
69
+        }
70
+    }
71
+</script>

+ 5
- 0
src/views/home/news.vue View File

@@ -0,0 +1,5 @@
1
+<template>
2
+    <div>
3
+        基本信息
4
+    </div>
5
+</template>

+ 178
- 0
src/views/home/student.vue View File

@@ -0,0 +1,178 @@
1
+<template>
2
+    <i-table border :content="self" :columns="columns" :data="data"></i-table>
3
+</template>
4
+<script>
5
+    export default {
6
+        data () {
7
+            return {
8
+                self: this,
9
+                columns: [
10
+                    {
11
+                        type:"index",
12
+                        title: '序号',
13
+                        align: 'center'
14
+                    },
15
+                    {
16
+                        title: '机构名字',
17
+                        key: 'orgar',
18
+                        align: 'center'
19
+                    },
20
+                    {
21
+                        title: '负责人',
22
+                        key: 'guarder',
23
+                        align: 'center'
24
+                    },
25
+                    {
26
+                        title: '负责人电话',
27
+                        key: 'phone',
28
+                        align: 'center'
29
+                    },
30
+                    {
31
+                        title: '地址',
32
+                        key: 'address',
33
+                        align: 'center'
34
+                    },
35
+                    {
36
+                        title: '教师数',
37
+                        key: 'teacher',
38
+                        align: 'center'
39
+                    },
40
+                    {
41
+                        title: '学生数',
42
+                        key: 'student',
43
+                        align: 'center'
44
+                    },
45
+                    {
46
+                      title: '操作',
47
+                      key: 'action',
48
+                      width: 180,
49
+                      align: 'center',
50
+                      render: (h, params) => {
51
+                        return h('div', [
52
+                          h('Button', {
53
+                            props: {
54
+                              type: 'text',
55
+                              size: 'small'
56
+                            },
57
+                            // style: {
58
+                            //   color: 'black'
59
+                            // },
60
+                            on: {
61
+                              click: () => {
62
+                                this.show(params.index)
63
+                              }
64
+                            }
65
+                          }, '编辑'),
66
+                          h('Button', {
67
+                            props: {
68
+                              type: 'text',
69
+                              size: 'small'
70
+                            },
71
+                            style: {
72
+                              color: '#3D8EFE'
73
+                            },
74
+                            on: {
75
+                              click: () => {
76
+                                this.show(params.index)
77
+                              }
78
+                            }
79
+                          }, '查看'),
80
+                          h('Button', {
81
+                            props: {
82
+                              type: 'text',
83
+                              size: 'small'
84
+                            },
85
+                            style: {
86
+                              color: '#FF3366'
87
+                            },
88
+                            on: {
89
+                              click: () => {
90
+                                this.show(params.index)
91
+                              }
92
+                            }
93
+                          }, '删除')
94
+                        ])
95
+                      }
96
+                    }
97
+                ],
98
+                data: [
99
+                    { 
100
+                        orgar:'郑州天琥培训机构',
101
+                        guarder: '宋老师',
102
+                        phone: 18888888888,
103
+                        address: '北京市朝阳区芍药居',
104
+                        teacher:60,
105
+                        student:120
106
+                    },
107
+                    { 
108
+                        orgar:'郑州天琥培训机构',
109
+                        guarder: '宋老师',
110
+                        phone: 18888888888,
111
+                        address: '北京市朝阳区芍药居',
112
+                        teacher:60,
113
+                        student:120
114
+                    },
115
+                    { 
116
+                        orgar:'郑州天琥培训机构',
117
+                        guarder: '宋老师',
118
+                        phone: 18888888888,
119
+                        address: '北京市朝阳区芍药居',
120
+                        teacher:60,
121
+                        student:120
122
+                    },
123
+                    { 
124
+                        orgar:'郑州天琥培训机构',
125
+                        guarder: '宋老师',
126
+                        phone: 18888888888,
127
+                        address: '北京市朝阳区芍药居',
128
+                        teacher:60,
129
+                        student:120
130
+                    },
131
+                    { 
132
+                        orgar:'郑州天琥培训机构',
133
+                        guarder: '宋老师',
134
+                        phone: 18888888888,
135
+                        address: '北京市朝阳区芍药居',
136
+                        teacher:60,
137
+                        student:120
138
+                    },
139
+                    { 
140
+                        orgar:'郑州天琥培训机构',
141
+                        guarder: '宋老师',
142
+                        phone: 18888888888,
143
+                        address: '北京市朝阳区芍药居',
144
+                        teacher:60,
145
+                        student:120
146
+                    },
147
+                    { 
148
+                        orgar:'郑州天琥培训机构',
149
+                        guarder: '宋老师',
150
+                        phone: 18888888888,
151
+                        address: '北京市朝阳区芍药居',
152
+                        teacher:60,
153
+                        student:120
154
+                    },
155
+                    { 
156
+                        orgar:'郑州天琥培训机构',
157
+                        guarder: '宋老师',
158
+                        phone: 18888888888,
159
+                        address: '北京市朝阳区芍药居',
160
+                        teacher:60,
161
+                        student:120
162
+                    }
163
+                ]
164
+            }
165
+        },
166
+        methods: {
167
+            show (index) {
168
+                this.$Modal.info({
169
+                    title: '用户信息',
170
+                    content: `负责人:${this.data[index].guarder}<br>年龄:${this.data[index].phone}<br>地址:${this.data[index].address}`
171
+                })
172
+            },
173
+            remove (index) {
174
+                this.data.splice(index, 1);
175
+            }
176
+        }
177
+    }
178
+</script>

+ 96
- 0
src/views/login/login.css View File

@@ -0,0 +1,96 @@
1
+input{
2
+    margin: 0;
3
+}
4
+.login{
5
+    width: 100%;
6
+    height: 100%;
7
+    position: fixed;
8
+    top:0; bottom: 0; right: 0; left: 0;
9
+    background-image: url("../../assets/login-background.png");
10
+    background-size: 100% 100%;
11
+    background-repeat: no-repeat;
12
+}
13
+.login-title{
14
+    margin-top: 149px;
15
+    font-weight: bold;
16
+    font-size: 23px;
17
+    color: #ffffff;
18
+}
19
+.login-text{
20
+    box-sizing: border-box;
21
+    margin: 14px auto;
22
+    width: 329px;
23
+    height: 300px;
24
+    background-image: url("../../assets/radius.png");
25
+    background-size: 100% 100%;
26
+    background-repeat: no-repeat;
27
+    display: flex;
28
+    flex-direction: column;
29
+    justify-content: center;
30
+    align-items: center;
31
+    padding: 51px 30px 36px;
32
+}
33
+.login-input{
34
+    box-sizing: border-box;
35
+    width: 270px;
36
+    height: 36px;
37
+    border:1px solid #dfdfdf;
38
+    margin-bottom: 14px;
39
+    padding: 12px 0px 12px 38px;
40
+    font-size: 12px;
41
+    color: #666666;
42
+    background-size: 18px 18px;
43
+    background-repeat: no-repeat;
44
+    background-position: 11px 8px;
45
+    font-weight: 400;
46
+}
47
+.user-log{
48
+    background-image: url("../../assets/User.png");
49
+}
50
+.key-log{
51
+    background-image: url("../../assets/Key.png");
52
+}
53
+.radio{
54
+    width: 100%;
55
+    display: flex;
56
+    justify-content: flex-start;
57
+    align-items: center;
58
+    margin: 6px 0 22px;
59
+    color:#666666;
60
+}
61
+.checkbox{
62
+    width: 18px;
63
+    height: 18px;
64
+    background-image: url("../../assets/want-key.png");
65
+    background-size: 100% 100%;
66
+    background-repeat: no-repeat;
67
+    margin-right: 4px;
68
+}
69
+.checkbox-active{
70
+    width: 12px;
71
+    height: 11px;
72
+    background-image: url("../../assets/want-key-active.png");
73
+    background-size: 100% 100%;
74
+    background-repeat: no-repeat;
75
+    margin: 3px;
76
+}
77
+.login-btn{
78
+    margin: 0 3px;
79
+    width: 100%;
80
+    height: 40px;
81
+    font-size: 17px;
82
+    background-color: #5B8DFD;
83
+    border:none;
84
+    outline: none;
85
+    border-radius: 2px;
86
+    color:#ffffff;
87
+    margin-bottom: 14px;
88
+}
89
+.login-register{
90
+    width: 100%;
91
+    display: flex;
92
+    justify-content: space-between;
93
+    align-items: center;
94
+    color:#789FFD;
95
+    font-size: 11px;
96
+}

+ 56
- 0
src/views/login/login.vue View File

@@ -0,0 +1,56 @@
1
+<template>
2
+<!-- 登陆页面背景图 -->
3
+  <div class="login">
4
+    <div class="login-title">欢迎,登陆青鸽管家!</div>
5
+    <!-- 登陆板块 -->
6
+    <div class="login-text">
7
+      <input type="text" placeholder="用户名" class="login-input user-log" v-model="user">
8
+      <input type="text" placeholder="密码" class="login-input key-log" v-model="passworld">
9
+      <div class="radio" @click="remembers">
10
+        <div class="checkbox">
11
+          <div class="checkbox-active" v-show="active"></div>
12
+        </div>
13
+        <div>记住密码</div>
14
+      </div>
15
+      <button class="login-btn" @click="login">登陆</button>
16
+      <div class="login-register">
17
+        <div>注册</div>
18
+        <div>忘记密码</div>
19
+      </div>
20
+    </div>
21
+  </div>
22
+</template>
23
+
24
+<script>
25
+export default {
26
+  name: 'login',
27
+  data () {
28
+    return {
29
+      user:"",  // 用户名
30
+      passworld:"",  // 用户密码
31
+      active:false
32
+    }
33
+  },
34
+  methods:{
35
+    login(){
36
+      if(!user){
37
+        return;
38
+      }
39
+      if(!passworld){
40
+        return;
41
+      }
42
+    },
43
+    // 判断是否选中记住密码
44
+    remembers(){
45
+      if(this.active==false){
46
+        this.active=true;
47
+      }else{
48
+        this.active=false;
49
+      }
50
+    }
51
+  }
52
+}
53
+</script>
54
+<style scoped>
55
+@import url(login.css);
56
+</style>

+ 0
- 0
static/.gitkeep View File


Loading…
Cancel
Save