├── .babelrc
├── .editorconfig
├── .gitignore
├── .postcssrc.js
├── .project
├── README.md
├── build
├── build.js
├── check-versions.js
├── logo.png
├── 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
├── index.html
├── manifest.json
├── package.json
├── postcss.config.js
├── src
├── App.vue
├── api
│ └── index.js
├── assets
│ ├── audio
│ │ ├── shake.wav
│ │ └── videoviewdemo.mp4
│ ├── css
│ │ ├── base.styl
│ │ ├── common.styl
│ │ ├── flex.styl
│ │ ├── iconfont.styl
│ │ ├── index.styl
│ │ ├── mint.css
│ │ ├── reset.styl
│ │ ├── transition.styl
│ │ └── variable.styl
│ ├── fonts
│ │ ├── iconfont.eot
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
│ ├── js
│ │ ├── mixins.js
│ │ ├── plusReady.js
│ │ ├── storageConst.js
│ │ ├── utils.js
│ │ └── vconsole.min.js
│ └── logo.png
├── components
│ ├── plus
│ │ ├── accelerometer
│ │ │ └── Accelerometer.vue
│ │ ├── camera
│ │ │ └── Camera.vue
│ │ ├── geolocation
│ │ │ └── Geolocation.vue
│ │ ├── payment
│ │ │ └── Payment.vue
│ │ ├── resumeCallback
│ │ │ └── ResumeCallback.vue
│ │ ├── router
│ │ │ ├── Router.vue
│ │ │ └── RouterChildren.vue
│ │ └── test
│ │ │ └── Test.vue
│ └── ui
│ │ ├── actionSheet
│ │ └── ActionSheet.vue
│ │ ├── badge
│ │ └── Badge.vue
│ │ ├── button
│ │ └── Button.vue
│ │ ├── cell
│ │ └── Cell.vue
│ │ ├── checklist
│ │ └── Checklist.vue
│ │ ├── datetimePicker
│ │ └── DatetimePicker.vue
│ │ ├── field
│ │ └── Field.vue
│ │ ├── header
│ │ └── Header.vue
│ │ ├── indexList
│ │ └── IndexList.vue
│ │ ├── indicator
│ │ └── Indicator.vue
│ │ ├── infiniteScroll
│ │ └── infiniteScroll.vue
│ │ ├── lazyLoad
│ │ └── LazyLoad.vue
│ │ ├── loadmore
│ │ └── Loadmore.vue
│ │ ├── messageBox
│ │ └── MessageBox.vue
│ │ ├── paletteButton
│ │ └── PaletteButton.vue
│ │ ├── picker
│ │ └── Picker.vue
│ │ ├── popup
│ │ └── Popup.vue
│ │ ├── progress
│ │ └── Progress.vue
│ │ ├── radio
│ │ └── Radio.vue
│ │ ├── range
│ │ └── Range.vue
│ │ ├── search
│ │ └── Search.vue
│ │ ├── spinner
│ │ └── Spinner.vue
│ │ ├── swipe
│ │ └── Swipe.vue
│ │ ├── switch
│ │ └── Switch.vue
│ │ └── toast
│ │ └── Toast.vue
├── main.js
├── page
│ ├── advertisement
│ │ └── Advertisement.vue
│ ├── index.vue
│ ├── indexTab
│ │ ├── IndexMine.vue
│ │ ├── IndexPlus.vue
│ │ └── IndexUi.vue
│ ├── login
│ │ └── Login.vue
│ ├── mine
│ │ └── mine.vue
│ └── slider
│ │ └── Slider.vue
└── router
│ ├── index.js
│ └── router.js
├── static
├── .gitkeep
├── QR
│ ├── weixin.png
│ └── zhifubao.png
└── media
│ └── shake.wav
└── unpackage
├── .confirmed_dependencies
└── .dependencies
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "env",
5 | {
6 | "modules": false,
7 | "targets": {
8 | "browsers": [
9 | "> 1%",
10 | "last 2 versions",
11 | "not ie <= 8"
12 | ]
13 | }
14 | }
15 | ],
16 | "stage-2"
17 | ],
18 | "plugins": [
19 | "transform-vue-jsx",
20 | "transform-runtime",
21 | "syntax-dynamic-import"
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/.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 | .project
16 |
--------------------------------------------------------------------------------
/.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 5 version'
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | vue-hbuilder-test
4 |
5 |
6 |
7 |
8 |
9 | com.aptana.ide.core.unifiedBuilder
10 |
11 |
12 |
13 |
14 | com.pandora.projects.ui.MKeyBuilder
15 |
16 |
17 |
18 |
19 |
20 | com.pandora.projects.ui.MKeyNature
21 | com.aptana.projects.webnature
22 |
23 |
24 |
25 | 1526350413058
26 |
27 | 26
28 |
29 | org.eclipse.ui.ide.multiFilter
30 | 1.0-name-matches-false-false-node_modules
31 |
32 |
33 |
34 | 1526396919120
35 |
36 | 26
37 |
38 | org.eclipse.ui.ide.multiFilter
39 | 1.0-name-matches-false-false-node_modules
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-webpack-hbuilder
2 |
3 | > 此项目设计的最初目的是为了解决使用 vue+webpack 自动化构建并实时同步手机热更新调试而诞生。截止目前,DCloud 官方并提供一套完整的 vue+webpack+hbuilder 实时开发调试的文章,只是零零散散有人去构建一些自己的项目,并不能很好地教会或者引导大量开发者使用该开发模式进行开发。本项目以构建流程为主,适量 demo 为辅,印证了 vue+webpack+hbuilder 实时调试以及打包的可行性,为开发者提供多开发种选择。
4 | 本APP与其他APP不同,该APP并不是功能性APP,所以几乎没有展示内容的业务逻辑,你可以把它理解为DCLOUD的muiAPP,做UIdemo的展示,并且验证PLUS在vue+webpack构建方式下的各类使用情况。更多的AQ可以在APP中的‘INTRODUCE’中得到解答。
5 | 本应用为单页面开发,多页面请参照我的另一个APP:[vue-webpack-cube-for-hbuilder](https://github.com/wjsljc/vue-webpack-cube-for-hbuilder "vue-webpack-cube-for-hbuilder")
6 |
7 | ## 使用步骤
8 | ###下载代码
9 | ```
10 | $ git clone https://github.com/wjsljc/vue-webpack-mint-for-hbuilder.git
11 | $ cd vue-webpack-mint-for-hbuilder
12 | $ npm install
13 | ```
14 |
15 | ### 在浏览器中调试调试
16 | ```
17 | $ npm run dev
18 | ```
19 | 浏览器地址为:``http://localhost:8080/index.html``
20 |
21 | ### 真机同步调试
22 | ```
23 | $ npm run dev
24 | ```
25 | 在 HBuilder 中设置应用入口地址为 ``本地服务器:端口号/index.html``
26 | 如 192.168.11.102:8080/index.html
27 | > 请确保手机与本地服务在同一网段,否则无法访问本机的服务。
28 |
29 | ### 编译后真机同步调试
30 | ```
31 | $ npm run build
32 | ```
33 | - 把 dist 目录下的文件复制到 HBuilder 项目下
34 | - 设置起始页为 index.html
35 | - 真机运行调试
36 |
37 | ## 主要架构以及特色
38 | > vue + webpack + mint-ui + hbuilder
39 | - UI模块和PLUS模块独立展示,参考使用各取所需
40 | - UI是对mint-ui官网demo的仿造与实际实践,100%迁移以及额外的扩展,更多的自定义demo展示与结合APP的运用,更加符合一款APP的基础需求
41 | - PLUS对5+SDK的的集成运用,对APP常用的几个功能进行了展示,验证5+在vue中的使用
42 | - 索引页面、登陆与登出,登陆超时、广告弹出等等功能的基础实现原理,使得APP更加“高仿”
43 | - 对公共函数的封装、组件的封装、对公用代码mixin的使用等也体现了作者对APP的态度
44 | - 应用中间右边增加虚拟HOME键,方便在移动端中查看log、调试等
45 |
46 | ## 赞助
47 | 如果该项目给您带来了工作上的参考或者启发,亦或者期待更多其他项目的诞生和该项目的继续维护,支持作者原创扫一扫或点击识别下方的二维码,为作者打赏1.0元吧!
48 |
49 | 
50 | 
51 |
52 |
--------------------------------------------------------------------------------
/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/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/build/logo.png
--------------------------------------------------------------------------------
/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 | minimize: true
23 | }
24 | }
25 |
26 | const postcssLoader = {
27 | loader: 'postcss-loader',
28 | options: {
29 | sourceMap: options.sourceMap
30 | }
31 | }
32 |
33 | // generate loader string to be used with extract text plugin
34 | function generateLoaders (loader, loaderOptions) {
35 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
36 |
37 | if (loader) {
38 | loaders.push({
39 | loader: loader + '-loader',
40 | options: Object.assign({}, loaderOptions, {
41 | sourceMap: options.sourceMap
42 | })
43 | })
44 | }
45 |
46 | // Extract CSS when that option is specified
47 | // (which is the case during production build)
48 | if (options.extract) {
49 | return ExtractTextPlugin.extract({
50 | use: loaders,
51 | fallback: 'vue-style-loader'
52 | })
53 | } else {
54 | return ['vue-style-loader'].concat(loaders)
55 | }
56 | }
57 |
58 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
59 | return {
60 | css: generateLoaders(),
61 | postcss: generateLoaders(),
62 | less: generateLoaders('less'),
63 | sass: generateLoaders('sass', {indentedSyntax: true}),
64 | scss: generateLoaders('sass'),
65 | stylus: generateLoaders('stylus'),
66 | styl: generateLoaders('stylus')
67 | }
68 | }
69 |
70 | // Generate loaders for standalone style files (outside of .vue)
71 | exports.styleLoaders = function (options) {
72 | const output = []
73 | const loaders = exports.cssLoaders(options)
74 |
75 | for (const extension in loaders) {
76 | const loader = loaders[extension]
77 | output.push({
78 | test: new RegExp('\\.' + extension + '$'),
79 | use: loader
80 | })
81 | }
82 |
83 | return output
84 | }
85 |
86 | exports.createNotifierCallback = () => {
87 | const notifier = require('node-notifier')
88 |
89 | return (severity, errors) => {
90 | if (severity !== 'error') return
91 |
92 | const error = errors[0]
93 | const filename = error.file && error.file.split('!').pop()
94 |
95 | notifier.notify({
96 | title: packageConfig.name,
97 | message: severity + ': ' + error.name,
98 | subtitle: filename || '',
99 | icon: path.join(__dirname, 'logo.png')
100 | })
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/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 | module.exports = {
13 | context: path.resolve(__dirname, '../'),
14 | entry: {
15 | app: ['babel-polyfill', './src/main.js']
16 | },
17 | output: {
18 | path: config.build.assetsRoot,
19 | filename: '[name].js',
20 | publicPath: process.env.NODE_ENV === 'production'
21 | ? config.build.assetsPublicPath
22 | : config.dev.assetsPublicPath
23 | },
24 | resolve: {
25 | extensions: ['.js', '.vue', '.json'],
26 | alias: {
27 | 'vue$': 'vue/dist/vue.esm.js',
28 | '@': resolve('src'),
29 | 'page': resolve('src/page'),
30 | 'assets': resolve('src/assets'),
31 | 'components': resolve('src/components'),
32 | 'api': resolve('src/api'),
33 | 'ROUTER': resolve('src/router')
34 | }
35 | },
36 | module: {
37 | rules: [
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 | }
87 |
--------------------------------------------------------------------------------
/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 | publicPath: './',
28 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
29 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
30 | },
31 | plugins: [
32 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
33 | new webpack.DefinePlugin({
34 | 'process.env': env
35 | }),
36 | new UglifyJsPlugin({
37 | uglifyOptions: {
38 | compress: {
39 | warnings: false
40 | }
41 | },
42 | sourceMap: config.build.productionSourceMap,
43 | parallel: true
44 | }),
45 | // extract css into its own file
46 | new ExtractTextPlugin({
47 | filename: utils.assetsPath('css/[name].[contenthash].css'),
48 | // Setting the following option to `false` will not extract CSS from codesplit chunks.
49 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
50 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
51 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
52 | allChunks: true,
53 | }),
54 | // Compress extracted CSS. We are using this plugin so that possible
55 | // duplicated CSS from different components can be deduped.
56 | // new OptimizeCSSPlugin({
57 | // cssProcessorOptions: config.build.productionSourceMap
58 | // ? {safe: true, map: {inline: false}}
59 | // : {safe: true}
60 | // }),
61 | // generate dist index.html with correct asset hash for caching.
62 | // you can customize output by editing /index.html
63 | // see https://github.com/ampedandwired/html-webpack-plugin
64 | new HtmlWebpackPlugin({
65 | filename: config.build.index,
66 | template: 'index.html',
67 | inject: true,
68 | minify: {
69 | removeComments: true,
70 | collapseWhitespace: true,
71 | removeAttributeQuotes: true
72 | // more options:
73 | // https://github.com/kangax/html-minifier#options-quick-reference
74 | },
75 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
76 | chunksSortMode: 'dependency'
77 | }),
78 | // keep module.id stable when vendor modules does not change
79 | new webpack.HashedModuleIdsPlugin(),
80 | // enable scope hoisting
81 | new webpack.optimize.ModuleConcatenationPlugin(),
82 | // split vendor js into its own file
83 | new webpack.optimize.CommonsChunkPlugin({
84 | name: 'vendor',
85 | minChunks (module) {
86 | // any required modules inside node_modules are extracted to vendor
87 | return (
88 | module.resource &&
89 | /\.js$/.test(module.resource) &&
90 | module.resource.indexOf(
91 | path.join(__dirname, '../node_modules')
92 | ) === 0
93 | )
94 | }
95 | }),
96 | // extract webpack runtime and module manifest to its own file in order to
97 | // prevent vendor hash from being updated whenever app bundle is updated
98 | new webpack.optimize.CommonsChunkPlugin({
99 | name: 'manifest',
100 | minChunks: Infinity
101 | }),
102 | // This instance extracts shared chunks from code splitted chunks and bundles them
103 | // in a separate chunk, similar to the vendor chunk
104 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
105 | new webpack.optimize.CommonsChunkPlugin({
106 | name: 'app',
107 | async: 'vendor-async',
108 | children: true,
109 | minChunks: 3
110 | }),
111 |
112 | // copy custom static assets
113 | new CopyWebpackPlugin([
114 | {
115 | from: path.resolve(__dirname, '../static'),
116 | to: config.build.assetsSubDirectory,
117 | ignore: ['.*']
118 | }
119 | ])
120 | ]
121 | })
122 |
123 | if (config.build.productionGzip) {
124 | const CompressionWebpackPlugin = require('compression-webpack-plugin')
125 |
126 | webpackConfig.plugins.push(
127 | new CompressionWebpackPlugin({
128 | asset: '[path].gz[query]',
129 | algorithm: 'gzip',
130 | test: new RegExp(
131 | '\\.(' +
132 | config.build.productionGzipExtensions.join('|') +
133 | ')$'
134 | ),
135 | threshold: 10240,
136 | minRatio: 0.8
137 | })
138 | )
139 | }
140 |
141 | if (config.build.bundleAnalyzerReport) {
142 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
143 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
144 | }
145 |
146 | module.exports = webpackConfig
147 |
--------------------------------------------------------------------------------
/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 |
15 | // Various Dev Server settings
16 | host: '0.0.0.0', // 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 | }
70 |
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vue-hbuilder-test
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "@platforms": [
3 | "android",
4 | "iPhone",
5 | "iPad"
6 | ],
7 | "id": "H58F8F36D",/*应用的标识,创建应用时自动生成,勿手动修改*/
8 | "name": "vue-hbuilder-test",/*应用名称,程序桌面图标名称*/
9 | "version": {
10 | "name": "1.0",/*应用版本名称*/
11 | "code": ""
12 | },
13 | "description": "",/*应用描述信息*/
14 | "icons": {
15 | "72": "icon.png"
16 | },
17 | "launch_path": "http://192.168.7.156:8080/index.html",/*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/
18 | "developer": {
19 | "name": "",/*开发者名称*/
20 | "email": "",/*开发者邮箱地址*/
21 | "url": ""
22 | },
23 | "permissions": {
24 | "Messaging": {
25 | "description": "短彩邮件插件"
26 | },
27 | "Cache": {
28 | "description": "管理应用缓存"
29 | },
30 | "Console": {
31 | "description": "跟踪调试输出日志"
32 | },
33 | "Contacts": {
34 | "description": "访问系统联系人信息"
35 | },
36 | "Events": {
37 | "description": "应用扩展事件"
38 | },
39 | "Maps": {
40 | "description": "管理地图插件"
41 | },
42 | "Speech": {
43 | "description": "管理语音识别插件"
44 | }
45 | },
46 | "plus": {
47 | "statusbar": {
48 | "immersed": false
49 | },
50 | "splashscreen": {
51 | "autoclose": true,/*是否自动关闭程序启动界面,true表示应用加载应用入口页面后自动关闭;false则需调plus.navigator.closeSplashscreen()关闭*/
52 | "waiting": true
53 | },
54 | "popGesture": "close",/*设置应用默认侧滑返回关闭Webview窗口,"none"为无侧滑返回功能,"hide"为侧滑隐藏Webview窗口。参考http://ask.dcloud.net.cn/article/102*/
55 | "runmode": "normal",/*应用的首次启动运行模式,可取liberate或normal,liberate模式在第一次启动时将解压应用资源(Android平台File API才可正常访问_www目录)*/
56 | "signature": "Sk9JTiBVUyBtYWlsdG86aHIyMDEzQGRjbG91ZC5pbw==",/*可选,保留给应用签名,暂不使用*/
57 | "distribute": {
58 | "apple": {
59 | "appid": "",/*iOS应用标识,苹果开发网站申请的appid,如io.dcloud.HelloH5*/
60 | "mobileprovision": "",/*iOS应用打包配置文件*/
61 | "password": "",/*iOS应用打包个人证书导入密码*/
62 | "p12": "",/*iOS应用打包个人证书,打包配置文件关联的个人证书*/
63 | "devices": "universal",/*iOS应用支持的设备类型,可取值iphone/ipad/universal*/
64 | "frameworks": []
65 | },
66 | "google": {
67 | "packagename": "",/*Android应用包名,如io.dcloud.HelloH5*/
68 | "keystore": "",/*Android应用打包使用的密���库文件*/
69 | "password": "",/*Android应用打包使用密钥库中证书的密码*/
70 | "aliasname": "",/*Android应用打包使用密钥库中证书的别名*/
71 | "permissions": [
72 | "",
73 | "",
74 | "",
75 | "",
76 | "",
77 | "",
78 | "",
79 | "",
80 | "",
81 | "",
82 | "",
83 | "",
84 | "",
85 | "",
86 | "",
87 | "",
88 | "",
89 | "",
90 | "",
91 | "",
92 | "",
93 | ""
94 | ]
95 | },
96 | "orientation": [
97 | "portrait-primary"
98 | ],/*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/
99 | "icons": {
100 | "ios": {
101 | "prerendered": true, /*应用图标是否已经高亮处理,在iOS6及以下设备上有效*/
102 | "auto": "", /*应用图标,分辨率:512x512,用于自动生成各种尺寸程序图标*/
103 | "iphone": {
104 | "normal": "", /*iPhone3/3GS程序图标,分辨率:57x57*/
105 | "retina": "", /*iPhone4程序图标,分辨率:114x114*/
106 | "retina7": "", /*iPhone4S/5/6程序图标,分辨率:120x120*/
107 | "retina8": "", /*iPhone6 Plus程序图标,分辨率:180x180*/
108 | "spotlight-normal": "", /*iPhone3/3GS Spotlight搜索程序图标,分辨率:29x29*/
109 | "spotlight-retina": "", /*iPhone4 Spotlight搜索程序图标,分辨率:58x58*/
110 | "spotlight-retina7": "", /*iPhone4S/5/6 Spotlight搜索程序图标,分辨率:80x80*/
111 | "settings-normal": "", /*iPhone4设置页面程序图标,分辨率:29x29*/
112 | "settings-retina": "", /*iPhone4S/5/6设置页面程序图标,分辨率:58x58*/
113 | "settings-retina8": ""
114 | },
115 | "ipad": {
116 | "normal": "", /*iPad普通屏幕程序图标,分辨率:72x72*/
117 | "retina": "", /*iPad高分屏程序图标,分辨率:144x144*/
118 | "normal7": "", /*iPad iOS7程序图标,分辨率:76x76*/
119 | "retina7": "", /*iPad iOS7高分屏程序图标,分辨率:152x152*/
120 | "spotlight-normal": "", /*iPad Spotlight搜索程序图标,分辨率:50x50*/
121 | "spotlight-retina": "", /*iPad高分屏Spotlight搜索程序图标,分辨率:100x100*/
122 | "spotlight-normal7": "",/*iPad iOS7 Spotlight搜索程序图标,分辨率:40x40*/
123 | "spotlight-retina7": "",/*iPad iOS7高分屏Spotlight搜索程序图标,分辨率:80x80*/
124 | "settings-normal": "",/*iPad设置页面程序图标,分辨率:29x29*/
125 | "settings-retina": ""
126 | }
127 | },
128 | "android": {
129 | "mdpi": "", /*普通屏程序图标,分辨率:48x48*/
130 | "ldpi": "", /*大屏程序图标,分辨率:48x48*/
131 | "hdpi": "", /*高分屏程序图标,分辨率:72x72*/
132 | "xhdpi": "",/*720P高分屏程序图标,分辨率:96x96*/
133 | "xxhdpi": ""
134 | }
135 | },
136 | "splashscreen": {
137 | "ios": {
138 | "iphone": {
139 | "default": "", /*iPhone3启动图片选,分辨率:320x480*/
140 | "retina35": "",/*3.5英寸设备(iPhone4)启动图片,分辨率:640x960*/
141 | "retina40": "",/*4.0 英寸设备(iPhone5/iPhone5s)启动图片,分辨率:640x1136*/
142 | "retina47": "",/*4.7 英寸设备(iPhone6)启动图片,分辨率:750x1334*/
143 | "retina55": "",/*5.5 英寸设备(iPhone6 Plus)启动图片,分辨率:1242x2208*/
144 | "retina55l": ""
145 | },
146 | "ipad": {
147 | "portrait": "", /*iPad竖屏启动图片,分辨率:768x1004*/
148 | "portrait-retina": "",/*iPad高分屏竖屏图片,分辨率:1536x2008*/
149 | "landscape": "", /*iPad横屏启动图片,分辨率:1024x748*/
150 | "landscape-retina": "", /*iPad高分屏横屏启动图片,分辨率:2048x1496*/
151 | "portrait7": "", /*iPad iOS7竖屏启动图片,分辨率:768x1024*/
152 | "portrait-retina7": "",/*iPad iOS7高分屏竖屏图片,分辨率:1536x2048*/
153 | "landscape7": "", /*iPad iOS7横屏启动图片,分辨率:1024x768*/
154 | "landscape-retina7": ""
155 | }
156 | },
157 | "android": {
158 | "mdpi": "", /*普通屏启动图片,分辨率:240x282*/
159 | "ldpi": "", /*大屏启动图片,分辨率:320x442*/
160 | "hdpi": "", /*高分屏启动图片,分辨率:480x762*/
161 | "xhdpi": "", /*720P高分屏启动图片,分辨率:720x1242*/
162 | "xxhdpi": ""
163 | }
164 | }
165 | }
166 | }
167 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-webpack-hbuilder",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "ljc_mac_window <635314068@qq.com>",
6 | "scripts": {
7 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
8 | "start": "npm run dev",
9 | "build": "node build/build.js"
10 | },
11 | "dependencies": {
12 | "mint-ui": "^2.2.13",
13 | "vue": "^2.5.2",
14 | "vue-router": "^3.0.1",
15 | "axios": "^0.18.0"
16 | },
17 | "devDependencies": {
18 | "autoprefixer": "^8.4.1",
19 | "babel-core": "^6.22.1",
20 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
21 | "babel-loader": "^7.1.1",
22 | "babel-plugin-syntax-dynamic-import": "^6.18.0",
23 | "babel-plugin-syntax-jsx": "^6.18.0",
24 | "babel-plugin-transform-runtime": "^6.22.0",
25 | "babel-plugin-transform-vue-jsx": "^3.5.0",
26 | "babel-polyfill": "^6.26.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 | "stylus": "^0.54.5",
47 | "stylus-loader": "^3.0.2",
48 | "uglifyjs-webpack-plugin": "^1.1.1",
49 | "url-loader": "^0.5.8",
50 | "vue-loader": "^13.3.0",
51 | "vue-style-loader": "^3.0.1",
52 | "vue-template-compiler": "^2.5.2",
53 | "webpack": "^3.6.0",
54 | "webpack-bundle-analyzer": "^2.9.0",
55 | "webpack-dev-server": "^2.9.1",
56 | "webpack-merge": "^4.1.0"
57 | },
58 | "engines": {
59 | "node": ">= 6.0.0",
60 | "npm": ">= 3.0.0"
61 | },
62 | "browserslist": [
63 | "> 1%",
64 | "last 5 versions",
65 | "not ie <= 8"
66 | ]
67 | }
68 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | const autoprefixer = require('autoprefixer')
2 |
3 | module.exports = {
4 | plugins: [
5 | autoprefixer()
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
28 |
--------------------------------------------------------------------------------
/src/api/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const config = {
4 | timeout: 0,
5 | withCredentials: true, // cookie
6 | }
7 | const ajaxInstance = axios.create(config);
8 |
9 | export function payment (url, params) {
10 | return ajaxInstance.post(url, params).then((res) => {
11 | return Promise.resolve(res.data)
12 | })
13 | }
14 |
15 | export function patientList (params) {
16 | let url = 'http://test.jlrcare.com/doctor/service/patient/getAllPatientByUserId'
17 | return ajaxInstance.post(url, params).then((res) => {
18 | return Promise.resolve(res.data)
19 | })
20 | }
21 |
--------------------------------------------------------------------------------
/src/assets/audio/shake.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/src/assets/audio/shake.wav
--------------------------------------------------------------------------------
/src/assets/audio/videoviewdemo.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/src/assets/audio/videoviewdemo.mp4
--------------------------------------------------------------------------------
/src/assets/css/base.styl:
--------------------------------------------------------------------------------
1 | @import "variable.styl"
2 |
3 | body, html
4 | line-height: 1
5 | font-family: 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', arial, sans-serif, 'Droid Sans Fallback'
6 | user-select: none
7 | -webkit-tap-highlight-color: transparent
8 | background: $color-background
9 | color: $color-text
10 |
11 | #__vconsole .vc-switch {
12 | width 15px
13 | height 15px
14 | padding 8px
15 | border-radius 100%
16 | bottom 50%
17 | right 5px
18 | background-color $color-background-w
19 | }
20 |
--------------------------------------------------------------------------------
/src/assets/css/common.styl:
--------------------------------------------------------------------------------
1 | @import "variable.styl"
2 |
3 | .mint-cell-wrapper {
4 | height 50px
5 | }
6 |
7 | /*头部样式*/
8 | .mint-header {
9 | height 50px
10 | h1 {
11 | font-size $font-size-medium-x
12 | }
13 | }
14 |
15 | /*indicator遮罩*/
16 | .mint-indicator-wrapper, .mint-indicator-mask {
17 | z-index 9999999 !important
18 | }
19 |
20 | /*msgbox弹出框字体大小*/
21 | .mint-msgbox-confirm, .mint-msgbox-cancel {
22 | font-size $font-size-medium-x
23 | }
24 |
25 | /*搜索框左边间距*/
26 | .mint-searchbar-core {
27 | padding-left 5px
28 | }
29 |
30 | /*header组件*/
31 | .mint-header.is-fixed {
32 | z-index 201
33 | }
34 |
--------------------------------------------------------------------------------
/src/assets/css/flex.styl:
--------------------------------------------------------------------------------
1 | .flex-1 {
2 | flex: 1;
3 | }
4 |
5 | .flex-2 {
6 | flex: 2;
7 | }
8 |
9 | .flex-3 {
10 | flex: 3;
11 | }
12 |
13 | .flex-4 {
14 | flex: 4;
15 | }
16 |
17 | .flex-5 {
18 | flex: 5;
19 | }
20 |
21 | .flex-6 {
22 | flex: 6;
23 | }
24 |
25 | .flex-7 {
26 | flex: 7;
27 | }
28 |
29 | .flex-8 {
30 | flex: 8;
31 | }
32 |
33 | .flex-9 {
34 | flex: 9;
35 | }
36 |
37 | flex($i)
38 | flex $i
39 |
40 | .flex-middle {
41 | -webkit-align-items: center;
42 | align-items: center;
43 | }
44 |
45 | .flex-center {
46 | -webkit-justify-content: center;
47 | justify-content: center;
48 | }
49 |
50 | .flex-row {
51 | display: -webkit-flex;
52 | display: flex;
53 | flex-direction: row;
54 | }
55 |
56 | .flex-col {
57 | display: -webkit-flex;
58 | display: flex;
59 | flex-direction: column;
60 | }
61 |
62 | .flex-allCenter {
63 | display: -webkit-flex;
64 | display: flex;
65 | -webkit-justify-content: center;
66 | justify-content: center;
67 | -webkit-align-items: center;
68 | align-items: center;
69 | }
70 |
--------------------------------------------------------------------------------
/src/assets/css/iconfont.styl:
--------------------------------------------------------------------------------
1 |
2 | @font-face {font-family: "iconfont";
3 | src: url('../fonts/iconfont.eot?t=1527087489253'); /* IE9*/
4 | src: url('../fonts/iconfont.eot?t=1527087489253#iefix') format('embedded-opentype'), /* IE6-IE8 */
5 | url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAbAAAsAAAAACYwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW7knlY21hcAAAAYAAAABuAAABsgV400BnbHlmAAAB8AAAArYAAAMkjbDXE2hlYWQAAASoAAAAMQAAADYRdojyaGhlYQAABNwAAAAeAAAAJAffA4VobXR4AAAE/AAAABQAAAAUE+n//2xvY2EAAAUQAAAADAAAAAwBcAJybWF4cAAABRwAAAAeAAAAIAEUAG1uYW1lAAAFPAAAAUUAAAJtPlT+fXBvc3QAAAaEAAAAOwAAAE03E3p/eJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/s04gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDz/wdzwv4EhhrmBoQEozAiSAwA20Q1oeJzFkMENgDAIRR+ixhjjJA7hQJ48deK6gjf9LR50Aj95DfxAaAA6wMUiWrAdo2iTa9V3xuq3rKpHBhpFyp7n47wuee88ZOqLKHmjWe2wnt9k/63+aqrv+lS6OOlBX8we6GLkOSg9xxngNwOZF4QAAHicNZJbaxNBFMfnzGR3c2k2u5vNTnbTXHa3zVprF5rmUtCmVEQ0VLAkL741tPjWtFDSYvGhlhi8FfwAqQ8i5EEK0r4WFQQf+uIHEGpFfRH8AILdOtvqMJzLzDmH+f0ZxCF0+pUckCSKowtoHF1DtxECfhQsEafBdIouHoWEySWoKhLHdkzBtlwyBdTiVa1QLuYpL/AxECEDE2ah7LjYgVKxii9DQUsD6CmjrgwPKuQ5hJNO5qFXwy8hkbUHY9Ux7+alabWQiwfXBxRFV5RnQZ7jghgHYiIsUS3EhcK894qLGYmD7AjOwoDuGLN3ormU0nxUbKWHaQhgcxPiqZzYn5YNme37hhZXdEGKBpNG1B5SYf17JBkfSOe/IbZ81ndklcyg2BnrDLrKWEWs0YTPMgUMp2KXXHBEEBI2M3IGqFmFiuwCA6QJs1QFUHnbtPIluViumBlIyBjF09GgqFla3PrtkM7CQoc4IxWAygi2zrz3sd7C3gZuwQtTPznSTVPHlm7CdVBtK1qSNU0uKQXrTXOxg3Fnsck6ve3zCbDK/DBu1ZvNeusk7LfCatIEMJPeNmMCxvSTfCAaCrHEEaCMKg6P4N7nJmwUIfmefvKOwdif81pP4fXbycfeD8Sdnp5uB4DcRRFEUQHdQvOsl/ExYgbPeFnAUha4ELfyU/BPEhH8hB37WojsyoVypYrzjgsC78dljWbYXxD+N7lQLE/4xSoPT+orGK/UG8sYLzfaPUJ67TP7S6Jkr9vdI6CZNPCl3z/iQIvENKJI9oRkpNUxKumcJDmzufHRVOPKoUTxg3lfs61dQgnFK42GP5nZOdJba+8QstNe6/25SOVad5+Q/W7NL671jwOB435NpnCo5igRxm/MaNFwAJSsERBkOrS0PhfxDqg02dw8f8ru1qREmcR/AZk0lrwAAHicY2BkYGAA4rv7tk+O57f5ysDNwgAC17UXNcLo////97IwMqcBuRwMTCBRAG6ADOIAAAB4nGNgZGBgbvjfwBDDwvAfCFgYGYAiKIAVAKDEBmsAAAQAAAAD6QAABAAAAAQAAAAEAP//AAAAAAB2AOAA+gGSeJxjYGRgYGBlSARiEGACYi4gZGD4D+YzAAASvQGCAAB4nGWPTU7DMBCFX/oHpBKqqGCH5AViASj9EatuWFRq911036ZOmyqJI8et1ANwHo7ACTgC3IA78EgnmzaWx9+8eWNPANzgBx6O3y33kT1cMjtyDRe4F65TfxBukF+Em2jjVbhF/U3YxzOmwm10YXmD17hi9oR3YQ8dfAjXcI1P4Tr1L+EG+Vu4iTv8CrfQ8erCPuZeV7iNRy/2x1YvnF6p5UHFockikzm/gple75KFrdLqnGtbxCZTg6BfSVOdaVvdU+zXQ+ciFVmTqgmrOkmMyq3Z6tAFG+fyUa8XiR6EJuVYY/62xgKOcQWFJQ6MMUIYZIjK6Og7VWb0r7FDwl57Vj3N53RbFNT/c4UBAvTPXFO6stJ5Ok+BPV8bUnV0K27LnpQ0kV7NSRKyQl7WtlRC6gE2ZVeOEXpc0Yk/KGdI/wAJWm7IAAAAeJxjYGKAAC4G7ICVkYmRmZGFkZWRjYGxgiU3MzeRPzkxv6o0PzkjNS89PT8vna0SSGSUMjAAAL7PCzwA') format('woff'),
6 | url('../fonts/iconfont.ttf?t=1527087489253') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
7 | url('../fonts/iconfont.svg?t=1527087489253#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .iconfont {
11 | font-family:"iconfont" !important;
12 | font-size:16px;
13 | font-style:normal;
14 | -webkit-font-smoothing: antialiased;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | .icon-mima:before { content: "\e603"; }
19 |
20 | .icon-caozuochenggong:before { content: "\e7f8"; }
21 |
22 | .icon-yonghu:before { content: "\e60e"; }
23 |
24 |
--------------------------------------------------------------------------------
/src/assets/css/index.styl:
--------------------------------------------------------------------------------
1 | @import "./reset.styl"
2 | @import "./base.styl"
3 | @import "./common.styl"
4 | @import "./iconfont.styl"
5 | @import "./variable.styl"
6 |
--------------------------------------------------------------------------------
/src/assets/css/reset.styl:
--------------------------------------------------------------------------------
1 | /**
2 | * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
3 | * http://cssreset.com
4 | */
5 | html, body, div, span, applet, object, iframe,
6 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
7 | a, abbr, acronym, address, big, cite, code,
8 | del, dfn, em, img, ins, kbd, q, s, samp,
9 | small, strike, strong, sub, sup, tt, var,
10 | b, u, i, center,
11 | dl, dt, dd, ol, ul, li,
12 | fieldset, form, label, legend,
13 | table, caption, tbody, tfoot, thead, tr, th, td,
14 | article, aside, canvas, details, embed,
15 | figure, figcaption, footer, header,
16 | menu, nav, output, ruby, section, summary,
17 | time, mark, audio, video, input
18 | margin: 0
19 | padding: 0
20 | border: 0
21 | font-size: 100%
22 | font-weight: normal
23 | vertical-align: baseline
24 |
25 | /* HTML5 display-role reset for older browsers */
26 | article, aside, details, figcaption, figure,
27 | footer, header, menu, nav, section
28 | display: block
29 |
30 | body
31 | line-height: 1
32 |
33 | blockquote, q
34 | quotes: none
35 |
36 | blockquote:before, blockquote:after,
37 | q:before, q:after
38 | content: none
39 |
40 | table
41 | border-collapse: collapse
42 | border-spacing: 0
43 |
44 | /* custom */
45 |
46 | a
47 | color: #7e8c8d
48 | -webkit-backface-visibility: hidden
49 | text-decoration: none
50 |
51 | li
52 | list-style: none
53 |
54 | body
55 | -webkit-text-size-adjust: none
56 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0)
57 |
--------------------------------------------------------------------------------
/src/assets/css/transition.styl:
--------------------------------------------------------------------------------
1 | .slide-enter-active, .slide-leave-active
2 | transition: all .3s
3 |
4 | .slide-enter, .slide-leave-to
5 | transform: translate3d(100%, 0, 0)
6 |
--------------------------------------------------------------------------------
/src/assets/css/variable.styl:
--------------------------------------------------------------------------------
1 | // 颜色定义规范
2 | $color-background = #f7f7f7
3 | $color-background-w = white
4 | $color-background-d = rgba(0, 0, 0, 0.3)
5 | $color-highlight-background = #333
6 | $color-dialog-background = #666
7 | $color-theme = #ffcd32
8 | $color-theme-d = rgba(255, 205, 49, 0.5)
9 | $color-sub-theme = #d93f30
10 | $color-text = #4B4B4B
11 | $color-text-d = rgba(255, 255, 255, 0.3)
12 | $color-text-l = rgba(227, 227, 227, 0.7)
13 | $color-text-ll = rgba(255, 255, 255, 0.8)
14 | $color-shadow = #b8bbbf
15 |
16 | //字体定义规范
17 | $font-size-small-s = 10px
18 | $font-size-small = 12px
19 | $font-size-medium = 14px
20 | $font-size-medium-x = 16px
21 | $font-size-large = 18px
22 | $font-size-large-x = 22px
23 |
--------------------------------------------------------------------------------
/src/assets/fonts/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/src/assets/fonts/iconfont.eot
--------------------------------------------------------------------------------
/src/assets/fonts/iconfont.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
43 |
--------------------------------------------------------------------------------
/src/assets/fonts/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/src/assets/fonts/iconfont.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/src/assets/fonts/iconfont.woff
--------------------------------------------------------------------------------
/src/assets/js/mixins.js:
--------------------------------------------------------------------------------
1 | import { Header } from 'mint-ui'
2 |
3 | export const headerMixin = {
4 | components: {
5 | Header
6 | },
7 | data () {
8 | return {
9 | headerConf: {
10 | fixed: true
11 | }
12 | }
13 | },
14 | methods: {
15 | back () {
16 | window.history.back();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/assets/js/plusReady.js:
--------------------------------------------------------------------------------
1 | export const plusReady = (fn) => {
2 | if (window.plus) {
3 | setTimeout(fn, 0)
4 | } else {
5 | document.addEventListener("plusready", fn, false)
6 | }
7 | }
8 |
9 |
10 | /*重写返回按钮事件*/
11 | plusReady(() => {
12 |
13 | })
14 |
--------------------------------------------------------------------------------
/src/assets/js/storageConst.js:
--------------------------------------------------------------------------------
1 | export const SLIDER_FLAG = '_slider_flag_' // 索引页存储标识
2 | export const LOGIN_FLAG = '_login_flag_' // 登陆标识
3 | export const AD_FLAG = '_AD_flag_' // 广告显示标识
4 | export const INDEX_ACTIVETAB = '_index_activeTab_' // 首页tab活跃标识
5 |
--------------------------------------------------------------------------------
/src/assets/js/utils.js:
--------------------------------------------------------------------------------
1 | import { AD_FLAG, LOGIN_FLAG } from 'assets/js/storageConst'
2 | /*
3 | * 制作存储定时localstorage方法
4 | * */
5 | export const MyLocalStorage = {
6 | Cache: {
7 | /**
8 | * 总容量5M
9 | * 存入缓存,支持字符串类型、json对象的存储
10 | * 页面关闭后依然有效 ie7+都有效
11 | * @param key 缓存key
12 | * @param stringVal
13 | * @time 数字 缓存有效时间(秒) 默认60s
14 | * 注:localStorage 方法存储的数据没有时间限制。第二天、第二周或下一年之后,数据依然可用。不能控制缓存时间,故此扩展
15 | * */
16 | set: function (key, stringVal, time) {
17 | try {
18 | if (!localStorage) {
19 | return false;
20 | }
21 | if (!time || isNaN(time)) {
22 | time = 60;
23 | }
24 | var cacheExpireDate = (new Date() - 1) + time * 1000;
25 | var cacheVal = {
26 | val: stringVal,
27 | exp: cacheExpireDate
28 | };
29 | localStorage.setItem(key, JSON.stringify(cacheVal)); //存入缓存值
30 | //console.log(key+":存入缓存,"+new Date(cacheExpireDate)+"到期");
31 | } catch (e) {
32 | }
33 | },
34 | /**获取缓存*/
35 | get: function (key) {
36 | try {
37 | if (!localStorage) {
38 | return false;
39 | }
40 | var cacheVal = localStorage.getItem(key);
41 | var result = JSON.parse(cacheVal);
42 | var now = new Date() - 1;
43 | if (!result) {
44 | return null;
45 | } //缓存不存在
46 | if (now > result.exp) { //缓存过期
47 | this.remove(key);
48 | return null;
49 | }
50 | //console.log("get cache:"+key);
51 | return result.val;
52 | } catch (e) {
53 | this.remove(key);
54 | return null;
55 | }
56 | },
57 | /**移除缓存,一般情况不手动调用,缓存过期自动调用*/
58 | remove: function (key) {
59 | if (!localStorage) {
60 | return false;
61 | }
62 | localStorage.removeItem(key);
63 | },
64 | /**清空所有缓存*/
65 | clear: function () {
66 | if (!localStorage) {
67 | return false;
68 | }
69 | localStorage.clear();
70 | }
71 | } //end Cache
72 | }
73 |
74 | /*
75 | * 检查是否执行广告
76 | * */
77 | export function checkADFlag () {
78 | console.log("执行checkADFlag")
79 | let AD_flag = MyLocalStorage.Cache.get(AD_FLAG)
80 | if (!AD_flag) {
81 | console.log('进入广告')
82 | MyLocalStorage.Cache.set(AD_FLAG, true, 30)
83 | return true
84 | } else {
85 | return false
86 | }
87 | }
88 |
89 | /*
90 | * 检查是否登陆
91 | * */
92 | export function checkLoginFlag () {
93 | console.log("执行checkLoginFlag")
94 | let login_flag = MyLocalStorage.Cache.get(LOGIN_FLAG)
95 | if (!login_flag) {
96 | console.log('进入登陆')
97 | return true
98 | } else {
99 | return false
100 | }
101 | }
102 |
103 | let elementStyle = document.createElement('div').style // 能力检测
104 | let vendor = (() => { // 供应商
105 | let transformNames = {
106 | webkit: 'webkitTransform',
107 | Moz: 'MozTransform',
108 | O: 'OTransform',
109 | ms: 'msTransform',
110 | standard: 'transform'
111 | }
112 | for (let key in transformNames) {
113 | if (elementStyle[transformNames[key]] !== undefined) {
114 | return key
115 | }
116 | }
117 | return false // 如果都没有,那么这个浏览器是有问题的
118 | })()
119 |
120 | /*
121 | * 根据供应商添加前缀
122 | * */
123 | export function prefixStyle (style) {
124 | if (vendor === false) {
125 | return false
126 | }
127 |
128 | if (vendor === 'standard') {
129 | return style
130 | }
131 | return vendor + style.charAt(0).toUpperCase() + style.substr(1) // 首字母大写如 webkitTransform
132 | }
133 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/plus/accelerometer/Accelerometer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 | 摇一摇
12 |
13 |
14 | {{accelerometerInfo.text}}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
93 |
94 |
135 |
--------------------------------------------------------------------------------
/src/components/plus/camera/Camera.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
16 |
17 |
18 |
拍照需要build或者打成包之后方可看见效果
19 |
20 |
选取照片
21 |
22 |
23 |
![]()
24 |
25 |
26 |
27 |
28 |
29 |
30 |
143 |
144 |
179 |
--------------------------------------------------------------------------------
/src/components/plus/geolocation/Geolocation.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 | 点击获取当前地理信息
12 |
13 |
14 |
{{locationInfo.address}}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
59 |
60 |
90 |
--------------------------------------------------------------------------------
/src/components/plus/payment/Payment.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 | 支付模块需要配合后台接口测试,本例子只是验证支付可能性。测试需修改相应接口参数为自己公司需要参数即可。
13 |
14 |
15 |
16 | 支付宝支付
17 | 微信支付
18 |
19 |
20 |
21 |
22 |
23 |
24 |
131 |
132 |
156 |
--------------------------------------------------------------------------------
/src/components/plus/resumeCallback/ResumeCallback.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 | 切换到后台在切回来试试看(全局有效)
12 |
13 |
14 |
15 |
16 |
17 |
18 |
34 |
35 |
57 |
--------------------------------------------------------------------------------
/src/components/plus/router/Router.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 | 跳到其他路由
12 | 跳到动态子路由
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
46 |
47 |
77 |
--------------------------------------------------------------------------------
/src/components/plus/router/RouterChildren.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 | router的动态子页面--{{pageSign}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
40 |
41 |
71 |
--------------------------------------------------------------------------------
/src/components/plus/test/Test.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | test
4 |
5 |
6 |
7 |
10 |
11 |
14 |
--------------------------------------------------------------------------------
/src/components/ui/actionSheet/ActionSheet.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
16 |
17 |
23 |
24 | 带取消按钮
25 | 不带取消按钮
26 |
27 |
28 |
29 |
30 |
31 |
91 |
92 |
115 |
--------------------------------------------------------------------------------
/src/components/ui/badge/Badge.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
指定尺寸
12 |
30
13 |
10
14 |
10
15 |
16 |
17 |
指定类型
18 |
30
19 |
10
20 |
10
21 |
10
22 |
23 |
24 |
指定颜色
25 |
自定义颜色
26 |
27 |
28 |
29 |
30 | 10
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
46 |
47 |
74 |
--------------------------------------------------------------------------------
/src/components/ui/button/Button.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
35 |
36 |
37 |
38 |
46 |
47 |
77 |
--------------------------------------------------------------------------------
/src/components/ui/cell/Cell.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 | icon 是图片
22 |
23 |
24 |
25 | 自定义标题
26 |
27 |
28 | 这里是元素
29 |
30 |
31 |
32 | 按钮
33 |
34 |
38 |
39 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
104 |
105 |
120 |
--------------------------------------------------------------------------------
/src/components/ui/checklist/Checklist.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
15 |
16 | {{checkBoxConf1.value}}
17 |
18 |
19 |
23 |
24 | {{checkBoxConf2.value}}
25 |
26 |
27 |
32 |
33 | {{checkBoxConf3.value}}
34 |
35 |
36 |
41 |
42 | {{checkBoxConf4.value}}
43 |
44 |
45 |
46 |
47 |
48 |
49 |
113 |
114 |
133 |
--------------------------------------------------------------------------------
/src/components/ui/datetimePicker/DatetimePicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
16 |
17 |
23 |
24 |
30 |
31 |
39 |
40 |
47 |
48 |
56 |
57 |
67 |
68 |
79 |
80 |
年月日
81 |
年月日时分
82 |
时分
83 |
自定义按钮文字
84 |
设置起始时间
85 |
设置范围(年月)
86 |
设置范围(时)
87 |
自定义模板
88 |
{{value}}
89 |
90 |
91 |
92 |
93 |
94 |
170 |
171 |
200 |
202 |
--------------------------------------------------------------------------------
/src/components/ui/field/Field.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
基础使用
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
22 |
23 |
24 |
设置校验状态
25 |
26 |
27 |
28 |
29 |
30 |
自定义内容(例如添加验证码)
31 |
32 | {{fieldInfo.captcha}}
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
91 |
92 |
123 |
138 |
--------------------------------------------------------------------------------
/src/components/ui/header/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
37 |
38 |
39 |
40 |
82 |
83 |
111 |
--------------------------------------------------------------------------------
/src/components/ui/indexList/IndexList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
50 |
51 |
67 |
--------------------------------------------------------------------------------
/src/components/ui/indicator/Indicator.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 | 加载样式1
11 | 加载样式2
12 | 加载样式3
13 | 加载样式4
14 | 带文字的加载样式
15 |
16 |
17 |
18 |
19 |
20 |
70 |
71 |
94 |
--------------------------------------------------------------------------------
/src/components/ui/infiniteScroll/infiniteScroll.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
24 |
60 |
61 |
84 |
--------------------------------------------------------------------------------
/src/components/ui/lazyLoad/LazyLoad.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 | -
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
41 |
42 |
68 |
--------------------------------------------------------------------------------
/src/components/ui/loadmore/Loadmore.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
23 |
26 | 我是有底线的
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
102 |
103 |
131 |
--------------------------------------------------------------------------------
/src/components/ui/messageBox/MessageBox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 | alert
11 | confirm
12 | prompt
13 | 自定义
14 |
15 |
16 |
17 |
18 |
19 |
75 |
76 |
99 |
--------------------------------------------------------------------------------
/src/components/ui/paletteButton/PaletteButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
24 |
41 |
42 |
58 |
--------------------------------------------------------------------------------
/src/components/ui/picker/Picker.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
18 |
22 |
26 |
27 |
多级联动
28 |
29 |
选择的是:{{pickerConf4.value}}
30 |
31 |
35 |
36 | 点击弹出
37 |
38 |
39 |
40 | 关闭
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
261 |
262 |
329 |
--------------------------------------------------------------------------------
/src/components/ui/popup/Popup.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
90 |
91 |
92 |
93 |
180 |
181 |
259 |
--------------------------------------------------------------------------------
/src/components/ui/progress/Progress.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
基本功能
12 |
13 |
14 | 默认
15 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
26 | 左右文字
27 |
28 |
29 |
33 | 0%
34 | 100%
35 |
36 |
37 |
38 |
39 |
44 | 上传文件
45 |
46 |
50 | {{showValue}}
51 |
52 |
58 | {{progressConf3.pauseText}}
59 |
60 |
66 | 取消上传
67 |
68 |
69 |
70 |
71 |
72 |
73 |
164 |
165 |
217 |
--------------------------------------------------------------------------------
/src/components/ui/radio/Radio.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
15 |
16 | {{radioConf1.value}}
17 |
18 |
19 |
23 |
24 | {{radioConf2.value}}
25 |
26 |
27 |
32 |
33 | {{radioConf3.value}}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
78 |
79 |
98 |
--------------------------------------------------------------------------------
/src/components/ui/range/Range.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
基本功能
12 |
13 |
14 |
默认
15 |
value : {{range1.value}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
左右文字
24 |
value : {{range2.value}}
25 |
26 |
27 |
28 | 0
29 | 100
30 |
31 |
32 |
33 |
34 |
35 |
自定义
36 |
37 |
38 |
自定义步长
39 |
value : {{range3.value}}
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
自定义区间
48 |
value : {{range4.value}}
49 |
50 |
51 |
52 | 10
53 | 90
54 |
55 |
56 |
57 |
58 |
59 |
定义线宽
60 |
value : {{range5.value}}
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
设置无效
69 |
value : {{range6.value}}
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
117 |
118 |
166 |
195 |
--------------------------------------------------------------------------------
/src/components/ui/search/Search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 返回
7 |
8 |
9 |
10 |
14 |
15 |
设置显示文字
16 |
21 |
22 |
23 |
30 |
31 |
自定义搜索结果
32 |
35 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
118 |
119 |
159 |
--------------------------------------------------------------------------------
/src/components/ui/spinner/Spinner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
47 |
48 |
63 |
--------------------------------------------------------------------------------
/src/components/ui/swipe/Swipe.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
20 | 1
21 | 2
22 | 3
23 |
24 |
25 |
26 |
27 |
28 |
29 |
59 |
60 |
85 |
--------------------------------------------------------------------------------
/src/components/ui/switch/Switch.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{value2 ? '开' : '关'}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
47 |
48 |
75 |
--------------------------------------------------------------------------------
/src/components/ui/toast/Toast.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 | 上方弹出Toast
12 | 中间弹出Toast
13 | 下方弹出Toast
14 | 带图标的弹出框
15 |
16 |
17 |
18 |
19 |
20 |
21 |
63 |
64 |
92 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 | import Mint from 'mint-ui';
4 | import 'mint-ui/lib/style.css'
5 | import './assets/css/index.styl'
6 | import 'assets/js/vconsole.min.js'
7 |
8 | import router from './router'
9 |
10 | Vue.use(Mint);
11 |
12 | Vue.config.productionTip = false
13 |
14 | /* eslint-disable no-new */
15 | new Vue({
16 | el: '#app',
17 | router,
18 | components: {App},
19 | template: ''
20 | })
21 |
--------------------------------------------------------------------------------
/src/page/advertisement/Advertisement.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 关闭
6 |
这里是广告位
7 |
8 |
9 |
10 |
11 |
12 |
26 |
27 |
59 |
--------------------------------------------------------------------------------
/src/page/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UI
6 |
7 |
8 | PLUS
9 |
10 |
11 | INTRODUCE
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
117 |
118 |
138 |
155 |
--------------------------------------------------------------------------------
/src/page/indexTab/IndexMine.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
说明与AQ
4 |
5 |
概况
6 |
7 | 此APP设计的最初目的是为了解决使用vue+webpack自动化构建并实时同步手机热更新调试而诞生。截止目前,Dcloud官方没有提供一套完整的vue+webpack+hbuilder实时开发调试的文章,只是零零散散有人去构建一些自己的项目,并不能很好地教会或者引导大量开发者使用该开发模式进行开发。本APP以构建流程为主,demo为辅,印证了vue+webpack+hbuilder实时调试以及打包的可行性,为开发者提供多开发种选择。
8 |
9 |
10 | 本APP与其他APP不同,该APP并不是功能性APP,所以几乎没有展示内容的业务逻辑,你可以把它理解为DCLOUD的muiAPP,做UIdemo的展示,并且验证PLUS在vue+webpack构建方式下的各类使用情况。更多的AQ可以在APP中的‘ABOUT’中得到解答。
11 |
Q1:该APP的主要技术架构
12 |
vue + webpack + mint-ui + hbuilder
13 |
Q2:调试与使用方式?
14 |
15 | 保持手机与电脑同一网段,服务起起后,将hbuilder起始页设置为本地服务器:端口号/index.html如
16 | 192.168.11.102:8080/index.html,同步手机。也可编译打包之后直接在根目录下面配置manifest.json,设置起始页面为index.html,同步手机。不同的webpack配置入口可能会导致入口文件有所不同,不过差异不大。
17 |
18 |
Q3:该APP有什么特色?
19 |
20 | 该项目除去说明与AQ主要分为两个板块,UI和PLUS。UI是对mint-ui官网demo的仿造与实际实践,100%迁移以及额外的扩展,更多的自定义demo展示与结合APP的运用,更加符合一款APP的基础需求。PLUS主要是对5+SDK的的集成运用,板块不是很多,主要对APP常用的几个功能进行了展示,PLUS的运用大同小异,PLUS的展示主要是验证5+在vue中的使用。此外,项目在页面中间右边位置增加了vconsole按钮,方便用户在终端进行log调试。
21 |
22 | 除了UI和PLUS之外,本APP还刻意围绕APP的常用功能进行了制作,比如索引页面、登陆与登出,登陆超时、广告弹出等等功能的基础实现原理,使得APP更加“高仿”。此外,对路由跳转的拦截、组件的封装、对公用代码mixin的使用等也体现了作者对APP的态度
23 |
24 |
Q4:webpack如何构建?
25 |
此项目中的webpack是仿造vue-cli的结构进行构建的,有自定义的修改以及配置项。单页面的构建方式可以参照代码,多页面的后续可能会考虑再出一款多页面的APP。不是很精通webpack的同学建议先去了解一下。
26 |
Q5:为什么不使用webpack4?
27 |
28 | 本产品最初采用webpack4.7进行开发。但最终使用了webpack使用了3.6,主要原因是很多开发者习惯用vue-cli进行项目的初始化构建,作者开发时vue-cli还处于3.6。截止目前为止,3.x依然是最稳定的版本之一。保持与当时的vue-cli生成的webpack版本一致,可以减少使用vue-cli开发者的配置修改。其次,作者开发时4.x除了官方维护的loader以外还有很多个人维护的loader没有兼容4.x版本,不利于个别情况的扩展。但这并非不能使用webpack4进行开发,如果您在看到这篇文章的时候4.x的各方生态以及处于稳定或者您只需用到基础的loader,,那么您完全可以使用webpack4代替,只需少许的修改即可。
29 |
30 |
Q6:多页面如何调试?
31 |
32 | 此APP采用了单页面路由跳转代替多页面使用webview进行跳转的方式,并不意味着不能使用多页面进行开发,相反,现在很多用JQ或者js开发APP多数还是多页面应用。多页面调试需要webpack配置多入口文件,页面跳转推荐使用webview,有兴趣的朋友可以尝试。
33 |
Q7:为什么不使用mui?
34 |
35 | 本示例使用了mint-ui。mui对vue开发来说并不是最优的选择,因为它主要还是以dom的形式存在。但并不影响您在开发过程中使用mui。
36 |
37 |
Q8:程序员也会饿肚子?
38 |
程序员也是人,如果该项目给您带来了工作上的参考或者启发,亦或者期待更多其他项目的诞生和该项目的继续维护,支持作者原创扫一扫或点击识别下方的二维码,为作者打赏1.0元吧!
39 |
点击或扫一扫下方这个二维码!
40 |

41 |
扫一扫下方这个二维码!
42 |

43 |
44 | 退出登陆
45 |
46 |
47 |
48 |
49 |
50 |
95 |
96 |
138 |
--------------------------------------------------------------------------------
/src/page/indexTab/IndexPlus.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
27 |
--------------------------------------------------------------------------------
/src/page/indexTab/IndexUi.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
37 |
38 |
49 |
--------------------------------------------------------------------------------
/src/page/login/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
hbuilder+vue+mint+webpack开发
6 |
欢迎您
7 |
8 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
62 |
63 |
148 |
--------------------------------------------------------------------------------
/src/page/mine/mine.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 我123
4 |
5 |
6 |
7 |
10 |
11 |
21 |
--------------------------------------------------------------------------------
/src/page/slider/Slider.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
16 |
欢迎使用vue-webpack-mint
17 | for hbuilder
18 |
19 |
20 |
21 |
22 |
制作
23 | By LJC
24 |
25 |
26 |
27 |
28 | 即将开始体验{{time}}
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
90 |
91 |
134 |
144 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import { routers, indexRouter } from 'ROUTER/router'
4 | import { MyLocalStorage } from 'assets/js/utils'
5 | import { SLIDER_FLAG, LOGIN_FLAG } from 'assets/js/storageConst'
6 | import { Toast } from 'mint-ui'
7 |
8 | console.log(SLIDER_FLAG)
9 |
10 | Vue.use(Router)
11 |
12 | // 路由配置
13 | const RouterConfig = {
14 | // mode: 'history',
15 | routes: routers
16 | }
17 |
18 | const router = new Router(RouterConfig)
19 |
20 | router.beforeEach((to, from, next) => {
21 | console.log("beforeEach")
22 | let slider_flag = localStorage.getItem(SLIDER_FLAG)
23 | let login_flag = MyLocalStorage.Cache.get(LOGIN_FLAG)
24 | if (to.name === 'slider' && !slider_flag) {
25 | console.log(111)
26 | next()
27 | } else if (!slider_flag) { // 没有索引页就跳转索引页
28 | console.log("2222")
29 | next({
30 | name: 'slider'
31 | })
32 | } else if (to.name !== 'login' && !login_flag) { // 没有登陆
33 | console.log(3333)
34 | if (from.name !== 'slider') {
35 | Toast({
36 | message: '登陆超时',
37 | position: 'bottom',
38 | duration: 3000
39 | })
40 | }
41 | next({
42 | name: 'login'
43 | })
44 | } else if (to.name === 'login' && !login_flag) {
45 | console.log(4444)
46 | next()
47 | } else {
48 | console.log(555)
49 | next()
50 | }
51 | })
52 |
53 | router.afterEach((to) => {
54 | window.scrollTo(0, 0)
55 | })
56 | export default router
57 |
--------------------------------------------------------------------------------
/src/router/router.js:
--------------------------------------------------------------------------------
1 | // 独立功能页面单独写,如下
2 | export const indexRouter = {
3 | path: '/',
4 | name: 'index',
5 | component: () => import('page/Index')
6 | }
7 |
8 | export const sliderRouter = {
9 | path: '/slider',
10 | name: 'slider',
11 | component: () => import('page/slider/Slider')
12 | }
13 |
14 | export const loginRouter = {
15 | path: '/login',
16 | name: 'login',
17 | component: () => import('page/login/Login')
18 | }
19 |
20 | export const advertisementRouter = {
21 | path: '/advertisement',
22 | name: 'advertisement',
23 | component: () => import('page/advertisement/Advertisement')
24 | }
25 |
26 | // ui
27 | export const uiRouters = [
28 | {
29 | path: '/ui/toast',
30 | name: 'toast',
31 | component: (resolve) => {
32 | import('components/ui/toast/Toast').then((module) => {
33 | resolve(module)
34 | })
35 | }
36 | },
37 | {
38 | path: '/ui/indicator',
39 | name: 'indicator',
40 | component: () => import('components/ui/indicator/Indicator')
41 | },
42 | {
43 | path: '/ui/loadmore',
44 | name: 'loadmore',
45 | component: () => import('components/ui/loadmore/Loadmore')
46 | },
47 | {
48 | path: '/ui/infinite-scroll',
49 | name: 'infiniteScroll',
50 | component: () => import('components/ui/infiniteScroll/InfiniteScroll')
51 | },
52 | {
53 | path: '/ui/message-box',
54 | name: 'messageBox',
55 | component: () => import('components/ui/messageBox/MessageBox')
56 | },
57 | {
58 | path: '/ui/action-sheet',
59 | name: 'actionSheet',
60 | component: () => import('components/ui/actionSheet/ActionSheet')
61 | },
62 | {
63 | path: '/ui/popup',
64 | name: 'popup',
65 | component: () => import('components/ui/popup/Popup')
66 | }, {
67 | path: '/ui/swipe',
68 | name: 'swipe',
69 | component: () => import('components/ui/swipe/Swipe')
70 | }, {
71 | path: '/ui/lazyLoad',
72 | name: 'lazyLoad',
73 | component: () => import('components/ui/lazyLoad/LazyLoad')
74 | },
75 | {
76 | path: '/ui/range',
77 | name: 'range',
78 | component: () => import('components/ui/range/Range')
79 | },
80 | {
81 | path: '/ui/progress',
82 | name: 'progress',
83 | component: () => import('components/ui/progress/Progress')
84 | },
85 | {
86 | path: '/ui/picker',
87 | name: 'picker',
88 | component: () => import('components/ui/picker/Picker')
89 | },
90 | {
91 | path: '/ui/datetime-picker',
92 | name: 'datetimePicker',
93 | component: () => import('components/ui/datetimePicker/DatetimePicker')
94 | },
95 | {
96 | path: '/ui/index-list',
97 | name: 'indexList',
98 | component: () => import('components/ui/indexList/IndexList')
99 | },
100 | {
101 | path: '/ui/palette-button',
102 | name: 'paletteButton',
103 | component: () => import('components/ui/paletteButton/PaletteButton')
104 | },
105 | {
106 | path: '/ui/header',
107 | name: 'header',
108 | component: () => import('components/ui/header/Header')
109 | },
110 | {
111 | path: '/ui/button',
112 | name: 'button',
113 | component: () => import('components/ui/button/Button')
114 | },
115 | {
116 | path: '/ui/cell',
117 | name: 'cell',
118 | component: () => import('components/ui/cell/Cell')
119 | }, {
120 | path: '/ui/spinner',
121 | name: 'spinner',
122 | component: () => import('components/ui/spinner/Spinner')
123 | }, {
124 | path: '/ui/search',
125 | name: 'search',
126 | component: () => import('components/ui/search/Search')
127 | },
128 | {
129 | path: '/ui/switch',
130 | name: 'switch',
131 | component: () => import('components/ui/switch/Switch')
132 | }, {
133 | path: '/ui/checklist',
134 | name: 'checklist',
135 | component: () => import('components/ui/checklist/Checklist')
136 | }, {
137 | path: '/ui/radio',
138 | name: 'radio',
139 | component: () => import('components/ui/radio/Radio')
140 | },
141 | {
142 | path: '/ui/field',
143 | name: 'field',
144 | component: () => import('components/ui/field/Field')
145 | },
146 | {
147 | path: '/ui/badge',
148 | name: 'badge',
149 | component: () => import('components/ui/badge/Badge')
150 | }
151 | ]
152 |
153 | export const plusRouters = [
154 | {
155 | path: '/plus/camera',
156 | name: 'camera',
157 | component: () => import('components/plus/camera/Camera')
158 | },
159 | {
160 | path: '/plus/geolocation',
161 | name: 'geolocation',
162 | component: () => import('components/plus/geolocation/Geolocation')
163 | },
164 | {
165 | path: '/plus/accelerometer',
166 | name: 'accelerometer',
167 | component: () => import('components/plus/accelerometer/Accelerometer')
168 | },
169 | {
170 | path: '/plus/resumeCallback',
171 | name: 'resumeCallback',
172 | component: () => import('components/plus/resumeCallback/ResumeCallback')
173 | },
174 | {
175 | path: '/plus/payment',
176 | name: 'payment',
177 | component: () => import('components/plus/payment/Payment')
178 | },
179 | {
180 | path: '/plus/router',
181 | name: 'router',
182 | component: () => import('components/plus/router/Router'),
183 | children: [
184 | {
185 | path: 'routerChildren:id',
186 | component: () => import('components/plus/router/RouterChildren')
187 | },
188 | ]
189 | }
190 | ]
191 |
192 | export const routers = [
193 | indexRouter,
194 | loginRouter,
195 | sliderRouter,
196 | advertisementRouter,
197 | ...uiRouters,
198 | ...plusRouters
199 | ]
200 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/static/.gitkeep
--------------------------------------------------------------------------------
/static/QR/weixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/static/QR/weixin.png
--------------------------------------------------------------------------------
/static/QR/zhifubao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/static/QR/zhifubao.png
--------------------------------------------------------------------------------
/static/media/shake.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wjsljc/vue-webpack-mint-for-hbuilder/a3bb8807cdcfc8d13ab69ab87a3b7189e5f2755e/static/media/shake.wav
--------------------------------------------------------------------------------
/unpackage/.confirmed_dependencies:
--------------------------------------------------------------------------------
1 | null
--------------------------------------------------------------------------------
/unpackage/.dependencies:
--------------------------------------------------------------------------------
1 | null
--------------------------------------------------------------------------------