├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── TODO ├── examples │ ├── picker-iscroll.vue │ ├── timer.vue │ └── transition.vue ├── src │ ├── button-collection.vue │ ├── grid.vue │ ├── picker-iscroll.vue │ ├── timer-task.vue │ ├── timer.vue │ └── transition.vue └── stastic │ ├── electricity-statistics.vue │ ├── interval.vue │ ├── utils.js │ └── vue-stone-replace.css ├── bin └── ghpages-merge.sh ├── build ├── build.js ├── check-versions.js ├── dev-client.js ├── dev-server.js ├── utils.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js ├── prod.env.js └── test.env.js ├── dist ├── iconfonts.css ├── iconfonts.js ├── img │ └── iconfont.e9c89e5.svg ├── vue-stone.css └── vue-stone.js ├── examples ├── App.vue ├── index.js └── pages │ ├── 404.vue │ ├── _example_style.vue │ ├── _tmpl_back.vue │ ├── action-sheet.vue │ ├── alert.vue │ ├── button.vue │ ├── checkboard.vue │ ├── control-center.vue │ ├── counter.vue │ ├── days-picker.vue │ ├── dialog.vue │ ├── icons.vue │ ├── input.vue │ ├── modes.vue │ ├── panel.vue │ ├── picker-loop.vue │ ├── picker.vue │ ├── range.vue │ ├── search.vue │ ├── slider.vue │ ├── switch.vue │ ├── textarea.vue │ ├── timepicker.vue │ └── toast.vue ├── index.html ├── libs ├── dependencies.js ├── initializer.js ├── intactify.js ├── timepicker.vue └── vue-logger.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── src ├── assets │ ├── home.png │ ├── loading.png │ ├── menu.png │ ├── mute.png │ └── return.png ├── components │ ├── _style.vue │ ├── _style_dependencies_fonts.vue │ ├── _style_iconfonts.vue │ ├── _style_transition.vue │ ├── action-box.vue │ ├── action-sheet.vue │ ├── alert.vue │ ├── button-group.vue │ ├── button-switch.vue │ ├── button.vue │ ├── checkboard.vue │ ├── confirm.vue │ ├── control-center.vue │ ├── counter.vue │ ├── dayspicker.vue │ ├── dialog.vue │ ├── icon.vue │ ├── input.vue │ ├── loading.vue │ ├── mask.vue │ ├── modes.vue │ ├── panel.vue │ ├── picker-loop.vue │ ├── picker.vue │ ├── power.vue │ ├── range.vue │ ├── search.vue │ ├── slide.vue │ ├── switch.vue │ ├── textarea.vue │ ├── timepicker.vue │ └── toast.vue ├── iconfonts.js ├── index.js ├── libs │ └── iscroll-lite.js ├── styles │ ├── animate.css │ ├── base.css │ ├── default-theme │ │ ├── themes.css │ │ └── variables.css │ ├── dependenciesFonts │ │ ├── fonts │ │ │ ├── iconfont.svg │ │ │ ├── iconfont.ttf │ │ │ └── iconfont.woff │ │ ├── selection.json │ │ └── style.css │ ├── fonts │ │ ├── fonts │ │ │ ├── iconfont.svg │ │ │ ├── iconfont.ttf │ │ │ └── iconfont.woff │ │ ├── selection.json │ │ └── style.css │ ├── mixins.css │ ├── normalize.css │ └── utils.css └── utils │ ├── common.js │ └── timer.js ├── test ├── e2e │ ├── custom-assertions │ │ └── elementCount.js │ ├── nightwatch.conf.js │ ├── reports │ │ └── CHROME_55.0.2883.59_MAC_test.xml │ ├── runner.js │ └── specs │ │ └── test.js └── unit │ ├── .eslintrc │ ├── coverage │ └── .DS_Store │ ├── helper.js │ ├── index.js │ ├── karma.conf.js │ └── specs │ ├── power.spec.js │ └── switch.spec.js ├── wiki ├── contribute-guide.md ├── doc-action-box.md ├── doc-action-sheet.md ├── doc-alert.md ├── doc-button-group.md ├── doc-button-switch.md ├── doc-button.md ├── doc-checkboard.md ├── doc-confirm.md ├── doc-control-center.md ├── doc-counter.md ├── doc-dayspicker.md ├── doc-dialog.md ├── doc-icon.md ├── doc-input.md ├── doc-loading.md ├── doc-mask.md ├── doc-modes.md ├── doc-panel.md ├── doc-picker-loop.md ├── doc-picker.md ├── doc-range.md ├── doc-search.md ├── doc-slide.md ├── doc-switch.md ├── doc-textarea.md ├── doc-timepicker.md ├── doc-timer.md ├── doc-toast.md ├── doc-transition.md ├── fe-code-style.md ├── format-of-docs.md ├── how-to-build-by-deps-in-project.md └── how-to-generator-the-webfont.md └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false 5 | } 6 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | src/units/*.js 4 | postcss.config.js 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | "browser": true, 4 | }, 5 | root: true, 6 | parser: 'babel-eslint', 7 | parserOptions: { 8 | sourceType: 'module' 9 | }, 10 | extends: 'airbnb-base', 11 | // required to lint *.vue files 12 | plugins: [ 13 | 'html' 14 | ], 15 | // check if imports actually resolve 16 | 'settings': { 17 | 'import/resolver': { 18 | 'webpack': { 19 | 'config': 'build/webpack.base.conf.js' 20 | } 21 | } 22 | }, 23 | // add your custom rules here 24 | 'rules': { 25 | 26 | "no-restricted-syntax": ["off", "BinaryExpression[operator='in']"], 27 | // don't require .vue extension when importing 28 | 'import/extensions': ['error', 'always', { 29 | 'js': 'never', 30 | 'vue': 'never' 31 | }], 32 | "import/imports-first": 0, 33 | 'import/no-dynamic-require': 0, 34 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 35 | "no-use-before-define": ["error", { "functions": false,}], 36 | "no-unused-vars": 0, 37 | "no-console": 0, 38 | "no-underscore-dangle": 0, 39 | "arrow-parens": 0, 40 | "no-param-reassign": 0, 41 | "no-unused-expressions": 0, 42 | "padded-blocks": 0, 43 | "prefer-const": 1, 44 | "linebreak-style":0, 45 | "max-len":0, 46 | "import/no-extraneous-dependencies": 0, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log 4 | test/unit/coverage/ 5 | .vscode/ 6 | sfp-config.js 7 | Temp.md 8 | 9 | selenium-debug.log 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .babelrc 3 | .editorconfig 4 | .eslintrc.js 5 | .gitignore 6 | .eslintignore 7 | .karrierconfig.js 8 | index.html 9 | TODO.md 10 | 11 | npm-debug.log 12 | sfp-config.js 13 | selenium-debug.log 14 | 15 | test/unit/coverage/ 16 | .vscode/ 17 | node_modules/ 18 | examples/ 19 | config/ 20 | build/ 21 | wiki/ 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Cong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-stone 2 | [![npm](https://img.shields.io/npm/v/vue-stone.svg?style=flat-square)](https://www.npmjs.com/package/vue-stone) 3 | [![npm](https://img.shields.io/npm/dm/vue-stone.svg?style=flat-square)](https://www.npmjs.com/package/vue-stone) 4 | [![GitHub issues](https://img.shields.io/github/issues/JD-Smart-FE/vue-stone.svg?style=flat-square)](https://github.com/JD-Smart-FE/vue-stone/issues) 5 | [![npm](https://img.shields.io/npm/l/vue-stone.svg?style=flat-square)](https://github.com/JD-Smart-FE/vue-stone/blob/master/LICENSE) 6 | > A components library for vue2.x. 一个基于 vue2.x 的组件库 7 | 8 | 9 | ## 安装 10 | 11 | ``` 12 | npm install --save vue-stone 13 | ``` 14 | 15 | ## 使用 16 | 17 | ### 本项目版本号规定 18 | 19 | 在本项目发布 1.0.0 版本之前,第二位版本号的更新**将不向下兼容**,第三位版本号向下兼容,通常为优化或 BUG 修复更新。 20 | 21 | 因此请**注意这里**:将 package.json 中 dependencies 字段下 `"vue-stone": "^0.4.0"` 版本号前面的 "^" 更改为 "~",暨 `"vue-stone": "~0.4.0"`。这样再执行 npm install 时,将只会安装第三位版本号的最新版。 22 | 23 | ### 使用前注意 24 | 本项目采用了 rem 布局方案,因此在引入该组件库前请在 HTML 文件 head 标签內添加下面一段 script: 25 | 26 | ```html 27 | 47 | ``` 48 | 49 | ### 开始使用 50 | 51 | Import vue-stone and register components 52 | 53 | ```js 54 | import Stone from 'vue-stone'; 55 | import 'vue-stone/dist/vue-stone.css'; 56 | 57 | // 如果你需要使用组件库中字体图标,请单独引入字体图标的 CSS 文件 58 | // import 'vue-stone/dist/iconfonts.css'; 59 | 60 | import Vue from 'vue'; 61 | 62 | Vue.use(Stone); // register components 63 | ``` 64 | 65 | ### 按需打包组件 66 | 67 | 受 webpack 打包策略所限,我们目前并没有将按需打包做的很简练,但至少目前还是做到了,具体步骤请查阅 [按需加载组件](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/how-to-build-by-deps-in-project.md) 68 | 69 | 如果你有更好的 idea,欢迎你为 vue-stone 贡献出一份力量。 70 | 71 | 72 | ## 文档 73 | vue-stone 组件库提供了下述组件,每个组件都带有详细的文档,组件展示可参考 [example](https://jd-smart-fe.github.io/vue-stone/) 74 | 75 | - [Action-box](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-action-box.md) 76 | - [Action-sheet](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-action-sheet.md) 77 | - [Alert](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-alert.md) 78 | - [Button](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-button.md) 79 | - [Button-group](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-button-group.md) 80 | - [Button-switch](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-button-switch.md) 81 | - [Checkboard](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-checkboard.md) 82 | - [Confirm](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-confirm.md) 83 | - [Counter](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-counter.md) 84 | - [Dayspicker](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-dayspicker.md) 85 | - [Dialog](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-dialog.md) 86 | - [Input](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-input.md) 87 | - [Loading](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-loading.md) 88 | - [Mask](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-mask.md) 89 | - [Modes](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-modes.md) 90 | - [Panel](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-panel.md) 91 | - [Picker-loop](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-picker-loop.md) 92 | - [Picker](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-picker.md) 93 | - [Range](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-range.md) 94 | - [Slide](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-slide.md) 95 | - [Switch](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-switch.md) 96 | - [Timepicker](https://github.com/jd-smart-fe/vue-stone/blob/master/wiki/doc-timepicker.md) 97 | - [Toast](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-toast.md) 98 | - [Control-center](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-control-center.md) 99 | - [Search](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-search.md) 100 | - [Textarea](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/doc-textarea.md) 101 | - [icon](https://github.com/JD-Smart-FE/vue-stone/blob/next/wiki/doc-icon.md) 102 | ## Contribute 103 | 104 | 贡献代码请遵循[代码贡献规范](https://github.com/JD-Smart-FE/vue-stone/blob/master/wiki/contribute-guide.md) 105 | 106 | ## Release Notes 107 | 108 | [查看更新内容](https://github.com/JD-Smart-FE/vue-stone/releases) 109 | -------------------------------------------------------------------------------- /TODO/examples/timer.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 152 | 153 | 164 | -------------------------------------------------------------------------------- /TODO/examples/transition.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 71 | 72 | 82 | -------------------------------------------------------------------------------- /TODO/src/button-collection.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 90 | 91 | 104 | -------------------------------------------------------------------------------- /TODO/src/grid.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | 15 | 27 | -------------------------------------------------------------------------------- /TODO/src/transition.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 26 | 27 | 171 | 181 | -------------------------------------------------------------------------------- /TODO/stastic/interval.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 156 | 170 | -------------------------------------------------------------------------------- /TODO/stastic/utils.js: -------------------------------------------------------------------------------- 1 | function getMonth(params) { 2 | return params.substr(5, 2); 3 | } 4 | function getDate(params) { 5 | return params.substr(8, 2); 6 | } 7 | const convertToCoordinate = params => { 8 | const unit = params.sum_unit; 9 | const sum = parseFloat(params.sum); 10 | const arg = parseFloat(params.arg); 11 | const axis = []; 12 | const details = []; 13 | let axisTimeUnit = ''; 14 | let unitType = ''; 15 | const originArr = params.detail; 16 | const originArrType = originArr.length ? originArr[0].desc : ''; 17 | if (originArrType === '小时') { 18 | // 天 19 | axisTimeUnit = unitType = '点'; 20 | } else if (originArrType.indexOf('星期') !== -1) { 21 | // 周 22 | axisTimeUnit = ''; 23 | unitType = '日'; 24 | } else if (originArrType.indexOf('-') !== -1) { 25 | // 月 26 | axisTimeUnit = unitType = '日'; 27 | } else if (originArrType.indexOf('月') !== -1) { 28 | // 年 29 | axisTimeUnit = unitType = '月'; 30 | } 31 | originArr.forEach((item, index) => { 32 | const axisItme = { time: '', value: 0 }; 33 | const detailsItem = { time: '', desc: '' }; 34 | // 用电量转为数值型,‘NaN’转为0 35 | if (item.value === 'NaN') { 36 | axisItme.value = 0; 37 | detailsItem.desc = '没有数据'; 38 | } else { 39 | axisItme.value = parseFloat(item.value); 40 | detailsItem.desc = item.value; 41 | } 42 | // 坐标轴的时间变量 43 | if (axisTimeUnit === '点') { 44 | // 天 45 | // axisItme.time = parseInt(item.datetime, 10) + ''; 46 | axisItme.time = parseInt(item.datetime, 10).toString(); 47 | // detailsItem.time = item.datetime + ':00'; 48 | detailsItem.time = `${item.datetime} :00`; 49 | } else if (axisTimeUnit === '') { 50 | // 周 51 | axisItme.time = getDate(item.datetime); 52 | detailsItem.time = 53 | // getMonth(item.datetime) + '月' + getDate(item.datetime) + '日'; 54 | `${getMonth(item.datetime)}月${getDate(item.datetime)}日`; 55 | } else if (axisTimeUnit === '日') { 56 | // 月 57 | // axisItme.time = parseInt(getDate(item.datetime), 10) + ''; 58 | axisItme.time = parseInt(getDate(item.datetime), 10).toString(); 59 | detailsItem.time = item.datetime; 60 | } else if (axisTimeUnit === '月') { 61 | // 年 62 | // axisItme.time = parseInt(getMonth(item.datetime), 10) + ''; 63 | axisItme.time = parseInt(getMonth(item.datetime), 10).toString(); 64 | detailsItem.time = item.desc; 65 | } 66 | axis.push(axisItme); 67 | details.push(detailsItem); 68 | }); 69 | return { 70 | axis, 71 | details, 72 | unit, 73 | sum, 74 | arg, 75 | unitType, 76 | }; 77 | }; 78 | export default convertToCoordinate; 79 | -------------------------------------------------------------------------------- /TODO/stastic/vue-stone-replace.css: -------------------------------------------------------------------------------- 1 | 2 | .header .c-mode-4 .c-mode-item { 3 | height: .3rem; 4 | border: 0; 5 | border-left: 1px solid #45A3F1; 6 | 7 | } 8 | .header .c-mode-4 .c-mode-item:nth-child(1) { 9 | height: .3rem; 10 | border-left: 0; 11 | 12 | } 13 | .header .c-mode-item-active { 14 | background: #45a3f1; 15 | 16 | } 17 | .header .c-mode-item-text { 18 | font-size: 0.13rem; 19 | } -------------------------------------------------------------------------------- /bin/ghpages-merge.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | git checkout gh-pages 4 | git merge -Xtheirs master -m "Merge branch master into branch gh-pages" 5 | git push 6 | git checkout master 7 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | // https://github.com/shelljs/shelljs 2 | require('./check-versions')() 3 | require('shelljs/global') 4 | 5 | env.NODE_ENV = 'production' 6 | 7 | var path = require('path') 8 | var config = require('../config') 9 | var ora = require('ora') 10 | var webpack = require('webpack') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | console.log( 14 | ' Tip:\n' + 15 | ' Built files are meant to be served over an HTTP server.\n' + 16 | ' Opening index.html over file:// won\'t work.\n' 17 | ) 18 | 19 | var spinner = ora('building for production...') 20 | spinner.start() 21 | 22 | var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory) 23 | rm('-rf', assetsPath) 24 | mkdir('-p', assetsPath) 25 | cp('-R', 'static/*', assetsPath) 26 | 27 | webpack(webpackConfig, function (err, stats) { 28 | spinner.stop() 29 | if (err) throw err 30 | process.stdout.write(stats.toString({ 31 | colors: true, 32 | modules: false, 33 | children: false, 34 | chunks: false, 35 | chunkModules: false 36 | }) + '\n') 37 | }) 38 | 39 | 40 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | var semver = require('semver') 2 | var chalk = require('chalk') 3 | var packageConfig = require('../package.json') 4 | var exec = function (cmd) { 5 | return require('child_process') 6 | .execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | { 16 | name: 'npm', 17 | currentVersion: exec('npm --version'), 18 | versionRequirement: packageConfig.engines.npm 19 | } 20 | ] 21 | 22 | module.exports = function () { 23 | var warnings = [] 24 | for (var i = 0; i < versionRequirements.length; i++) { 25 | var mod = versionRequirements[i] 26 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 27 | warnings.push(mod.name + ': ' + 28 | chalk.red(mod.currentVersion) + ' should be ' + 29 | chalk.green(mod.versionRequirement) 30 | ) 31 | } 32 | } 33 | 34 | if (warnings.length) { 35 | console.log('') 36 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 37 | console.log() 38 | for (var i = 0; i < warnings.length; i++) { 39 | var warning = warnings[i] 40 | console.log(' ' + warning) 41 | } 42 | console.log() 43 | process.exit(1) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | var config = require('../config') 3 | if (!process.env.NODE_ENV) process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 4 | var path = require('path') 5 | var express = require('express') 6 | var webpack = require('webpack') 7 | var opn = require('opn') 8 | var proxyMiddleware = require('http-proxy-middleware') 9 | var webpackConfig = process.env.NODE_ENV === 'testing' 10 | ? require('./webpack.prod.conf') 11 | : require('./webpack.dev.conf') 12 | 13 | // default port where dev server listens for incoming traffic 14 | var port = process.env.PORT || config.dev.port 15 | // Define HTTP proxies to your custom API backend 16 | // https://github.com/chimurai/http-proxy-middleware 17 | var proxyTable = config.dev.proxyTable 18 | 19 | var app = express() 20 | var compiler = webpack(webpackConfig) 21 | 22 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 23 | publicPath: webpackConfig.output.publicPath, 24 | stats: { 25 | colors: true, 26 | chunks: false 27 | } 28 | }) 29 | 30 | var hotMiddleware = require('webpack-hot-middleware')(compiler) 31 | // force page reload when html-webpack-plugin template changes 32 | compiler.plugin('compilation', function (compilation) { 33 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 34 | hotMiddleware.publish({ action: 'reload' }) 35 | cb() 36 | }) 37 | }) 38 | 39 | // proxy api requests 40 | Object.keys(proxyTable).forEach(function (context) { 41 | var options = proxyTable[context] 42 | if (typeof options === 'string') { 43 | options = { target: options } 44 | } 45 | app.use(proxyMiddleware(context, options)) 46 | }) 47 | 48 | // handle fallback for HTML5 history API 49 | app.use(require('connect-history-api-fallback')()) 50 | 51 | // serve webpack bundle output 52 | app.use(devMiddleware) 53 | 54 | // enable hot-reload and state-preserving 55 | // compilation error display 56 | app.use(hotMiddleware) 57 | 58 | // serve pure static assets 59 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 60 | app.use(staticPath, express.static('./static')) 61 | 62 | module.exports = app.listen(port, function (err) { 63 | if (err) { 64 | console.log(err) 65 | return 66 | } 67 | var uri = 'http://localhost:' + port 68 | console.log('Listening at ' + uri + '\n') 69 | 70 | // when env is testing, don't need open it 71 | if (process.env.NODE_ENV !== 'testing') { 72 | opn(uri) 73 | } 74 | }) 75 | -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | var assetsSubDirectory = process.env.NODE_ENV === 'production' 7 | ? config.build.assetsSubDirectory 8 | : config.dev.assetsSubDirectory 9 | return path.posix.join(assetsSubDirectory, _path) 10 | } 11 | 12 | exports.cssLoaders = function (options) { 13 | options = options || {} 14 | // generate loader string to be used with extract text plugin 15 | function generateLoaders (loaders) { 16 | var sourceLoader = loaders.map(function (loader) { 17 | var extraParamChar 18 | if (/\?/.test(loader)) { 19 | loader = loader.replace(/\?/, '-loader?') 20 | extraParamChar = '&' 21 | } else { 22 | loader = loader + '-loader' 23 | extraParamChar = '?' 24 | } 25 | return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') 26 | }).join('!') 27 | 28 | // Extract CSS when that option is specified 29 | // (which is the case during production build) 30 | if (options.extract) { 31 | return ExtractTextPlugin.extract('vue-style-loader', sourceLoader) 32 | } else { 33 | return ['vue-style-loader', sourceLoader].join('!') 34 | } 35 | } 36 | 37 | // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html 38 | return { 39 | css: generateLoaders(['css?-autoprefixer']), 40 | postcss: generateLoaders(['css?-autoprefixer']), 41 | less: generateLoaders(['css?-autoprefixer', 'less']), 42 | sass: generateLoaders(['css?-autoprefixer', 'sass?indentedSyntax']), 43 | scss: generateLoaders(['css?-autoprefixer', 'sass']), 44 | stylus: generateLoaders(['css?-autoprefixer', 'stylus']), 45 | styl: generateLoaders(['css?-autoprefixer', 'stylus']) 46 | } 47 | } 48 | 49 | // Generate loaders for standalone style files (outside of .vue) 50 | exports.styleLoaders = function (options) { 51 | var output = [] 52 | var loaders = exports.cssLoaders(options) 53 | for (var extension in loaders) { 54 | var loader = loaders[extension] 55 | output.push({ 56 | test: new RegExp('\\.' + extension + '$'), 57 | loader: loader 58 | }) 59 | } 60 | return output 61 | } 62 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var utils = require('./utils') 4 | var precss = require('precss'); 5 | var ContextReplacementPlugin = require("webpack/lib/ContextReplacementPlugin"); 6 | 7 | var projectRoot = path.resolve(__dirname, '../') 8 | var list = require('../libs/initializer.js').components; 9 | var comsreg = new RegExp(`(${list.join('|')})\.vue$`); 10 | 11 | var env = process.env.NODE_ENV 12 | // check env & config/index.js to decide weither to enable CSS Sourcemaps for the 13 | // various preprocessor loaders added to vue-loader at the end of this file 14 | var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap) 15 | var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap) 16 | var useCssSourceMap = cssSourceMapDev || cssSourceMapProd 17 | 18 | module.exports = { 19 | entry: { 20 | app: './examples/index.js' 21 | }, 22 | output: { 23 | path: config.build.assetsRoot, 24 | publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, 25 | filename: '[name].js' 26 | }, 27 | resolve: { 28 | extensions: ['', '.js', '.vue'], 29 | fallback: [path.join(__dirname, '../node_modules')], 30 | alias: { 31 | 'vue$': 'vue/dist/vue.common.js', 32 | 'src': path.resolve(__dirname, '../src'), 33 | 'assets': path.resolve(__dirname, '../src/assets'), 34 | 'components': path.resolve(__dirname, '../src/components') 35 | } 36 | }, 37 | resolveLoader: { 38 | fallback: [path.join(__dirname, '../node_modules')] 39 | }, 40 | module: { 41 | preLoaders: [ 42 | { 43 | test: /\.vue$/, 44 | loader: 'eslint', 45 | include: projectRoot, 46 | exclude: /node_modules/ 47 | }, 48 | { 49 | test: /\.js$/, 50 | loader: 'eslint', 51 | include: projectRoot, 52 | exclude: /node_modules/ 53 | } 54 | ], 55 | loaders: [ 56 | { 57 | test: /\.vue$/, 58 | loader: 'vue' 59 | }, 60 | { 61 | test: /\.js$/, 62 | loader: 'babel', 63 | include: projectRoot, 64 | exclude: /node_modules/ 65 | }, 66 | { 67 | test: /\.json$/, 68 | loader: 'json' 69 | }, 70 | { 71 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 72 | loader: 'url', 73 | query: { 74 | limit: 10000, 75 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 76 | } 77 | }, 78 | { 79 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 80 | loader: 'url', 81 | query: { 82 | limit: 100000, 83 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 84 | } 85 | } 86 | ] 87 | }, 88 | eslint: { 89 | formatter: require('eslint-friendly-formatter') 90 | }, 91 | plugins: [ 92 | new ContextReplacementPlugin( 93 | /components$/, 94 | comsreg 95 | ) 96 | ], 97 | vue: { 98 | loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }), 99 | postcss: [ 100 | precss, 101 | require('autoprefixer')({ 102 | browsers: ['last 2 versions','Android >= 4.2','iOS >= 6', '>1%'] 103 | }) 104 | ] 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var config = require('../config') 2 | var webpack = require('webpack') 3 | var merge = require('webpack-merge') 4 | var utils = require('./utils') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | 8 | // add hot-reload related code to entry chunks 9 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 10 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 11 | }) 12 | 13 | module.exports = merge(baseWebpackConfig, { 14 | module: { 15 | loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 16 | }, 17 | // eval-source-map is faster for development 18 | devtool: '#eval-source-map', 19 | plugins: [ 20 | new webpack.DefinePlugin({ 21 | 'process.env': config.dev.env 22 | }), 23 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 24 | new webpack.optimize.OccurenceOrderPlugin(), 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }) 33 | ] 34 | }) 35 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var utils = require('./utils') 4 | var webpack = require('webpack') 5 | var merge = require('webpack-merge') 6 | var baseWebpackConfig = require('./webpack.base.conf') 7 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 8 | var HtmlWebpackPlugin = require('html-webpack-plugin') 9 | var env = process.env.NODE_ENV === 'testing' 10 | ? require('../config/test.env') 11 | : config.build.env 12 | 13 | 14 | var webpackConfig = merge(baseWebpackConfig, { 15 | 16 | entry: { 17 | 'vue-stone': './src/index.js', 18 | 'iconfonts': './src/iconfonts.js', 19 | }, 20 | 21 | module: { 22 | loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true }) 23 | }, 24 | devtool: config.build.productionSourceMap ? '#source-map' : false, 25 | output: { 26 | path: config.build.assetsRoot, 27 | chunkFilename: utils.assetsPath('[id].js'), 28 | 29 | filename: utils.assetsPath('[name].js'), 30 | library: 'vue-stone', 31 | libraryTarget: 'umd', 32 | umdNamedDefine: true, 33 | }, 34 | vue: { 35 | loaders: utils.cssLoaders({ 36 | sourceMap: config.build.productionSourceMap, 37 | extract: true 38 | }) 39 | }, 40 | plugins: [ 41 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 42 | new webpack.DefinePlugin({ 43 | 'process.env': env 44 | }), 45 | new webpack.optimize.UglifyJsPlugin({ 46 | compress: { 47 | warnings: false 48 | } 49 | }), 50 | new webpack.optimize.OccurrenceOrderPlugin(), 51 | 52 | new ExtractTextPlugin(utils.assetsPath('[name].css')), 53 | 54 | // new HtmlWebpackPlugin({ 55 | // filename: process.env.NODE_ENV === 'testing' 56 | // ? 'index.html' 57 | // : config.build.index, 58 | // template: 'index.html', 59 | // inject: true, 60 | // // necessary to consistently work with multiple chunks via CommonsChunkPlugin 61 | // chunksSortMode: 'dependency' 62 | // }), 63 | ] 64 | }) 65 | 66 | delete webpackConfig.entry.app; 67 | 68 | if (config.build.productionGzip) { 69 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 70 | 71 | webpackConfig.plugins.push( 72 | new CompressionWebpackPlugin({ 73 | asset: '[path].gz[query]', 74 | algorithm: 'gzip', 75 | test: new RegExp( 76 | '\\.(' + 77 | config.build.productionGzipExtensions.join('|') + 78 | ')$' 79 | ), 80 | threshold: 10240, 81 | minRatio: 0.8 82 | }) 83 | ) 84 | } 85 | 86 | module.exports = webpackConfig 87 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: '', 10 | assetsPublicPath: '/', 11 | productionSourceMap: false, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'] 18 | }, 19 | dev: { 20 | env: require('./dev.env'), 21 | port: 8086, 22 | assetsSubDirectory: 'static', 23 | assetsPublicPath: '/', 24 | proxyTable: {}, 25 | // CSS Sourcemaps off by default because relative paths are "buggy" 26 | // with this option, according to the CSS-Loader README 27 | // (https://github.com/webpack/css-loader#sourcemaps) 28 | // In our experience, they generally work as expected, 29 | // just be aware of this issue when enabling this option. 30 | cssSourceMap: false 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /dist/iconfonts.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("vue-stone",[],t):"object"==typeof exports?exports["vue-stone"]=t():e["vue-stone"]=t()}(this,function(){return function(e){function t(n){if(o[n])return o[n].exports;var r=o[n]={exports:{},id:n,loaded:!1};return e[n].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var o={};return t.m=e,t.c=o,t.p="/",t(0)}({0:function(e,t,o){"use strict";o(248)},1:function(e,t){e.exports=function(e,t,o,n){var r,u=e=e||{},c=typeof e.default;"object"!==c&&"function"!==c||(r=e,u=e.default);var f="function"==typeof u?u.options:u;if(t&&(f.render=t.render,f.staticRenderFns=t.staticRenderFns),o&&(f._scopeId=o),n){var s=f.computed||(f.computed={});Object.keys(n).forEach(function(e){var t=n[e];s[e]=function(){return t}})}return{esModule:r,exports:u,options:f}}},103:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={}},235:function(e,t){},248:function(e,t,o){o(235);var n=o(1)(o(103),null,null,null);e.exports=n.exports}})}); -------------------------------------------------------------------------------- /examples/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | 4 | import App from './App'; 5 | import Store from 'src/index'; 6 | import '../src/components/_style_iconfonts'; 7 | 8 | import './pages/_example_style'; 9 | import TmplBack from './pages/_tmpl_back'; 10 | 11 | const list = [{ 12 | name: '404', 13 | }, { 14 | name: 'button', 15 | }, { 16 | name: 'range', 17 | }, { 18 | name: 'panel', 19 | }, { 20 | name: 'icons', 21 | }, { 22 | name: 'days-picker', 23 | }, { 24 | name: 'modes', 25 | }, { 26 | name: 'slider', 27 | }, { 28 | name: 'action-sheet', 29 | }, { 30 | name: 'dialog', 31 | }, { 32 | name: 'alert', 33 | }, { 34 | name: 'input', 35 | }, { 36 | name: 'counter', 37 | }, { 38 | name: 'picker-loop', 39 | }, { 40 | name: 'picker', 41 | }, { 42 | name: 'timepicker', 43 | }, { 44 | name: 'switch', 45 | }, { 46 | name: 'toast', 47 | }, { 48 | name: 'control-center', 49 | }, { 50 | name: 'search', 51 | }, { 52 | name: 'checkboard', 53 | }, { 54 | name: 'textarea', 55 | }]; 56 | 57 | Vue.use(VueRouter); 58 | Vue.use(Store); 59 | 60 | Vue.component('tmpl-back', TmplBack); 61 | 62 | const routes = [{ path: '/', component: App }, 63 | /* eslint-disable global-require */ 64 | ...list.map((item) => { 65 | const route = { 66 | path: `/${item.name}`, 67 | component: require(`./pages/${item.name}`), 68 | }; 69 | return route; 70 | }), 71 | ]; 72 | 73 | const router = new VueRouter({ 74 | routes, 75 | }); 76 | 77 | /* eslint-disable no-new */ 78 | const app = new Vue({ 79 | router, 80 | template: ` 81 |
82 | 83 | 84 | 85 |
86 | `, 87 | }).$mount('#app'); 88 | -------------------------------------------------------------------------------- /examples/pages/404.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | 17 | 22 | -------------------------------------------------------------------------------- /examples/pages/_example_style.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 50 | -------------------------------------------------------------------------------- /examples/pages/_tmpl_back.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /examples/pages/action-sheet.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 76 | 77 | 81 | -------------------------------------------------------------------------------- /examples/pages/alert.vue: -------------------------------------------------------------------------------- 1 | 20 | 65 | -------------------------------------------------------------------------------- /examples/pages/checkboard.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 80 | 81 | 85 | -------------------------------------------------------------------------------- /examples/pages/counter.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 65 | 66 | 79 | -------------------------------------------------------------------------------- /examples/pages/days-picker.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 41 | 42 | 44 | -------------------------------------------------------------------------------- /examples/pages/dialog.vue: -------------------------------------------------------------------------------- 1 | 25 | 55 | 56 | 69 | -------------------------------------------------------------------------------- /examples/pages/input.vue: -------------------------------------------------------------------------------- 1 | 84 | 85 | 105 | 106 | 110 | -------------------------------------------------------------------------------- /examples/pages/modes.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 172 | 173 | 177 | -------------------------------------------------------------------------------- /examples/pages/panel.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 60 | 61 | 69 | -------------------------------------------------------------------------------- /examples/pages/range.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 116 | 117 | 120 | -------------------------------------------------------------------------------- /examples/pages/search.vue: -------------------------------------------------------------------------------- 1 | 22 | 90 | 91 | 95 | -------------------------------------------------------------------------------- /examples/pages/slider.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 56 | 57 | 61 | -------------------------------------------------------------------------------- /examples/pages/switch.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 69 | 70 | 74 | -------------------------------------------------------------------------------- /examples/pages/textarea.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 30 | -------------------------------------------------------------------------------- /examples/pages/timepicker.vue: -------------------------------------------------------------------------------- 1 | 7 | 11 | 12 | 14 | -------------------------------------------------------------------------------- /examples/pages/toast.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 73 | 74 | 77 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | stone 9 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /libs/dependencies.js: -------------------------------------------------------------------------------- 1 | const intactify = require('./intactify'); 2 | 3 | /* eslint-disable no-var */ 4 | /** 5 | * 列出了组件间的相互依赖关系 6 | */ 7 | var dependencies = { 8 | alert: ['dialog'], 9 | confirm: ['dialog'], 10 | loading: ['toast'], 11 | dayspicker: ['button'], 12 | dialog: ['mask'], 13 | counter: ['button'], 14 | 'button-group': ['button'], 15 | 'button-switch': ['button'], 16 | 'action-sheet': ['mask', 'action-box'], 17 | 'action-box': ['mask'], 18 | timer: ['panel', 'timepicker', 'modes', 'dialog', 19 | 'switch', 'dayspicker', 'timer-task', 'input', 'checkboard', 20 | ], 21 | 'timer-task': ['panel', 'modes', 'range', 'counter'], 22 | timepicker: ['picker'], 23 | }; 24 | 25 | module.exports = function dep(list) { 26 | return intactify(dependencies, list); 27 | }; 28 | -------------------------------------------------------------------------------- /libs/initializer.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | components: [ 3 | 'dayspicker', 4 | 'range', 5 | 'switch', 6 | 'power', 7 | 'panel', 8 | 'dialog', 9 | 'alert', 10 | 'confirm', 11 | 'button', 12 | 'button-switch', 13 | 'button-group', 14 | 'counter', 15 | 'modes', 16 | 'mask', 17 | 'picker-loop', 18 | 'picker', 19 | 'checkboard', 20 | 'action-sheet', 21 | 'action-box', 22 | 'input', 23 | // 'timer', 24 | // 'timer-task', 25 | 'timepicker', 26 | // 'transition', // 引入了整个 animation.css 导致样式文件过大 27 | 'slide', 28 | 'toast', 29 | 'loading', 30 | 'control-center', 31 | 'search', 32 | 'textarea', 33 | 'icon', 34 | ], 35 | }; 36 | -------------------------------------------------------------------------------- /libs/intactify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 这里用 export default 而不是 module.exports 是因为在 webpack2 下, 3 | * 会对 `module.exports intactify` 报错 `Cannot assign to read only property 'exports' of object '#' (mix require and export) ` 4 | * 令人费解。 5 | * 6 | * https://github.com/webpack/webpack/issues/4039 这个 issue 指明了 混用 require 和 export 会产生报错, 7 | * 但是在这里并不存在 require 和 export 混用的情况。因此这个报错令人费解 8 | * 9 | * 2018-04-25 10 | * @pspgbhu 11 | * 发现如果在 intactify 函数中去掉一些高级语法就不会产生上述报错。 12 | */ 13 | 14 | /* eslint-disable */ 15 | module.exports = function intactify(depe_, list_) { 16 | var length = list_.length; 17 | var _list = list_.concat(); 18 | 19 | // // 有相关依赖的组件 20 | var _l = list_.filter(val => { 21 | for (var key in depe_) { 22 | if (Object.prototype.hasOwnProperty.call(depe_, key)) { 23 | if (key === val) { 24 | return true; 25 | } 26 | } 27 | } 28 | return false; 29 | }); 30 | 31 | // // 添加相关依赖 32 | _l.forEach(val => { 33 | // 依赖去重 34 | const needPush = depe_[val].filter(item => _list.indexOf(item) === -1); 35 | // 将新依赖推入数组 36 | _list.push.apply(_list, needPush); 37 | }); 38 | 39 | // // 如果数组长度没有发生变化,说明没有新的相关依赖组件 40 | if (length === _list.length) { 41 | // 赋值 42 | return _list; 43 | } 44 | 45 | // // 递归调用 46 | return intactify(depe_, _list); 47 | } 48 | -------------------------------------------------------------------------------- /libs/timepicker.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /libs/vue-logger.js: -------------------------------------------------------------------------------- 1 | const VueLogger = { 2 | name: 'vue-logger', 3 | }; 4 | 5 | VueLogger.install = (Vue, options) => { 6 | 7 | // let methods = {}; 8 | 9 | // ['log', 'warn', 'error'].forEach((op) => { 10 | // methods[`$${op}`] = (...str) => { 11 | // if (process.env.NODE_ENV === 'production') { 12 | // return; 13 | // } 14 | // str.unshift(`Component ${this.$options.name} `); 15 | // console[op](...str); 16 | // }; 17 | // }); 18 | 19 | // Vue.mixin({ 20 | // methods, 21 | // }); 22 | 23 | const defaults = { 24 | silent: Vue.config.silent, 25 | format: (...str) => { 26 | str.unshift('[Vue Logger]: '); 27 | return str; 28 | }, 29 | }; 30 | 31 | options = Object.assign({}, defaults, options); 32 | 33 | 34 | /* eslint-disable func-names */ 35 | ['log', 'warn', 'error'].forEach((op) => { 36 | Vue.prototype[`$${op}`] = function (...str) { 37 | 38 | if (options.silent) { 39 | return; 40 | } 41 | 42 | str = options.format.apply(this, str); 43 | 44 | console[op](...str); 45 | }; 46 | }); 47 | }; 48 | 49 | export default VueLogger; 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-stone", 3 | "version": "1.0.0", 4 | "description": "vue component", 5 | "author": "zhengyuelin zhengyuelin@jd.com pspgbhu", 6 | "main": "dist/vue-stone.js", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/JD-Smart-FE/vue-stone.git" 11 | }, 12 | "keywords": [ 13 | "vue", 14 | "components" 15 | ], 16 | "bugs": { 17 | "url": "https://github.com/JD-Smart-FE/vue-stone/issues" 18 | }, 19 | "scripts": { 20 | "start": "npm run dev", 21 | "dev": "node build/dev-server.js", 22 | "build": "node build/build.js", 23 | "lint": "eslint --ext .js,.vue src", 24 | "preversion": "npm run lint", 25 | "version": "npm run build && git add -A dist", 26 | "postversion": "npm publish && git push", 27 | "release:beta": "npm version prerelease", 28 | "release:patch": "npm version patch", 29 | "release:minor": "npm version minor", 30 | "ghpages": "./bin/ghpages-merge.sh" 31 | }, 32 | "dependencies": { 33 | "@antv/f2": "^3.2.2", 34 | "core-js": "^3.6.5", 35 | "dayjs": "^1.7.5", 36 | "vue": "^2.3.4" 37 | }, 38 | "peerDependencies": { 39 | "vue": "2.x" 40 | }, 41 | "devDependencies": { 42 | "autoprefixer": "^6.4.0", 43 | "babel-core": "^6.0.0", 44 | "babel-eslint": "^7.0.0", 45 | "babel-loader": "^6.0.0", 46 | "babel-plugin-transform-runtime": "^6.0.0", 47 | "babel-preset-es2015": "^6.0.0", 48 | "babel-preset-stage-2": "^6.0.0", 49 | "babel-register": "^6.0.0", 50 | "chalk": "^1.1.3", 51 | "chromedriver": "^2.21.2", 52 | "connect-history-api-fallback": "^1.1.0", 53 | "cross-spawn": "^4.0.2", 54 | "css-loader": "^0.25.0", 55 | "eslint": "^3.7.1", 56 | "eslint-config-airbnb-base": "^8.0.0", 57 | "eslint-friendly-formatter": "^2.0.5", 58 | "eslint-import-resolver-webpack": "^0.6.0", 59 | "eslint-loader": "^1.5.0", 60 | "eslint-plugin-html": "^1.3.0", 61 | "eslint-plugin-import": "^1.16.0", 62 | "eventsource-polyfill": "^0.9.6", 63 | "express": "^4.13.3", 64 | "extract-text-webpack-plugin": "^1.0.1", 65 | "file-loader": "^0.9.0", 66 | "fs-extra": "^7.0.1", 67 | "function-bind": "^1.0.2", 68 | "html-webpack-plugin": "^2.8.1", 69 | "http-proxy-middleware": "^0.17.2", 70 | "inject-loader": "^2.0.1", 71 | "isparta-loader": "^2.0.0", 72 | "json-loader": "^0.5.4", 73 | "karrier": "^0.1.4", 74 | "lolex": "^1.4.0", 75 | "opn": "^4.0.2", 76 | "ora": "^0.3.0", 77 | "precss": "^1.4.0", 78 | "selenium-server": "2.53.1", 79 | "semver": "^5.5.0", 80 | "shelljs": "^0.7.4", 81 | "url-loader": "^0.5.7", 82 | "vue-loader": "^10.0.0", 83 | "vue-router": "^2.4.0", 84 | "vue-style-loader": "^1.0.0", 85 | "vue-template-compiler": "^2.1.0", 86 | "webpack": "^1.13.2", 87 | "webpack-dev-middleware": "^1.8.3", 88 | "webpack-hot-middleware": "^2.12.2", 89 | "webpack-merge": "^0.14.1" 90 | }, 91 | "engines": { 92 | "node": ">= 4.0.0", 93 | "npm": ">= 3.0.0" 94 | }, 95 | "config": { 96 | "commitizen": { 97 | "path": "./node_modules/cz-conventional-changelog" 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: zhaohongyun1@jd.com 3 | * @Date: 2020-07-19 11:39:58 4 | * @LastEditors: Please set LastEditors 5 | * @LastEditTime: 2020-07-19 11:40:46 6 | */ 7 | module.exports = { 8 | plugins: { 9 | autoprefixer: { browsers: "last 5 version" }, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /src/assets/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/assets/home.png -------------------------------------------------------------------------------- /src/assets/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/assets/loading.png -------------------------------------------------------------------------------- /src/assets/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/assets/menu.png -------------------------------------------------------------------------------- /src/assets/mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/assets/mute.png -------------------------------------------------------------------------------- /src/assets/return.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/assets/return.png -------------------------------------------------------------------------------- /src/components/_style.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | -------------------------------------------------------------------------------- /src/components/_style_dependencies_fonts.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /src/components/_style_iconfonts.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /src/components/_style_transition.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 14 | -------------------------------------------------------------------------------- /src/components/action-box.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 66 | 67 | 91 | -------------------------------------------------------------------------------- /src/components/action-sheet.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 129 | 130 | 164 | -------------------------------------------------------------------------------- /src/components/alert.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 110 | -------------------------------------------------------------------------------- /src/components/button-group.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /src/components/button-switch.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 109 | 110 | 132 | -------------------------------------------------------------------------------- /src/components/confirm.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 81 | 82 | 87 | -------------------------------------------------------------------------------- /src/components/counter.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 146 | 147 | 173 | -------------------------------------------------------------------------------- /src/components/icon.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 30 | 31 | 36 | -------------------------------------------------------------------------------- /src/components/input.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 123 | 184 | -------------------------------------------------------------------------------- /src/components/loading.vue: -------------------------------------------------------------------------------- 1 | 8 | 21 | 22 | 92 | 93 | 167 | -------------------------------------------------------------------------------- /src/components/mask.vue: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | 67 | 68 | 79 | -------------------------------------------------------------------------------- /src/components/panel.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 27 | 28 | 100 | -------------------------------------------------------------------------------- /src/components/power.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 76 | 77 | 131 | -------------------------------------------------------------------------------- /src/components/search.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 141 | 194 | -------------------------------------------------------------------------------- /src/components/switch.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 107 | 108 | 172 | -------------------------------------------------------------------------------- /src/components/textarea.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 69 | 70 | -------------------------------------------------------------------------------- /src/components/toast.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 89 | 90 | 168 | -------------------------------------------------------------------------------- /src/iconfonts.js: -------------------------------------------------------------------------------- 1 | import './components/_style_iconfonts'; 2 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import VueLogger from '../libs/vue-logger'; 2 | import Initializer from '../libs/initializer'; 3 | import dependencies from '../libs/dependencies'; 4 | import './utils/common'; 5 | 6 | // 引入全局样式 7 | import './components/_style'; 8 | 9 | const install = (Vue, options = {}) => { 10 | if (install.installed) { 11 | return; 12 | } 13 | 14 | const components = dependencies(options.components ? options.components : Initializer.components); 15 | const singletonComponents = []; 16 | 17 | /* eslint-disable global-require */ 18 | components.every(val => { 19 | 20 | // _style 开头的样式组件,只需引入不需要注册为组件 21 | // if (val.indexOf('_style') !== -1) { 22 | // require(`./components/${val}.vue`); 23 | // return true; 24 | // } 25 | 26 | const comp = require(`./components/${val}.vue`); 27 | // 按需打包的时候,有时需要用 comp.default 才能访问到组件对象 28 | const Component = Vue.extend( 29 | comp.name ? comp : comp.default 30 | ); 31 | if (Component.options.type === 'singleton') { 32 | singletonComponents.push(Component); 33 | } 34 | Vue.component(Component.options.name, Component); 35 | return true; 36 | }); 37 | 38 | singletonComponents.forEach((Component) => { 39 | const instance = new Component({ 40 | el: document.createElement(Component.options.tag || 'div'), 41 | }); 42 | Vue.prototype[`$${Component.options.name.replace('v-', '')}`] = instance; 43 | }); 44 | 45 | VueLogger.install(Vue, { 46 | /* eslint-disable func-names */ 47 | format(...str) { 48 | str.unshift(`[Vue Component ${this.$options.name}]: `); 49 | return str; 50 | }, 51 | }); 52 | 53 | install.installed = true; 54 | }; 55 | install.installed = false; 56 | 57 | if (typeof window !== 'undefined' && window.Vue) { 58 | install(window.Vue); 59 | } 60 | 61 | const Stone = { 62 | install, 63 | }; 64 | 65 | export default Stone; 66 | -------------------------------------------------------------------------------- /src/styles/base.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | font-family: 'Avenir', Helvetica, Arial, sans-serif; 4 | -webkit-font-smoothing: antialiased; 5 | -moz-osx-font-smoothing: grayscale; 6 | 7 | font-size: 14px; 8 | } 9 | -------------------------------------------------------------------------------- /src/styles/default-theme/themes.css: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 主题色 3 | * @Author: shilili1 4 | * @Date: 2019-01-04 16:58:58 5 | * @LastEditTime: 2019-03-25 14:17:11 6 | * @LastEditors: Please set LastEditors 7 | */ 8 | 9 | /* 定义主题色 */ 10 | 11 | $theme-ff516e: #ff516e; 12 | $theme-ff86a8: #ff86a8; 13 | 14 | $theme-0a8de8: #0a8de8; 15 | $theme-02d9d1: #02d9d1; 16 | 17 | $theme-0475d4: #0475d4; 18 | $theme-3ae1ff: #3ae1ff; 19 | 20 | $theme-5e48cd: #5e48cd; 21 | $theme-9270f3: #9270f3; 22 | 23 | $theme-f76b46: #f76b46; 24 | $theme-ff9166: #ff9166; 25 | 26 | $theme-693da5: #693da5; 27 | $theme-af559b: #af559b; 28 | 29 | $theme-23bbaa: #23bbaa; 30 | $theme-44ddd8: #44ddd8; 31 | 32 | $theme-474db0: #474db0; 33 | $theme-c78cdf: #c78cdf; 34 | 35 | $theme-2dcdc4: #2dcdc4; 36 | $theme-ffcca4: #ffcca4; 37 | 38 | $theme-00a678: #00a678; 39 | $theme-72f6b0: #72f6b0; 40 | 41 | $theme-00997f: #00997f; 42 | $theme-12ddf5: #12ddf5; 43 | 44 | $theme-cd3b3b: #cd3b3b; 45 | $theme-ef7070: #ef7070; 46 | 47 | $theme-e93166: #e93166; 48 | $theme-fea36c: #fea36c; 49 | 50 | $theme-8a2fd7: #8a2fd7; 51 | $theme-fea36c: #fea36c; 52 | 53 | $theme-59b8fc: #59B8FC; 54 | $theme-d5d5d5: #d5d5d5; 55 | 56 | $theme-45a3f1: #45a3f1; 57 | /* 智能灯主题色 */ 58 | $theme-9777fa: #9777fa; 59 | $theme-03bcee: #03bcee; 60 | /* 微波炉 */ 61 | $theme-fa7b53: #fa7b53; 62 | /* 加湿器 */ 63 | $theme-4281f3: #4281f3; 64 | /* 风扇 */ 65 | $theme-27c88d: #27c88d; 66 | /* 电烤箱 */ 67 | $theme-f95763: #f95763; 68 | /* 电热水器 */ 69 | $theme-ee6a4e: #ee6a4e; 70 | -------------------------------------------------------------------------------- /src/styles/default-theme/variables.css: -------------------------------------------------------------------------------- 1 | @import "./themes.css"; 2 | 3 | $grid-size: 0.3rem; /* 12 grid */ 4 | $main-width: 3.12rem; /* 0.26 * 12 */ 5 | 6 | /* 主题色 */ 7 | $main-color: $theme-45a3f1; 8 | $c-primary: $theme-45a3f1; 9 | $c-primary-on: $theme-45a3f1; 10 | 11 | /******************** length ********************/ 12 | $l-radius: 3px; 13 | 14 | /******************** font size ********************/ 15 | /* $font-size-xs: 10px; 16 | $font-size-sm: 12px; 17 | $font-size-base: 14px; 18 | $font-size-lg: 16px; 19 | $font-size-xl: 18px; 20 | $font-size-32: 32px; */ 21 | 22 | $font-size-xs: 0.1rem; 23 | $font-size-sm: 0.12rem; 24 | $font-size-base: 0.14rem; 25 | $font-size-lg: 0.16rem; 26 | $font-size-xl: 0.18rem; 27 | $font-size-32: 0.32rem; 28 | 29 | /******************** color ********************/ 30 | $gray-dark: #333; 31 | $gray: #666; 32 | $gray-light: #999; 33 | $gray-lighter: #ccc; 34 | $gray-lightest: #eaeaea; 35 | $white: #fff; 36 | $blue: #59b8fc; 37 | $orange: #f76b46; 38 | 39 | /******************** component theme ********************/ 40 | 41 | $t-disabled: #efefef; 42 | 43 | /******************** dayspicker ********************/ 44 | 45 | $dayspicker-item-width: 0.6rem; 46 | $dayspicker-item-height: 0.28rem; 47 | $dayspicker-item-radius: 4px; 48 | $dayspicker-padding-y: 0.12rem; 49 | 50 | $t-dayspicker-font-size: $font-size-base; 51 | $t-dayspicker-defcolor: $gray-light; 52 | $t-dayspicker-lightcolor: $blue; 53 | 54 | /******************** range ********************/ 55 | $range-padding-y: 0.16rem; 56 | $range-slide-height: 2px; 57 | $range-slide-button-size: 24px; 58 | $range-padding-x: calc($range-slide-button-size/2); 59 | $range-slide-button-border: 2px; 60 | $range-slide-stepdot-size: 4px; 61 | $range-slide-dot-size: 24px; 62 | 63 | $t-range-defcolor: $gray-lighter; 64 | $t-range-lightcolor: $c-primary; 65 | 66 | /************************ switch ************************/ 67 | 68 | $switch-width: 0.6rem; 69 | $switch-height: 0.32rem; 70 | $switch-background-color-off: $theme-d5d5d5; 71 | $switch-background-color-on: $c-primary; 72 | 73 | $switch-btn-width: 0.26rem; 74 | $switch-btn-height: 0.26rem; 75 | $switch-btn-background-color: #fff; 76 | 77 | $switch-transform-x-off: 0.03rem; 78 | $switch-transform-x-on: 0.31rem; 79 | 80 | /************************ power ************************/ 81 | $power-width: 0.4rem; 82 | $power-height: 0.4rem; 83 | 84 | $t-power-offcolor: #fff; 85 | $t-power-oncolor: $c-primary; 86 | $t-power-disabled: #efefef; 87 | 88 | /************************ button ************************/ 89 | $btn-padding-sm: 0.06rem 0.08rem; 90 | $btn-fontsize-sm: $font-size-sm; 91 | $btn-radius-sm: 0.05rem; 92 | 93 | $btn-padding-base: 0.1rem 0.16rem; 94 | $btn-fontsize-base: $font-size-base; 95 | 96 | $btn-padding-lg: 0.14rem 0.26rem; 97 | $btn-fontsize-lg: $font-size-lg; 98 | 99 | $btn-icon-only-width-lg: 0.52rem; 100 | $btn-icon-only-width-base: 0.4rem; 101 | $btn-icon-only-width-sm: 0.24rem; 102 | 103 | $btn-disabled: #efefef; 104 | $btn-hover: #efefef; /* 按钮按下底色 */ 105 | 106 | /************************ counter ************************/ 107 | $counter-width: 1.03rem; 108 | $counter-height: 0.35rem; 109 | 110 | /************************ checkboard ************************/ 111 | $c-checkboard-item-padding: 0.12rem 0; 112 | $c-checkboard-icon-width: 0.1rem; 113 | $c-checkboard-icon-height: 0.1rem; 114 | $c-checkboard-icon-size: 0.14rem; 115 | 116 | $c-checkboard-icon-size-round: 0.18rem; 117 | $c-checkboard-icon-height-round: 0.18rem; 118 | $c-checkboard-icon-width-round: 0.18rem; 119 | $c-checkboard-icon-size-round: 0.18rem; 120 | 121 | $c-checkboard-icon-size-square: 0.18rem; 122 | $c-checkboard-icon-height-square: 0.18rem; 123 | $c-checkboard-icon-width-square: 0.18rem; 124 | $c-checkboard-icon-size-square: 0.18rem; 125 | 126 | /************************ modal ************************/ 127 | $c-dialog-title: #333; 128 | 129 | /* 组件当中使用主题色 */ 130 | .c-theme-color { 131 | color: $theme-45a3f1; 132 | } 133 | -------------------------------------------------------------------------------- /src/styles/dependenciesFonts/fonts/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/styles/dependenciesFonts/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/styles/dependenciesFonts/fonts/iconfont.ttf -------------------------------------------------------------------------------- /src/styles/dependenciesFonts/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/styles/dependenciesFonts/fonts/iconfont.woff -------------------------------------------------------------------------------- /src/styles/dependenciesFonts/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'iconfont'; 3 | src: 4 | url('../styles/fonts/fonts/iconfont.ttf?xrh9ax') format('truetype'), 5 | url('../styles/fonts/fonts/iconfont.woff?xrh9ax') format('woff'), 6 | url('../styles/fonts/fonts/iconfont.svg?xrh9ax#iconfont') format('svg'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | [class^="v-icon-"], [class*=" v-icon-"] { 12 | /* use !important to prevent issues with browser extensions that change fonts */ 13 | font-family: 'iconfont' !important; 14 | speak: none; 15 | font-style: normal; 16 | font-weight: normal; 17 | font-variant: normal; 18 | text-transform: none; 19 | line-height: 1; 20 | 21 | /* Better Font Rendering =========== */ 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | 26 | .v-icon-pull-right:before { 27 | content: "\e909"; 28 | } 29 | .v-icon-pull-left:before { 30 | content: "\e910"; 31 | } 32 | .v-icon-power:before { 33 | content: "\e908"; 34 | } 35 | .v-icon-cross:before { 36 | content: "\e900"; 37 | } 38 | .v-icon-select:before { 39 | content: "\e901"; 40 | } 41 | .v-icon-minus:before { 42 | content: "\e906"; 43 | } 44 | .v-icon-plus:before { 45 | content: "\e907"; 46 | } 47 | -------------------------------------------------------------------------------- /src/styles/fonts/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/styles/fonts/fonts/iconfont.ttf -------------------------------------------------------------------------------- /src/styles/fonts/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/src/styles/fonts/fonts/iconfont.woff -------------------------------------------------------------------------------- /src/styles/mixins.css: -------------------------------------------------------------------------------- 1 | 2 | /*@define-extend border { 3 | border-width: 1px; 4 | border-style: solid; 5 | } 6 | */ 7 | 8 | @define-mixin border $width: 1px, $style: solid { 9 | border-width: 1px; 10 | border-style: solid; 11 | } 12 | 13 | @define-mixin border-top-radius $radius: 3px { 14 | border-top-right-radius: $radius; 15 | border-top-left-radius: $radius; 16 | } 17 | 18 | @define-mixin border-bottom-radius $radius: 3px { 19 | border-bottom-right-radius: $radius; 20 | border-bottom-left-radius: $radius; 21 | } 22 | 23 | @define-mixin transition $prop: all, $duration: 0.3s, $delay: 0s { 24 | transition: $prop $duration $delay; 25 | transition-timing-function: ease; 26 | } 27 | 28 | @define-mixin box-shadow $prop { 29 | box-shadow: 0 1px 1px rgba(0,0,0,.01); 30 | } 31 | 32 | @define-mixin bd1 $color: #eee { 33 | border-top: 1px solid $color; 34 | } 35 | 36 | @define-mixin cross-center { 37 | display: flex; 38 | flex-direction: row; 39 | align-items: center; 40 | justify-content: space-around; 41 | justify-content: space-between; 42 | } 43 | 44 | @define-mixin main-center { 45 | display: flex; 46 | justify-content: center; 47 | } 48 | 49 | @define-mixin center { 50 | display: flex; 51 | align-items: center; 52 | justify-content: center; 53 | } 54 | 55 | 56 | /* TODO: 未用到,后续可以删除。 57 | @define-mixin without-padding $main: 1, $cross: 1 { 58 | 59 | @if $main == 0 { 60 | .without-main-padding { 61 | padding-left: 0; 62 | padding-right: 0; 63 | } 64 | } 65 | 66 | @if $cross == 0 { 67 | .without-cross-padding { 68 | padding-top: 0; 69 | padding-bottom: 0; 70 | } 71 | } 72 | } 73 | */ 74 | -------------------------------------------------------------------------------- /src/styles/utils.css: -------------------------------------------------------------------------------- 1 | 2 | @import './mixins.css'; 3 | 4 | /******************** Clearfix, Float ********************/ 5 | .clearfix:before, 6 | .clearfix:after { 7 | content: " "; 8 | display: table; 9 | } 10 | .clearfix:after { 11 | clear: both; 12 | } 13 | 14 | .u-fl { 15 | float: left; 16 | } 17 | 18 | .u-fr { 19 | float: right; 20 | } 21 | 22 | /******************** Show, Hide ********************/ 23 | .u-ofh { 24 | overflow: hidden; 25 | } 26 | 27 | .u-hidden { 28 | display: none !important; 29 | } 30 | 31 | .u-vis-hidden { 32 | visibility: hidden; 33 | } 34 | 35 | /******************** Center ********************/ 36 | 37 | .u-cross-center { 38 | @mixin cross-center; 39 | } 40 | 41 | .u-main-center { 42 | @mixin main-center; 43 | } 44 | 45 | .u-center { 46 | @mixin center; 47 | } 48 | 49 | /******************** Padding ********************/ 50 | .u-without-main-padding { 51 | padding-left: 0 !important; 52 | padding-right: 0 !important; 53 | } 54 | 55 | .u-without-cross-padding { 56 | padding-top: 0 !important; 57 | padding-bottom: 0 !important; 58 | } 59 | 60 | .u-without-padding { 61 | padding: 0 !important; 62 | } 63 | 64 | /******************** Others ********************/ 65 | .space { 66 | height: 10px; 67 | } 68 | /******************** textle-not-flex ********************/ 69 | .title-not-flex { 70 | flex: none; 71 | } 72 | .control-field { 73 | text-overflow:ellipsis; 74 | overflow:hidden; 75 | white-space:nowrap; 76 | word-break:keep-all; 77 | padding-left: 0.12rem; 78 | } 79 | 80 | 81 | @for $i from 1 to 12 { 82 | .col-$i { 83 | width: calc($grid-size * $i); 84 | } 85 | .row-$i { 86 | height: calc($grid-size * $i); 87 | } 88 | } 89 | 90 | 91 | 92 | /******** border ********/ 93 | 94 | .bd1 { 95 | @mixin bd1; 96 | } 97 | 98 | -------------------------------------------------------------------------------- /src/utils/common.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | ;(function (params) { 3 | if (window.devicePixelRatio && devicePixelRatio >= 2) { 4 | var testElem = document.createElement('div'); 5 | testElem.style.border = '.5px solid transparent'; 6 | document.body.appendChild(testElem); 7 | if (testElem.offsetHeight == 1) { 8 | document.querySelector('html').classList.add('hairlines'); 9 | } 10 | document.body.removeChild(testElem); 11 | } 12 | })(); 13 | 14 | /* eslint-disable */ 15 | ;(function (params) { 16 | if (!Array.prototype.fill) { 17 | Object.defineProperty(Array.prototype, 'fill', { 18 | value: function(value) { 19 | 20 | // Steps 1-2. 21 | if (this == null) { 22 | throw new TypeError('this is null or not defined'); 23 | } 24 | 25 | var O = Object(this); 26 | 27 | // Steps 3-5. 28 | var len = O.length >>> 0; 29 | 30 | // Steps 6-7. 31 | var start = arguments[1]; 32 | var relativeStart = start >> 0; 33 | 34 | // Step 8. 35 | var k = relativeStart < 0 ? 36 | Math.max(len + relativeStart, 0) : 37 | Math.min(relativeStart, len); 38 | 39 | // Steps 9-10. 40 | var end = arguments[2]; 41 | var relativeEnd = end === undefined ? 42 | len : end >> 0; 43 | 44 | // Step 11. 45 | var final = relativeEnd < 0 ? 46 | Math.max(len + relativeEnd, 0) : 47 | Math.min(relativeEnd, len); 48 | 49 | // Step 12. 50 | while (k < final) { 51 | O[k] = value; 52 | k++; 53 | } 54 | 55 | // Step 13. 56 | return O; 57 | } 58 | }); 59 | } 60 | })(); 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/utils/timer.js: -------------------------------------------------------------------------------- 1 | 2 | // 输入年月日周,返回值为定时接口日期表达式 3 | function taskTimeExpress(min = '*', hour = '*', date = '*', month = '*', week = '*', year = '*') { 4 | const weekStr = Array.isArray(week) ? week.join(',') : week; 5 | const express = `${min}_${hour}_${date}_${month}_${weekStr}_${year}`; 6 | return express; 7 | } 8 | 9 | // 输入定时api的日期表达式,返回值为汉字星期字符串 '每天' '工作日' '周一, 周二' 10 | function textTaskTimeExpress(express) { 11 | const arr = express.split('_'); 12 | 13 | // 执行一次 14 | if (arr[5] !== '*') { 15 | return '执行一次'; 16 | } 17 | 18 | if (arr[4] === '*' && arr[3] === '*' && arr[2] === '*') { 19 | return '每天'; 20 | } 21 | const week = arr[4].split(','); 22 | 23 | return weekArrToStr(week); 24 | } 25 | 26 | // 输入定时api的日期表达式,返回值为星期数组 [1, 2, 4] 27 | function arrayTaskTimeExpress(express) { 28 | const week = express.split('_')[4]; 29 | if (week === '*') { 30 | return []; 31 | } 32 | const arr = week.split(',').map(val => val * 1); 33 | return arr; 34 | } 35 | 36 | // 输入星期数组, 返回值为汉字星期字符串 37 | function weekArrToStr(week) { 38 | const text = []; 39 | 40 | week.forEach(val => { 41 | const num = val * 1; 42 | switch (true) { 43 | case (num === 1): 44 | text.push('周一'); 45 | break; 46 | case (num === 2): 47 | text.push('周二'); 48 | break; 49 | case (num === 3): 50 | text.push('周三'); 51 | break; 52 | case (num === 4): 53 | text.push('周四'); 54 | break; 55 | case (num === 5): 56 | text.push('周五'); 57 | break; 58 | case (num === 6): 59 | text.push('周六'); 60 | break; 61 | case (num === 7): 62 | text.push('周日'); 63 | break; 64 | default: 65 | } 66 | }); 67 | if (text.join(',') === '周六,周日') { 68 | return '周末'; 69 | } 70 | 71 | if (text.join(',') === '周一,周二,周三,周四,周五') { 72 | return '工作日'; 73 | } 74 | 75 | if (text.join(',') === '周一,周二,周三,周四,周五,周六,周日') { 76 | return '每天'; 77 | } 78 | 79 | return text.join('、'); 80 | } 81 | 82 | // 传入固定格式的时间(2016-11-12 12:30),返回小时分钟(12:30)。 83 | function resolveTimeInTasklist(date) { 84 | return date.split(' ')[1]; 85 | } 86 | 87 | // 传入对象,返回固定格式字符串 (执行一次 2天后执行) 88 | function toTasklistStr(obj) { 89 | const express = obj.task_time_express; 90 | const minutes = obj.next_left_minutes; 91 | const str1 = textTaskTimeExpress(express); 92 | 93 | const hour = Math.floor(minutes / 60); 94 | const min = minutes - (hour * 60); 95 | const day = Math.floor(hour / 24); 96 | 97 | if (day >= 1) { 98 | return `${str1} ${day}天后执行`; 99 | } 100 | 101 | return `${str1} ${hour}小时${min}分钟后执行`; 102 | } 103 | 104 | function warn(options) { 105 | const opt = { 106 | com: options.com || '', 107 | prop: options.prop || '', 108 | param: options.param || [], 109 | }; 110 | 111 | const paramStr = `${opt.param.join(',')}`; 112 | 113 | const str = `[${opt.com}] prop '${opt.prop}' error: yon pass an invalid value, please pass a value in ${paramStr}`; 114 | 115 | console.error(str); 116 | } 117 | 118 | export default { 119 | // 输入定时api的日期表达式,返回值为星期数组 120 | arrayTaskTimeExpress, 121 | // 输入定时api的日期表达式,返回值为汉字星期字符串 122 | textTaskTimeExpress, 123 | // 输入星期数组,返回值为汉字星期字符串 124 | weekArrToStr, 125 | // 输入多个时间参数,返回值为定时接口日期表达式字符串 126 | taskTimeExpress, 127 | // 传入固定格式的时间(2016-11-12 12:30),返回小时分钟(12:30)。 128 | resolveTimeInTasklist, 129 | // 传入对象,返回固定格式字符串 (执行一次 2天后执行) 130 | toTasklistStr, 131 | // 警告 console.error 132 | warn, 133 | }; 134 | -------------------------------------------------------------------------------- /test/e2e/custom-assertions/elementCount.js: -------------------------------------------------------------------------------- 1 | // A custom Nightwatch assertion. 2 | // the name of the method is the filename. 3 | // can be used in tests like this: 4 | // 5 | // browser.assert.elementCount(selector, count) 6 | // 7 | // for how to write custom assertions see 8 | // http://nightwatchjs.org/guide#writing-custom-assertions 9 | exports.assertion = function (selector, count) { 10 | this.message = 'Testing if element <' + selector + '> has count: ' + count; 11 | this.expected = count; 12 | this.pass = function (val) { 13 | return val === this.expected; 14 | } 15 | this.value = function (res) { 16 | return res.value; 17 | } 18 | this.command = function (cb) { 19 | var self = this; 20 | return this.api.execute(function (selector) { 21 | return document.querySelectorAll(selector).length; 22 | }, [selector], function (res) { 23 | cb.call(self, res); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/e2e/nightwatch.conf.js: -------------------------------------------------------------------------------- 1 | require('babel-register') 2 | var config = require('../../config') 3 | 4 | // http://nightwatchjs.org/guide#settings-file 5 | module.exports = { 6 | "src_folders": ["test/e2e/specs"], 7 | "output_folder": "test/e2e/reports", 8 | "custom_assertions_path": ["test/e2e/custom-assertions"], 9 | 10 | "selenium": { 11 | "start_process": true, 12 | "server_path": "node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar", 13 | "host": "127.0.0.1", 14 | "port": 4444, 15 | "cli_args": { 16 | "webdriver.chrome.driver": require('chromedriver').path 17 | } 18 | }, 19 | 20 | "test_settings": { 21 | "default": { 22 | "selenium_port": 4444, 23 | "selenium_host": "localhost", 24 | "silent": true, 25 | "globals": { 26 | "devServerURL": "http://localhost:" + (process.env.PORT || config.dev.port) 27 | } 28 | }, 29 | 30 | "chrome": { 31 | "desiredCapabilities": { 32 | "browserName": "chrome", 33 | "javascriptEnabled": true, 34 | "acceptSslCerts": true 35 | } 36 | }, 37 | 38 | "firefox": { 39 | "desiredCapabilities": { 40 | "browserName": "firefox", 41 | "javascriptEnabled": true, 42 | "acceptSslCerts": true 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/e2e/reports/CHROME_55.0.2883.59_MAC_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /test/e2e/runner.js: -------------------------------------------------------------------------------- 1 | // 1. start the dev server using production config 2 | process.env.NODE_ENV = 'testing'; 3 | var server = require('../../build/dev-server.js'); 4 | 5 | // 2. run the nightwatch test suite against it 6 | // to run in additional browsers: 7 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings" 8 | // 2. add it to the --env flag below 9 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` 10 | // For more information on Nightwatch's config file, see 11 | // http://nightwatchjs.org/guide#settings-file 12 | var opts = process.argv.slice(2); 13 | if (opts.indexOf('--config') === -1) { 14 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']); 15 | } 16 | if (opts.indexOf('--env') === -1) { 17 | opts = opts.concat(['--env', 'chrome']); 18 | } 19 | 20 | var spawn = require('cross-spawn'); 21 | var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }); 22 | 23 | runner.on('exit', function (code) { 24 | server.close(); 25 | process.exit(code); 26 | }); 27 | 28 | runner.on('error', function (err) { 29 | server.close(); 30 | throw err; 31 | }); 32 | -------------------------------------------------------------------------------- /test/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // For authoring Nightwatch tests, see 2 | // http://nightwatchjs.org/guide#usage 3 | 4 | module.exports = { 5 | 'default e2e tests': function test(browser) { 6 | // automatically uses dev Server port from /config.index.js 7 | // default: http://localhost:8080 8 | // see nightwatch.conf.js 9 | const devServer = browser.globals.devServerURL; 10 | 11 | browser 12 | .url(devServer) 13 | .waitForElementVisible('#app', 5000) 14 | .assert.elementPresent('.hello') 15 | .assert.containsText('h1', 'Welcome to Your Vue.js App') 16 | .assert.elementCount('img', 1) 17 | .end(); 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "mocha": true 5 | }, 6 | "globals": { 7 | "expect": true, 8 | "sinon": true 9 | }, 10 | 11 | 'rules': { 12 | 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /test/unit/coverage/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jd-smart-fe/vue-stone/371b1051eb01ed583ac4b526659e00fe976731c6/test/unit/coverage/.DS_Store -------------------------------------------------------------------------------- /test/unit/helper.js: -------------------------------------------------------------------------------- 1 | 2 | const helper = {}; 3 | 4 | helper.convertNodelist = (nodeList) => Array.prototype.slice.call(nodeList, 0); 5 | 6 | helper.createVuefactory = (Klass, Component) => (config = {}, createElementOption) => { 7 | config.el = document.createElement('div'); 8 | if (!createElementOption) { 9 | config.render = (createElement) => createElement(Component); 10 | } else { 11 | config.render = (createElement) => createElement(Component, createElementOption); 12 | } 13 | 14 | return new Klass(config); 15 | }; 16 | 17 | export default helper; 18 | 19 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | // Polyfill fn.bind() for PhantomJS 2 | /* eslint-disable no-extend-native */ 3 | /* eslint-disable import/no-extraneous-dependencies */ 4 | Function.prototype.bind = require('function-bind'); 5 | 6 | // require all test files (files that ends with .spec.js) 7 | const testsContext = require.context('./specs', true, /\.spec$/); 8 | testsContext.keys().forEach(testsContext); 9 | 10 | // require all src files except main.js for coverage. 11 | // you can also change this to match only the subset of files that 12 | // you want coverage for. 13 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/); 14 | srcContext.keys().forEach(srcContext); 15 | -------------------------------------------------------------------------------- /test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | 6 | var path = require('path'); 7 | var merge = require('webpack-merge'); 8 | var baseConfig = require('../../build/webpack.base.conf'); 9 | var utils = require('../../build/utils'); 10 | var webpack = require('webpack'); 11 | var projectRoot = path.resolve(__dirname, '../../'); 12 | 13 | var webpackConfig = merge(baseConfig, { 14 | // use inline sourcemap for karma-sourcemap-loader 15 | module: { 16 | loaders: utils.styleLoaders() 17 | }, 18 | devtool: '#inline-source-map', 19 | vue: { 20 | loaders: { 21 | js: 'isparta' 22 | } 23 | }, 24 | plugins: [ 25 | new webpack.DefinePlugin({ 26 | 'process.env': require('../../config/test.env') 27 | }) 28 | ] 29 | }); 30 | 31 | // no need for app entry during tests 32 | delete webpackConfig.entry; 33 | 34 | // make sure isparta loader is applied before eslint 35 | webpackConfig.module.preLoaders = webpackConfig.module.preLoaders || []; 36 | webpackConfig.module.preLoaders.unshift({ 37 | test: /\.js$/, 38 | loader: 'isparta', 39 | include: path.resolve(projectRoot, 'src'), 40 | }); 41 | 42 | module.exports = function (config) { 43 | config.set({ 44 | // to run in additional browsers: 45 | // 1. install corresponding karma launcher 46 | // http://karma-runner.github.io/0.13/config/browsers.html 47 | // 2. add it to the `browsers` array below. 48 | browsers: ['PhantomJS'], 49 | frameworks: ['mocha', 'sinon-chai'], 50 | // reporters: ['spec', 'coverage'], 51 | reporters: ['spec'], 52 | files: ['./index.js'], 53 | preprocessors: { 54 | './index.js': ['webpack', 'sourcemap'] 55 | }, 56 | webpack: webpackConfig, 57 | webpackMiddleware: { 58 | noInfo: true, 59 | }, 60 | coverageReporter: { 61 | dir: './coverage', 62 | reporters: [ 63 | { type: 'lcov', subdir: '.' }, 64 | { type: 'text-summary' }, 65 | ] 66 | }, 67 | }); 68 | }; 69 | -------------------------------------------------------------------------------- /test/unit/specs/power.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Power from 'src/components/power'; 3 | import helper from '../helper'; 4 | 5 | Vue.create = helper.createVuefactory(Vue, Power); 6 | 7 | describe('Power.vue', () => { 8 | // beforeEach(() => { 9 | // }); 10 | 11 | // afterEach(() => { 12 | // }); 13 | 14 | it('should render component with default state', () => { 15 | const vm = Vue.create(); 16 | const list = helper.convertNodelist(vm.$el.classList); 17 | expect(list).to.be.include('is-off'); 18 | }); 19 | 20 | it('should render component with `on` state', (done) => { 21 | const vm = new Vue({ 22 | el: document.createElement('div'), 23 | template: '', 24 | components: { 25 | Power, 26 | }, 27 | data() { 28 | return { 29 | pstate: true, 30 | }; 31 | }, 32 | }); 33 | 34 | expect(vm.$refs.power.$el.classList.contains('is-on')).to.be.true; 35 | 36 | vm.pstate = false; 37 | 38 | vm.$nextTick(() => { 39 | expect(vm.$refs.power.$el.classList.contains('is-off')).to.be.true; 40 | done(); 41 | }); 42 | }); 43 | 44 | it('should render component with `disabled` state', () => { 45 | const vm = Vue.create({}, { 46 | props: { 47 | disabled: true, 48 | }, 49 | ref: 'power', 50 | }); 51 | 52 | const list = helper.convertNodelist(vm.$el.classList); 53 | expect(list).to.include('is-disabled'); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /test/unit/specs/switch.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Switch from 'src/components/switch'; 3 | import helper from '../helper'; 4 | 5 | Vue.create = helper.createVuefactory(Vue, Switch); 6 | 7 | describe('Switch.vue', () => { 8 | // beforeEach(() => { 9 | // }); 10 | 11 | // afterEach(() => { 12 | // }); 13 | 14 | it('should render component with default state', () => { 15 | const vm = Vue.create(); 16 | const list = helper.convertNodelist(vm.$el.classList); 17 | expect(list).to.include('is-off'); 18 | }); 19 | 20 | it('should render component with `on` state', () => { 21 | const vm = Vue.create({}, { 22 | props: { 23 | value: true, 24 | }, 25 | ref: 'switch', 26 | }); 27 | 28 | expect(vm.$el.classList.contains('is-on')).to.be.true; 29 | }); 30 | 31 | it('should render component with `disabled` state', () => { 32 | const vm = Vue.create({}, { 33 | props: { 34 | disabled: true, 35 | }, 36 | ref: 'switch', 37 | }); 38 | 39 | const list = helper.convertNodelist(vm.$el.classList); 40 | expect(list).to.include('is-disabled'); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /wiki/contribute-guide.md: -------------------------------------------------------------------------------- 1 | # 代码贡献规范 2 | 3 | > 欢迎补充更多合理的规范 4 | 5 | ## 提交代码时应遵守的 commit 规范 6 | 7 | 每一个 commit 都应该清晰明了,commit 的描述应和提交的改动一致。同时为了提高 commit 质量,故进行以下约定: 8 | 9 | * feat:新功能(feature) 10 | * fix:修补bug 11 | * docs:文档(documentation) 12 | * style: 格式(不影响代码运行的变动) 13 | * refactor:重构(即不是新增功能,也不是修改bug的代码变动) 14 | * test:增加测试 15 | * chore:构建过程或辅助工具的变动 16 | 17 | 例如: 18 | 19 | ``` 20 | $ git commit -m "feat: add a new feature in button component" 21 | ``` 22 | ## 组件贡献注意事项 23 | 24 | 仿照已有组件创建对应的组件和页面,并完善好文档 25 | 26 | ### 页面位置 examples -> pages -> ··· 27 | 28 | - 在 examples -> pages -> App.vue 添加入口 29 | - 在 examples -> pages -> index.js 注册路由 30 | - 在 libs -> initializer.js 添加组件 31 | 32 | ### 组件位置 src -> components -> ··· 33 | 34 | - 组件内注意指定好 name: v-···, `eg: v-panel` 35 | 36 | ### 更新 github 预览页面 37 | 38 | - 把最新的代码合并到分支 gh-pages 上,推到远端库 -------------------------------------------------------------------------------- /wiki/doc-action-box.md: -------------------------------------------------------------------------------- 1 | # Action-box 2 | 3 | ## Tag Name 4 | 5 | `v-action-box` 6 | 7 | ## Usage 8 | 9 | ```html 10 | 11 | 12 | 13 | ``` 14 | 15 | ## Options 16 | 17 | 属性名 | 类型 | 默认值 | 说明 18 | ---- | ---- | ---- | ---- | 19 | v-model | Boolean | false | 控制组件的显隐,true为显示。 20 | maskCloseable| Boolean | false | 控制点击蒙层是否可关闭v-action-box 21 | 22 | ## Methods 23 | 方法名称 | 说明 | 参数 | 24 | ---- | ---- | ---- | 25 | hide | 关闭 Action-box 组件 | 无 26 | show | 打开 Action-box 组件 | 无 27 | -------------------------------------------------------------------------------- /wiki/doc-action-sheet.md: -------------------------------------------------------------------------------- 1 | # Action-sheet 2 | 3 | ## Tag Name 4 | 5 | `v-action-sheet` 6 | 7 | ## Usage 8 | 9 | ```html 10 | 11 | 12 | ``` 13 | 14 | ## Options 15 | 16 | 属性名 | 类型 | 默认值 | 说明 17 | ---- | ---- | ---- | ---- | 18 | v-model | Boolean | false | 控制组件的显隐,true为显示 (非必需属性) 19 | items | Array | `[{ text: '确定' }]` | 可配置多个按钮 20 | maskCloseable| Boolean | false | 控制点击蒙层是否可关闭v-action-sheet 21 | 22 | 23 | items 结构: 24 | ```js 25 | items: [ 26 | { 27 | text: '编辑', // 按钮文案 28 | }, { 29 | text: '删除', 30 | color: 'red', // 按钮颜色 可传递16位色。默认 #2c3e50; 31 | }, 32 | ], 33 | 34 | ``` 35 | 36 | ## Methods 37 | 方法名称 | 说明 | 参数 | 38 | ---- | ---- | ---- | 39 | hide | 关闭 Action-box 组件 | 无 40 | show | 打开 Action-box 组件 | 无 41 | -------------------------------------------------------------------------------- /wiki/doc-alert.md: -------------------------------------------------------------------------------- 1 | # Alert 2 | 3 | Alert 组件向 Vue 原型属性上添加了 `$alert` 属性,通过调用当前 vue 实例 `$alert` 属性的方法来使用 alert。 4 | 5 | `this.$alert.show(opt)` 方法接受一个参数来配置 alert,参数可以是一个字符串,或者是一个对象。 6 | 7 | 8 | ## Usage 9 | 10 | 调用 show(options) 传入对象参数 11 | ```js 12 | this.$alert.show({ 13 | title: 'alert', // 标题 14 | desc: 'This is alert content', // 内容区 默认无 15 | maskCloseable: true, // 点击蒙层可关闭 alert 默认 false 16 | }) 17 | ``` 18 | 19 | 或者直接传入字符串 20 | ```js 21 | this.$alert.show('Hello world'); 22 | ``` 23 | 24 | 25 | ## Methods 26 | 方法名称 | 说明 | 参数 | 返回值 27 | ---- | ---- | ---- | 28 | show(options) | 显示弹窗 | 参见备注 | promies 对象,会在弹窗关闭时状态改变为 Resolved 29 | hide() | 关闭弹窗 | 无 | 无 30 | 31 | **备注:** 32 | ```js 33 | this.$alert.show({ 34 | title: 'Title', // Alter 的 标题 35 | desc: 'This is alert content', // Alert 的内容,默认 无 36 | buttonText: '确定', // 按钮的文案,默认 “确定” 37 | buttonColor: 'red' // 按钮颜色,默认 '#666' 38 | }).then(() => { 39 | console.log('弹窗关闭啦'); 40 | }); 41 | ``` 42 | 43 | ## Events 44 | 45 | 事件名称 | 说明 | 参数 | 46 | ---- | ---- | ---- | 47 | show | 弹窗显示时触发此事件 | 无 48 | hide | 弹窗隐藏时触发此事件 | 无 49 | 50 | ```js 51 | this.$alert.$on('hide', () => { 52 | console.log('confirm close'); 53 | }); 54 | ``` 55 | -------------------------------------------------------------------------------- /wiki/doc-button-group.md: -------------------------------------------------------------------------------- 1 | # Button-group 2 | 3 | ## Tag Name 4 | `v-button-group` 5 | 6 | ## Usage 7 | ```html 8 | 9 | 0 10 | 1 11 | 2 12 | 4 13 | 14 | 15 | ``` 16 | -------------------------------------------------------------------------------- /wiki/doc-button-switch.md: -------------------------------------------------------------------------------- 1 | # Button-switch 2 | 3 | ## Tag Name 4 | `v-button-switch` 5 | 6 | ## Usage 7 | ```html 8 | 9 | ``` 10 | 11 | ## Options 12 | 13 | 属性名 | 类型 | 默认值 | 说明 14 | ---- | ---- | ---- | ---- | 15 | v-model | Boolean | false | 按钮激活状态 16 | size | String | 'base' | 定义按钮大小,可选值 'small', 'base', 'large'。 17 | icon | String | '' | 定义按钮图标。 18 | radius | String | 'small' | 定义圆角大小, 可选 'small', 'circle', 19 | disabled | Boolean | false | 是否禁用按钮。 20 | hold | Boolean | false | 值为true时,点击按钮不会改变按钮的状态,但会触发change事件。 21 | syncHold | Boolean | false | 值为true时,点击按钮不会改变按钮的状态,但会触发change事件。 22 | htmlType | String | 'button' | 设置按钮原生 type 参数 23 | 24 | 25 | **备注:** 26 | 1. 在没有文本的情况下,传入 icon 参数且 radius 设置为 circle 按钮会变成圆形。 27 | 28 | 2. 可以使用 `hold` 参数很好的处理组件状态的异步改变。同时为了避免触发多次无意义的 `change` 事件,当 `hold` 时,多次点击按钮仅触发一次 `change` 事件,直到按钮状态被改变,或调用组件 `relive()` 方法。 29 | 30 | 3. `syncHold` 功能和 hold 属性类似,但不具备 hold 属性改变一次状态前只会触发一次 change 事件的特性。 31 | 32 | 33 | ## Events 34 | 35 | 事件名称 | 说明 | 参数 | 36 | ---- | ---- | ---- | 37 | change | type 属性为 click 时,点击按钮会触发事件。 type 属性为 toogle 时,按钮状态改变会触发事件。disabled 属性为 true 时,点击按钮不触发事件。 | 当前按钮的 value 值 38 | 39 | 40 | ## Methods 41 | 42 | 方法名称 | 说明 | 参数 | 43 | ---- | ---- | ---- | 44 | update | 可改变激活按钮状态 | 参数为想要改变成为的状态,可传入`true, false, 'toggle'`。 45 | relive | 当 `hold` 为 `true` 时,未改变按钮状态前,按钮仅能触发一次 `change` 事件,触发事件后再调用本方法,可以让按钮在下次点击时能再触发一次 `change` 事件。 一般用于异步方法失败时的回调里调用。| 46 | -------------------------------------------------------------------------------- /wiki/doc-button.md: -------------------------------------------------------------------------------- 1 | # Button 2 | 3 | ## Release Notes 4 | 5 | - v0.5.1: 修改 icon 属性的入参,现在需要传入完整的 icon 样式类名。 6 | 7 | ## Tag Name 8 | `v-button` 9 | 10 | ## Usage 11 | ```html 12 | Button 13 | 14 | 19 | ``` 20 | 21 | ## 代码演示 22 | 禁用按钮 23 | ```html 24 | 禁用按钮 25 | ``` 26 | 27 | 按钮大小 28 | ```html 29 | 默认按钮 30 | 小按钮 31 | 大按钮 32 | ``` 33 | 34 | 按钮形状 35 | ```html 36 | 默认形状 37 | 圆角按钮 38 | 39 | ``` 40 | 41 | 满宽按钮 42 | ```html 43 | 长按钮 44 | ``` 45 | 46 | ## Options 47 | 48 | 属性名 | 类型 | 默认值 | 说明 49 | ---- | ---- | ---- | ---- | 50 | size | String | 'base' | 定义按钮大小,可选值 'small', 'base', 'large'。 51 | full | Boolean | false | 按钮是否展示为满屏宽度 52 | icon | String | '' | 定义按钮图标,传入完整的图标样式类名。 53 | radius | String | 'small' | 定义圆角大小, 可选 'small', 'circle'。 54 | disabled | Boolean | false | 是否禁用按钮。 55 | htmlType | String | 'button' | 设置按钮原生 type 参数 56 | borderColor | String | '' | 默认是显示主题色,可以配置按钮的边框颜色 57 | 58 | **备注:** 59 | 在没有文本的情况下,传入 icon 参数且 radius 设置为 circle 按钮会变成圆形。 60 | -------------------------------------------------------------------------------- /wiki/doc-checkboard.md: -------------------------------------------------------------------------------- 1 | # Checkboard: 2 | 3 | ## Tag Name 4 | 5 | `v-checkboard` 6 | 7 | ## Usage 8 | 9 | **每个选项必须添加属性 `data-value`** 10 | 11 | 你可以通过一个简单的 for 循环来写出所有的 item。 12 | 13 | 单选模式: 14 | ```html 15 | 16 |
17 | {{ i.text }} 18 |
19 |
20 | ``` 21 | ```js 22 | data() { 23 | return { 24 | value: 'item1', 25 | }; 26 | }, 27 | ``` 28 | 29 | 复选模式: 30 | ```html 31 | 32 |
33 | {{ i.text }} 34 |
35 |
36 | ``` 37 | ```js 38 | data() { 39 | return { 40 | value: ['item1', 'item3'], 41 | }; 42 | }, 43 | ``` 44 | 45 | 组件绑定的值为 data-value 的值,但同时你令你的组件显示出不同于 data-value 的值。如: 46 | ```html 47 | 48 |
49 | this is display value 50 |
51 |
52 | ``` 53 | 54 | 55 | 56 | 57 | ## Options 58 | 59 | | 属性名 | 类型 | 默认值 | 说明 | 60 | | ---- | ---- | ---- | ---- | 61 | | v-model | Number, String 或 Array | 必需属性 | 该值双向绑定了当前激活的选项的 data-value 的值。当该组件为复选模式时,请传入一组由选项 data-value 值组成的数据。| 62 | | multi | Boolean | false | 值为 true 是为复选,反之为单选。| 63 | | htmlName | String | "" | input原生name值 | 64 | | iconType | String | "hook" | 有三种样式,'hook': 对勾; 'round': 圆形'; 'squ': 方形 | 65 | 66 | ## Events 67 | | 事件名称 | 说明 | 参数 | 68 | | --- | --- | --- | 69 | | input | 当切换选项的时候 | value | 70 | | change | 当切换选项的时候 | value | 71 | 72 | ```html 73 | 74 |
75 | this is display value 76 |
77 |
78 | ``` 79 | ```js 80 | this.$refs.box.$on('input', value => { 81 | console.log(value); 82 | }) 83 | ``` 84 | -------------------------------------------------------------------------------- /wiki/doc-confirm.md: -------------------------------------------------------------------------------- 1 | # Comfirm 2 | 3 | Toast 组件向 Vue 原型属性上添加了 `$confirm` 属性,通过调用当前 vue 实例 `$confirm` 属性的方法来使用 comfirm。 4 | 5 | **`this.$confirm.show(opt)`** 方法接受一个参数来配置 toast,参数可以是一个字符串(表示的是title),或者是一个对象。 6 | 7 | ## Usage 8 | 9 | 调用 show(options) 传入对象参数 10 | ```js 11 | this.$confirm.show({ 12 | title: 'confirm', // 标题 13 | desc: 'This is confirm content', // 内容区 默认无 14 | }) 15 | ``` 16 | 17 | 或者直接传入字符串 18 | ```js 19 | this.$confirm.show('Hello world'); 20 | ``` 21 | 22 | 23 | ## Methods 24 | | 方法名称 | 说明 | 参数 | 返回值 | 25 | | ---- | ---- | ---- | ---- | 26 | | show(options) | 显示弹窗 | 参考Options | promies 对象,点击确定时状态改变为 Resolved,点击取消时状态改变为 Rejected。| 27 | |hide() | 关闭弹窗 | 无 | 无 | 28 | 29 | **备注:** 30 | show 方法: 31 | 32 | ```js 33 | this.$confirm.show({ 34 | title: 'Title', // Alter 的 标题 35 | desc: 'This is confirm content', // confirm 的内容,默认 无 36 | leftColor: 'blue', // 按钮的文案,默认 #59B8FC 37 | rightColor: 'red' // 按钮颜色,默认 '#666' 38 | }).then(() => { 39 | console.log('点击确定'); 40 | }, () => { 41 | consle.log('点击取消'); 42 | }); 43 | ``` 44 | 45 | 46 | ## Options 47 | 48 | 属性名 | 类型 | 默认值 | 说明 49 | ---- | ---- | ---- | ---- | 50 | v-model | Boolean | false | 控制组件显隐 51 | title | String | '提示' | 设置弹窗标题 52 | desc | String | 无 | 设置弹窗内容 53 | tcolor | String | '#333' | 设置标题颜色 54 | dcolor | String | '#999' | 设置内容颜色 55 | button | Array | [{ text: '确定' }] | 设置按钮文字及颜色 56 | preventClose | Boolean | false | 值为true时,点击按钮后不会自动关闭弹窗 57 | 58 | **备注:** 59 | buttons 属性: 60 | 61 | ```js 62 | // 数组每一项对应一个按钮,最多可配置五个按钮 63 | button: [{ 64 | text: '确定', // 按钮文本 65 | color: '#666', // 按钮颜色 默认 '#59B8FC' 66 | },{ 67 | text: '取消', // 按钮文本 68 | color: 'red', // 按钮颜色 默认 '#59B8FC' 69 | }] 70 | ``` 71 | 72 | title 属性: 73 | 74 | 设置 title 属性为空字符串,`title=""`,组件将不会渲染 title 区域。 75 | 76 | ## Events 77 | 78 | 事件名称 | 说明 | 参数 | 79 | ---- | ---- | ---- | 80 | show | 弹窗显示时触发此事件 | 无 81 | hide | 弹窗隐藏时触发此事件 | 无 82 | 83 | **备注:** 84 | ```js 85 | this.$confirm.$on('hide', () => { 86 | console.log('confirm close'); 87 | }); 88 | ``` 89 | -------------------------------------------------------------------------------- /wiki/doc-control-center.md: -------------------------------------------------------------------------------- 1 | # Controlcenter 2 | 3 | ## Tag Name 4 | 5 | `v-control-center` 6 | 7 | ## Usage 8 | 9 | ```html 10 | 22 | ``` 23 | 24 | ## Options 25 | 26 | 属性名 | 类型 | 默认值 | 说明 27 | ---- | ---- | ---- | ---- | 28 | top_icon | String | 主页图标 | 上部的图标 29 | top_text | String | 主页 | 上部的文字 30 | bottom_icon | String | 静音图标 | 下部的图标 31 | bottom_text | String | 静音 | 下部的文字 32 | left_icon | String | 菜单图标 | 左部的图标 33 | left_text | String | 菜单 | 左部的文字 34 | right_icon | String | 返回图标 | 右部的图标 35 | right_text | String | 返回 | 右部的文字 36 | center_text | String | OK | 中间的文字 37 | 38 | ## Events 39 | 方法名称 | 说明 | 40 | ---- | ---- | 41 | topHandle | 点击上部时触发此事件 42 | bottomHandle | 点击下部时触发此事件 43 | leftHandle | 点击左部时触发此事件 44 | rightHandle | 点击右部时触发此事件 45 | centerHandle | 点击中间时触发此事件 46 | 47 | ## Usage 48 | 49 | ```js 50 | mounted() { 51 | this.$refs.controlCenter.$on('topHandle', () => { 52 | console.log('触发topHandle事件'); 53 | }); 54 | this.$refs.controlCenter.$on('bottomHandle', () => { 55 | console.log('触发bottomHandle事件'); 56 | }); 57 | this.$refs.controlCenter.$on('leftHandle', () => { 58 | console.log('触发leftHandle事件'); 59 | }); 60 | this.$refs.controlCenter.$on('rightHandle', () => { 61 | console.log('触发rightHandle事件'); 62 | }); 63 | this.$refs.controlCenter.$on('centerHandle', () => { 64 | console.log('触发centerHandle事件'); 65 | }); 66 | }, 67 | ``` 68 | -------------------------------------------------------------------------------- /wiki/doc-counter.md: -------------------------------------------------------------------------------- 1 | # Counter 2 | 3 | ## Tag Name 4 | 5 | `v-counter` 6 | 7 | ## Options 8 | 9 | 属性名 | 类型 | 默认值 | 说明 10 | ---- | ---- | ---- | ---- | 11 | v-model | Number | 必需属性 | 计数器初始值,必填。 12 | max | Number | Infinity | 计数器最大值,计数若超过最大值时,加号按钮会自动置为disabled状态。 13 | min | Number | -Infinity | 计数器最小值,计数若超过最小值时,减号按钮会自动置为disabled状态。 14 | step | Number | 1 | 步距,点一次加减号会加减相应的值。 15 | disabled| Boolean | false | 设置true表示组件为禁用状态。 16 | 17 | 18 | ## Events 19 | 20 | 事件名称 | 说明 | 参数 | 21 | ---- | ---- | ---- | 22 | change | 点击加号或减号都会触发该事件,按钮disabled时不会触发。 | 当前计数值 23 | increase | 点击加号时会触发该事件,按钮disabled时不会触发。 | 当前计数值 24 | decrease | 点击减号时会触发该事件,按钮disabled时不会触发。 | 当前计数值 25 | -------------------------------------------------------------------------------- /wiki/doc-dayspicker.md: -------------------------------------------------------------------------------- 1 | # Dayspicker 2 | 3 | ## Tag Name 4 | 5 | `v-dayspicker` 6 | 7 | ## Usage 8 | 9 | ```html 10 | 11 | ``` 12 | 13 | ## Options 14 | 15 | 属性名 | 类型 | 默认值 | 说明 16 | ---- | ---- | ---- | ---- | 17 | v-model | Array | 必需属性 | 传入星期数组,如 [1, 3, 4, 7],表示选中周一、周三、周四、周日。1 代表周一,以此类推,7 代表周日。 18 | 19 | 20 | 21 | ## Events 22 | 方法名称 | 说明 | 参数 | 23 | ---- | ---- | ---- | 24 | change | 更换日期时触发此事件 | 当前被选中的星期的数组。 25 | -------------------------------------------------------------------------------- /wiki/doc-dialog.md: -------------------------------------------------------------------------------- 1 | # Modal 2 | 3 | ## Usage 4 | 5 | ```html 6 | 7 | ``` 8 | 9 | ## Options 10 | 11 | 属性名 | 类型 | 默认值 | 说明 12 | ---- | ---- | ---- | ---- | 13 | v-model | Boolean | false | 控制组件显隐 14 | title | String | '提示' | 设置弹窗标题 15 | desc | String | 无 | 设置弹窗内容 16 | tcolor | String | '#333' | 设置标题颜色 17 | dcolor | String | '#999' | 设置内容颜色 18 | buttons | Array | [{ text: '确定' }] | 设置按钮文字及颜色 19 | preventClose | Boolean | false | 值为true时,点击按钮后不会自动关闭弹窗 20 | 21 | **备注:** 22 | buttons 属性: 23 | 24 | ```js 25 | // 数组每一项对应一个按钮,最多可配置五个按钮 26 | buttons: [{ 27 | text: '确定', // 按钮文本 28 | color: '#666', // 按钮颜色 默认 '#59B8FC' 29 | },{ 30 | text: '取消', // 按钮文本 31 | color: 'red', // 按钮颜色 默认 '#59B8FC' 32 | }] 33 | ``` 34 | 35 | **tips:** 36 | 设置 title 属性为空字符串,`title=""`,组件将不会渲染 title 区域。 37 | 38 | ## Events 39 | 事件名称 | 说明 | 参数 40 | ---- | ---- | ---- | 41 | maskclick | 点击蒙版出发事件 | 无 42 | buttonfirst | 点击第一个按钮发出事件 | 无 43 | buttonsecond | 点击第二个按钮发出事件 | 无 44 | buttonthird | 点击第三个按钮发出事件 | 无 45 | buttonfourth | 点击第四个按钮发出事件 | 无 46 | buttonfifth | 点击第五个按钮发出事件 | 无 47 | 48 | 49 | ## Methods 50 | 事件名称 | 说明 | 参数 51 | ---- | ---- | ---- | 52 | show | 显示弹窗 | 无 53 | hide | 隐藏弹窗 | 无 54 | -------------------------------------------------------------------------------- /wiki/doc-icon.md: -------------------------------------------------------------------------------- 1 | # Icon 2 | 3 | Icon 包含了常用的图标; 4 | 5 | ## Tag Name 6 | `v-icon` 7 | 8 | ## Usage 9 | ```html 10 | 15 | ``` 16 | 17 | ## Options 18 | 19 | | 属性名 | 类型 | 默认值 | 说明 | 20 | | ---- | ---- | ---- | ---- | 21 | | name | String | '' | 设置icon的图标名称 | 22 | | size | String | '' | 设置图标的大小,例如:'12px' | 23 | | color | String | $c-primary | 设置图标的颜色,默认是主题色,例如:'#000' | 24 | -------------------------------------------------------------------------------- /wiki/doc-input.md: -------------------------------------------------------------------------------- 1 | # Input 2 | 3 | 4 | ## Tag Name 5 | 6 | `v-input` 7 | 8 | ## Usage 9 | 10 | ```js 11 | 17 | ``` 18 | 19 | ## Options 20 | 21 | | 属性名 | 类型 | 默认值 | 说明 | 22 | | ---- | ---- | ---- | ---- | 23 | | v-model | String | '' | 输入框的内容 | 24 | | placeholder | String | '' | 输入框没有内容时的占位字符 | 25 | | htmlName | String | '' | 原生 input 标签的 name 属性 | 26 | | hasB | Boolean | false | 是否有边框 | 27 | | size | String | 'large' | 当 ``hasB`` 是 ``true`` 的时候起效果,有 ``large``, ``small``, ``middle`` | 28 | | disabled | Boolean | false | 是否禁用 | 29 | | canClear | Boolean | false | 是否支持清楚功能 | 30 | 31 | 该组件暂时只支持 'text' 型的 input 输入框。 32 | 33 | ## Events 34 | 35 | | 事件名称 | 说明 | 参数 | 36 | | ---- | ---- | ---- | 37 | | input | 输入内容时触发事件,触发条件类似于原生 input 标签的 input 事件 | 当前组件输入框的内容 | 38 | | change | 用户离开输入框,并且输入框内容发生改变时 | 当前组件输入框的内容 | 39 | -------------------------------------------------------------------------------- /wiki/doc-loading.md: -------------------------------------------------------------------------------- 1 | # Loading 2 | 3 | Loading 组件向 Vue 原型上添加了 `$loading` 属性,通过调用当前 vue 实例 `$loading` 属性的方法来使用 loading。 4 | 5 | ## Usage 6 | 7 | 调用 show(options) 传入参数 8 | 9 | ``` 10 | this.$loading.show(); 11 | 12 | this.$loading.show({ 13 | modal: true, 14 | text: '正在控制', 15 | });; 16 | ``` 17 | 18 | ## Methods 19 | 20 | | 方法名称 | 说明 | 参数 | 返回值 | 21 | | ---- | ---- | ---- | ---- | 22 | | show(options) | 显示弹窗 | 参考Options | 无 | 23 | | hide() | 关闭弹窗 | 无 | 无 | 24 | 25 | ## Options 26 | 27 | | 属性名 | 类型 | 默认值 | 说明 | 28 | | ---- | ---- | ---- | ---- | 29 | | text | String | 加载中 | 文字展示 | 30 | | pos | String | 'center' | 设置loading展示位置,center:上下左右居中展示;top:在顶部展示;bottom:在底部展示;| 31 | | duration | Int | 3000 | 设置持续时间 | 32 | | mask | Boolean | true | 是否添加蒙层 | 33 | -------------------------------------------------------------------------------- /wiki/doc-mask.md: -------------------------------------------------------------------------------- 1 | # 遮罩组件 2 | 3 | ## Usage 4 | 5 | ```html 6 | 7 | ``` 8 | 9 | ## Options 10 | 11 | 属性名 | 类型 | 默认值 | 说明 12 | ---- | ---- | ---- | ---- | 13 | v-model | Boolean | false | 是否显示mask 14 | cls | string | '' | 可传入自定义css类名 15 | transition | String | 'fade' | 更改 vue transition 的 name 属性值 16 | 17 | ## Events 18 | 事件名称 | 说明 | 参数 19 | ---- | ---- | ---- 20 | click | 点击mask时会触发该事件 | 无 21 | change | mask 组件切换显隐状态时会触发此事件 | value 22 | -------------------------------------------------------------------------------- /wiki/doc-modes.md: -------------------------------------------------------------------------------- 1 | # Modes 2 | 卡片样式选择设备模式 3 | ## Release Notes 4 | 5 | - v0.5.1: 修改 icon 属性的入参,现在需要传入完整的 icon 样式类名。 6 | 7 | ## Tag Name 8 | 9 | `v-modes` 10 | 11 | ## Options 12 | 13 | 属性名 | 类型 | 默认值 | 说明 14 | ---- | ---- | ---- | ---- | 15 | v-model | number | -1 | 当前激活的按钮id 16 | numberal | number | 4 | 每行显示的按钮数量,可为 2,3,4 17 | more | String | '' | 展开面板按钮上的提示文案 18 | items | Array | 必传参数 | 配置每个按钮,下面会详细介绍 19 | iconPosition | String | 'top' | 可传属性值为‘top’、'right'、'bottom'、'left',表示icon在文字的不同位置。 20 | type | Sting | 'Single' | 默认表示模式选项互斥显示| 21 | 22 | 23 | 注: 24 | ```js 25 | items: [{ 26 | text: '标准加热', // 按钮文案 27 | icon: 'v-icon-mode-holiday', // 按钮图标 需引入组件图标库 28 | id: 1, // 按钮唯一 id 29 | disabled: true // 是否禁用当前模式,默认不禁用 30 | }, { 31 | text: '快速加热', // 按钮文案 32 | icon: 'v-icon-mode-holiday', // 按钮图标 需引入组件图标库 33 | id: 2, // 按钮唯一 id 34 | }, { 35 | text: '超级加热', // 按钮文案 36 | icon: 'v-icon-mode-holiday', // 按钮图标 需引入组件图标库 37 | id: 3, // 按钮唯一 id 38 | }] 39 | ``` 40 | 41 | ## Events 42 | 43 | 方法名称 | 说明 | 参数 44 | ---- | ---- | ---- 45 | change | 切换激活按钮时会触发该事件 | 2个参数(当前激活按钮的id, 当前激活按钮的对象) 46 | -------------------------------------------------------------------------------- /wiki/doc-panel.md: -------------------------------------------------------------------------------- 1 | # Panel 2 | 3 | 此面板组件为 CSS 容器组件,里面可以放入自定义的内容。 4 | 5 | ## Usage 6 | ```html 7 | 8 |
9 |
Panel Title
10 |
11 |
12 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

13 |
14 | 17 |
18 | ``` 19 | 20 | 结合不同的 `class`,可满足不同的使用场景。更多示例可参考:*examples/pages/panel.vue* 21 | 22 | 23 | ## Options 24 | 25 | 属性名 | 类型 | 默认值 | 说明 26 | ---- | ---- | ---- | ---- | 27 | title | String | - | 标题 28 | description | String | - | 描述 29 | status | String | - | 状态 30 | 31 | ## Events 32 | 33 | 无 34 | 35 | ## Methods 36 | 37 | 无 38 | -------------------------------------------------------------------------------- /wiki/doc-picker-loop.md: -------------------------------------------------------------------------------- 1 | # Picker 2 | 3 | ## Tag Name 4 | 5 | `v-picker-loop` 6 | 7 | ## Opttions 8 | 9 | 属性名 | 类型 | 默认值 | 说明 10 | ---- | ---- | ---- | ---- | 11 | type | String | line | line-不循环,circle-循环。 12 | value | String | 无 |初始化当前选中的值。 13 | unit | String | '' | 单位。 14 | list-data | Array | [] | 选项列表。 15 | 16 | ## Events 17 | 方法名称 | 说明 | 参数 | 18 | ---- | ---- | ---- | 19 | input | 滚动完成后会触发此事件 | 当前被激活选项所组成的选项的值。 20 | 21 | --- 22 | 23 | ## 版本支持 24 | 25 | | browser       | version       | 26 | | ------------- |:-------------:| 27 | | IE | >11 | 28 | | Edg | >=16 | 29 | | Firefox | >=57 | 30 | | chrome | >=47 | 31 | | safari | >=11 | 32 | | iOS Safari | >=9.3 | 33 | | Chrome for Android | >=62 | 34 | | Samsung Internet | >=6.2 | 35 | -------------------------------------------------------------------------------- /wiki/doc-picker.md: -------------------------------------------------------------------------------- 1 | # Picker 2 | 3 | ## Tag Name 4 | 5 | `v-picker` 6 | 7 | ## 6.x 8 | 属性名 | 类型 | 默认值 | 说明 9 | ---- | ---- | ---- | ---- | 10 | items | Object | 无 | 配置 picker 组件中的选项,备注中会详细说明。 11 | itemHeight | Number | 30 | 每行的高度。 12 | offsetLine | Number | 3 | 上下偏移的行数。 13 | id | Number | uuid | 组件的id。 14 | 15 | 备注: 16 | 17 | ```js 18 | { 19 | values: [2017, 2016, 2015], // 每一个选项的 value 20 | displayValues: [2017, 2016, 2015], // 对应每一个选项的显示文本,可忽略,如果忽略 displayValues === values 21 | active: 2, // 当前激活选项的 value 的索引 22 | disableds: [1], // 要禁用 displayValues 索引 23 | } 24 | ``` 25 | 26 | ## Events 27 | 方法名称 | 说明 | 参数 | 28 | ---- | ---- | ---- | 29 | change | 滚动完成后会触发此事件 | 当前被激活选项所组成的对象。 30 | setIndex| 设置组件要选中的目标| 如果 `items.displayValues` 的索引。 31 | 32 | --- 33 | 34 | ## 5.x 35 | 36 | ## Options 37 | 38 | 属性名 | 类型 | 默认值 | 说明 39 | ---- | ---- | ---- | ---- | 40 | items | Array | [] | 配置 picker 组件中的选项,备注中会详细说明。 41 | shown | Boolean | false | 控制 picker 组件显隐 42 | mode | String | 'inline' | 两种显示模式, 支持 inline 模式 及 modal 模式 43 | buttonColor | String | '#59B8FC' | modal 模式下按钮的颜色 44 | title | String | '' | modal 模式下标题栏的文字 45 | 46 | 47 | 备注: 48 | ```js 49 | items: [{ 50 | values: [2017, 2016, 2015], // 每一个选项的 value 51 | displayValues: [2017, 2016, 2015], // 对应每一个选项的显示文本,可忽略 52 | active: 2017, // 当前激活选项的 value 53 | unit: '年', // 单位,可忽略 54 | }, { 55 | values: monthAry.slice(), 56 | displayValues: monthAry.slice(), 57 | active: monthAry.indexOf(curMonth), 58 | unit: '月', 59 | }, { 60 | values: dateAry.slice(), 61 | displayValues: dateAry.slice(), 62 | active: dateAry.indexOf(curDate), 63 | unit: '日', 64 | }] 65 | 66 | ``` 67 | 68 | 69 | ## Events 70 | 方法名称 | 说明 | 参数 | 71 | ---- | ---- | ---- | 72 | change | 滚动完成后会触发此事件 | 当前被激活选项所组成的对象 73 | select | modal 模式下点击确定或取消按钮触发此事件 | 当前被激活选项所组成的对象 74 | maskclick | modal 模式下点击灰色蒙版会触发此事件 | 无 75 | -------------------------------------------------------------------------------- /wiki/doc-range.md: -------------------------------------------------------------------------------- 1 | # Range: 2 | 3 | ## Tag Name 4 | `v-range` 5 | 6 | ## Options 7 | 8 | 属性名 | 类型 | 默认值 | 说明 9 | ---- | ---- | ---- | ---- | 10 | v-model | Number 或 Object | | 在 有级 状态下 value可以传入一个json对象,其属性必须是一一对应的 value 及 text,例:{ value: 20, text: '中档'};这种情况下 滑动改变值后 返回的值也是一个如上格式的json对象。 11 | min | Number | 0 | 无极时的最小值 12 | max | Number | 50 | 无极时的最大值 13 | showTip | Boolean | true | 滑动时是否提示,默认提示 14 | tooltip | Function | 返回当前值 | 滑动时是否提示的文案,默认提示当前value值 15 | isStep | Boolean | false | 是否有级,默认时无极 16 | dots | Array | [] | 滑杆下面的文字信息列表,有级时 以此来判断份几级,dots是一组json对象组成的数组。包含的字段: value、text、icon;,例: [{value: 10, text: '低档', icon: model-cool},{value: 20, text: '中档', icon: model-cool}]; 17 | disabled | Boolean | false | 是否禁用滑杆,默认不仅用 18 | disappear | Boolean | false | 是否另滑杆上的控制球消失,默认不消失 19 | 20 | 21 | ## Events 22 | 事件名称 | 说明 | 参数 | 23 | ---- | ---- | ---- | 24 | input | 滑杆拖动时连续触发 | 当前滑杆的 value 值 25 | change | 滑杆拖动结束时触发 | 当前滑杆的 value 值 26 | -------------------------------------------------------------------------------- /wiki/doc-search.md: -------------------------------------------------------------------------------- 1 | # Search 2 | 3 | ## Tag Name 4 | 5 | `v-search` 6 | 7 | ## Usage 8 | 9 | ```html 10 | 11 | 12 | 13 | ``` 14 | 15 | ## Options 16 | 17 | 属性名 | 类型 | 默认值 | 说明 18 | ---- | ---- | ---- | ---- | 19 | v-model | String | '' | 输入框的内容 20 | placeholder | String | '' | 输入框没有内容时的占位字符 21 | relation|带搜索匹配结果|false|输入匹配为true时生效 22 | result|Array |''|匹配结果(relation为true时生效)支持对象数组或者字符串数组形式,对象数组需包含label属性,例如:[{label: 'Apple', id: '1111'}, {label: 'Orange', id: '2222'}...] 或者 ['Apple', 'Orange'...] 23 | item-click|''|''|匹配结果点击事件(relation为true时生效) 24 | top|String && (px或rem)|0.2rem|匹配结果列表距离input顶部的距离 25 | 26 | ## Methods 27 | 方法名称 | 说明 | 参数 | 28 | ---- | ---- | ---- | 29 | input | 输入内容时触发事件,触发条件类似于原生 input 标签的 input 事件 | 当前组件输入框的内容 30 | change | 用户离开输入框,并且输入框内容发生改变时 | 当前组件输入框的内容 31 | -------------------------------------------------------------------------------- /wiki/doc-slide.md: -------------------------------------------------------------------------------- 1 | # Slide 2 | 3 | > 本组件库中的轮播组件只提供了最基本的功能,如果需要更强大的 vue 轮播组件的话,请关注 [c-swipe](https://github.com/pspgbhu/Vue2-C-Swipe-Mobile) 4 | 5 | ## Tag Name 6 | `c-slide` 7 | 8 | ## Options 9 | 属性名 | 类型 | 默认值 | 说明 10 | ---- | ---- | ---- | ---- | 11 | v-model | Number | 0 | 当前激活状态下的卡片的索引 12 | pagination | Boolean | true | 是否显示导航器 13 | 14 | 15 | 16 | ## Events 17 | 事件名 | 说明 | 参数 18 | ---- | ---- | ---- | 19 | change | 卡片切换时触发此事件 | 当前激活的卡片的索引值 20 | -------------------------------------------------------------------------------- /wiki/doc-switch.md: -------------------------------------------------------------------------------- 1 | # Switch 2 | 3 | ## Tag Name 4 | 5 | ```html 6 | 7 | ``` 8 | 9 | ## Options 10 | 属性名 | 类型 | 默认值 | 说明 11 | ---- | ---- | ---- | ---- | 12 | v-model | Boolean | 0 | 当前开关状态 13 | disabled | Boolean | false | 是否将开关置为禁用状态 14 | hold | Boolean | false | 值为true时,点击按钮不会改变按钮的状态,但会触发change事件。 15 | 16 | **备注:** 17 | 1. 可以使用 `hold` 参数很好的处理组件状态的异步改变。同时为了避免触发多次无意义的 `change` 事件,当 `hold` 时,多次点击按钮仅触发一次 `change` 事件,直到按钮状态被改变,或调用组件 `relive()` 方法。 18 | 19 | ## Events 20 | 事件名 | 说明 | 参数 21 | ---- | ---- | ---- | 22 | change | 点击开关按钮时触发此事件 | 当前开关的状态 23 | 24 | 25 | ## Methods 26 | 方法名 | 说明 | 参数 27 | ---- | ---- | ---- | 28 | update(p) | 更新开关到指定状态 | 可传入 true, false 或者 'toggle' 29 | relive | 当 `hold` 为 `true` 时,未改变按钮状态前,按钮仅能触发一次 `change` 事件,触发事件后再调用本方法,可以让按钮在下次点击时能再触发一次 `change` 事件。 一般用于异步方法失败时的回调里调用。| | 30 | -------------------------------------------------------------------------------- /wiki/doc-textarea.md: -------------------------------------------------------------------------------- 1 | # Textarea 2 | 3 | ## Usage 4 | 5 | ```html 6 | 7 | ``` 8 | 9 | ## Options 10 | 属性名 | 类型 | 默认值 | 说明 11 | ---- | ---- | ---- | ---- | 12 | maxlength | Number | - | 最大输入字数 13 | placeholder | String | - | 初始提示文字 14 | readonly | Boolean | false | 是否只读 15 | showCounter | Boolean | false | 是否显示计数器 16 | callback | Function | - | 更改后调用的方法 17 | 18 | 19 | -------------------------------------------------------------------------------- /wiki/doc-timepicker.md: -------------------------------------------------------------------------------- 1 | # Timepicer 2 | 3 | 一个时间选择器,只能选择 时 和 分。 4 | 5 | ## Usage 6 | ```html 7 | 8 | ``` 9 | 10 | ## Options 11 | | 属性名 | 类型 | 默认值 | 说明 | 12 | | ---- | ---- | ---- | ---- | 13 | | hour | Number | 0 | 设置初始的 小时 14 | | min | Number | 0 | 设置初始的 分钟 15 | | rotate_effect | Boolean | false | 是否开启 3d 模式 16 | 17 | ## Event 18 | | 事件名称 | 说明 | 参数 19 | | ---- | ---- | ---- | 20 | | change | 滑动完成后触发此事件 | 滑动完成后最新的选择时间 例:`{displayValue: [1, 2], value: [1, 2]}` 21 | -------------------------------------------------------------------------------- /wiki/doc-timer.md: -------------------------------------------------------------------------------- 1 | # 定时组模 2 | 3 | 4 | ## Tag Name 5 | `v-timer` 6 | 7 | ## Usage 8 | 9 | ```html 10 | 11 | ``` 12 | 13 | ## Options 14 | 15 | 属性名 | 类型 | 默认值 | 说明 16 | ---- | ---- | ---- | ---- | 17 | options | Object | | 必须值,定义组件内容 18 | 19 | 20 | 相关用法,请看下面示例 21 | 22 | ## Methods 23 | 24 | 方法名称 | 说明 | 参数 25 | ---- | ---- | ---- 26 | getValue | 返回值为组件内部的值 | 无 27 | jumpMainpage | 跳会组件首页 | 无 28 | 29 | ## Events 30 | 31 | 方法名称 | 说明 | 参数 32 | ---- | ---- | ---- 33 | delete | 当点击删除按钮并确定时,触发该事件 | 无 34 | 35 | ## Example 36 | 37 | ### 开关类定时模块: 38 | 39 | 功能单一,只需要定时开启或关闭。 40 | 41 | ```js 42 | options: { 43 | // 定义主页内容 44 | mainpage: { 45 | task_name: '插座定时开关', // 定时任务名称 46 | task_time_express: '31_16_*_*_4,5_*', // 如果是新建任务,可以不传入该参数,或者传入false。 47 | pmg_setting: -1, // 执行结果通知。-1不通知,0仅失败通知,1均通知。 48 | show_delete: true, // 非必需,是否显示删除按钮,默认false,不显示, 49 | simple: { // 开启简单命令模式界面,会忽略复杂任务页 50 | title: '定时任务', // 开关面板标题 51 | status: false, // 开关状态 52 | hideDefault: false, // 是否隐藏默认的开关,主要用于想插入自定义组件,又不想要默认的开关组件 53 | }, 54 | }, 55 | } 56 | 57 | ``` 58 | 若想自定义开关组件,先通过hideDefault参数隐藏默认的开关,然后通过slot自定义组件。 59 | 60 | ```js 61 | options: { 62 | mainpage: { 63 | ... 64 | ... 65 | simple: { 66 | hideDefault: true, // 隐藏默认的开关 67 | }, 68 | }, 69 | }, 70 | 71 | ``` 72 | 73 | ```html 74 | 75 | 76 | 77 |
我是标题
78 |
79 |
开关
80 |
81 | 82 |
83 |
84 |
85 | 86 |
87 | 88 | ``` 89 | 90 | ###多任务定时模块: 91 | #### Tips: 92 | taskpage支持的模组:`onOff` , `modes`, `range`, `counter` 93 | 94 | ```js 95 | options: { 96 | // 定义主页内容 97 | mainpage: { 98 | task_name: '插座定时开关', 99 | time_task_express: '31_16_*_*_4,5_*', // 如果是新建任务,可以不传入该参数,或者传入false。 100 | pmg_setting: -1, 101 | show_delete: true, //非必需,是否显示删除按钮,默认false,不显示, 102 | }, 103 | 104 | // 定义多任务页内容 105 | taskpage: [{ // 注意:组件先后顺序会体现在页面上 106 | name: 'onOff', // 如果需要开关,必须写在第一位 107 | title: '自定义开关名称', 108 | value: 0, 109 | }, { 110 | name: 'modes', // 对应模板组件名称,目前支持仅支持'onOff', 'modes', 'range', 'counter' 111 | title: '自定义名称', // 任务面板的标题 112 | value: 1, // 其余参数均按照正常组件参数传入 113 | items: [{ 114 | text: '智能模式', 115 | icon: 'mode-smart', 116 | id: 1, 117 | }, { 118 | text: '速冷模式', 119 | icon: 'mode-cool', 120 | id: 2, 121 | }, { 122 | text: '速冻模式', 123 | icon: 'mode-freeze', 124 | id: 3, 125 | }], 126 | }, { 127 | name: 'range', 128 | title: '风速设置', 129 | value: 100, 130 | min: 0, 131 | max: 1000, 132 | tooltip(val) { 133 | return `${val}°C`; 134 | }, 135 | dots: [{ 136 | icon: 'mode-holiday', 137 | text: '啊啊', 138 | }, { 139 | icon: 'mode-freeze', 140 | text: '高温', 141 | }], 142 | }, { 143 | name: 'counter', 144 | title: '脱水次数', 145 | value: 5, 146 | max: 10, 147 | min: 0, 148 | step: 1, 149 | }], 150 | }; 151 | ``` 152 | -------------------------------------------------------------------------------- /wiki/doc-toast.md: -------------------------------------------------------------------------------- 1 | # Toast 2 | 3 | Toast 组件向 Vue 原型上添加了 `$toast` 属性,通过调用当前 vue 实例 `$toast` 属性的方法来使用 toast。 4 | 5 | 例如 6 | ```js 7 | // 普通只包含文本的 toast 8 | this.$toast.show('布谷,布谷。'); 9 | 10 | // 包含icon 的 toast 11 | this.$toast.show({ 12 | icon: 'icon-home', 13 | text: '操作成功', 14 | }); 15 | ``` 16 | 17 | 18 | `this.$toast.show(opt)` 方法接受一个参数来配置 toast,参数可以是一个字符串,或者是一个对象。 19 | 20 | ## 方法参数 21 | 22 | ```js 23 | this.$toast.show({ 24 | icon: 'icon-home', // toast 的 icon,默认无 25 | text: '操作成功', // 提示的文字,默认无 26 | duration: 2000 // toast 持续的时间,默认 2000 27 | autohide: true, // 是否自动隐藏,默认 true 28 | }) 29 | ``` 30 | 31 | 或者直接传入字符串 32 | ```js 33 | this.$toast.show('Hello world'); 34 | ``` 35 | 36 | ## 手动隐藏 toast 37 | 38 | 将 autohide 值为 false,取消 toast 的自动隐藏 39 | 40 | ```js 41 | this.$toast.show({ 42 | text: 'waiting', // 提示的文字,默认无 43 | autohide: false, 44 | }) 45 | ``` 46 | 然后手动调用 `$toast.hide()` 方法来隐藏 toast 47 | 48 | ```js 49 | this.$toast.hide(); 50 | ``` 51 | -------------------------------------------------------------------------------- /wiki/doc-transition.md: -------------------------------------------------------------------------------- 1 | # 过渡组件 2 | 3 | **v-transition** 4 | 5 | ```html 6 | 7 |
8 |
9 | ``` 10 | 11 | ```html 12 | 13 |
14 |
15 | 16 | ``` 17 | 18 | ##使用过渡效果时 19 | 属性 20 | 21 | 属性名 | 类型 | 默认值 | 说明 22 | ---- | ---- | ---- | ---- | 23 | name | String | | 必须值,定义组件过渡效果 24 | -------------------------------------------------------------------------------- /wiki/format-of-docs.md: -------------------------------------------------------------------------------- 1 | # Component-name 2 | 3 | ## Usage 4 | 5 | *此处应简单的注明组件用法。* 6 | 7 | ```html 8 | 9 | ``` 10 | 11 | ## Options 12 | 13 | *此处用表格展示出所有的组件可配置属性* 14 | 15 | 属性名 | 类型 | 默认值 | 说明 16 | ---- | ---- | ---- | ---- | 17 | v-model | Boolean | false | 按钮激活状态 18 | radius | String | 'small' | 定义圆角大小, 可选 'small', 'circle', 19 | options | Object | {} | 如果有配置复杂的属性,应在表格下面备注说明。 20 | 21 | 22 | *此处用备注说明表格中无法描述清楚的属性* 23 | 24 | **备注:** 25 | 26 | 1. 在没有文本的情况下,传入 icon 参数且 radius 设置为 circle 按钮会变成圆形。 27 | 28 | 2. options 配置: 29 | ```js 30 | options: { 31 | title: 'title', // 应详细的说明每一项属性,有默认值的应说明默认值 32 | desc: 'This is desc' // 组件的属性, 默认值 'description' 33 | } 34 | ``` 35 | 36 | ## Events 37 | 38 | *此处用表格展示出所有的组件的事件* 39 | 40 | 事件名称 | 说明 | 参数 | 41 | ---- | ---- | ---- | 42 | change | type 属性为 click 时,点击按钮会触发事件。 type 属性为 toogle 时,按钮状态改变会触发事件 43 | 44 | 45 | ## Methods 46 | 47 | *此处用表格展示出所有的组件的方法* 48 | 49 | 方法名称 | 说明 | 参数 | 50 | ---- | ---- | ---- | 51 | update | 可改变激活按钮状态 | 参数为想要改变成为的状态,可传入`true, false, 'toggle'`。 52 | -------------------------------------------------------------------------------- /wiki/how-to-build-by-deps-in-project.md: -------------------------------------------------------------------------------- 1 | # 关于根据实际项目需求进行按需打包 2 | 3 | 组件库 vue-stone 默认情况 dist 目录下的 vue-stone.js 包含了所有的组件,在实际项目中可能更希望能够根据项目的实际需要进行打包,而不是全部的组件,这就需要针对这种情况进行裁剪。 4 | 5 | ## 打包前的准备 6 | 7 | 既然产生了按需打包的需求,我们就假定你在项目中已经用到了 vue 的单文件系统和用 babel 去编译 ES6 语法,因此后续的说明会省略对于 .vue 后缀文件 和 ES6 语法的支持。 8 | 9 | 额外要说明的是,按需打包时引用的是 vue-stone 未经编译过的源码,在构建项目时我们不仅采用了 vue 单文件系统和 ES6语法,同时还使用了 precss 来书写样式,因此这就要求你在项目中要额外的支持 precss 语法。 10 | 11 | ## Let's do it 12 | 13 | 14 | ### Step 1: 引入项目对于 precss 的支持 15 | 16 | precss 是一个基于 [postcss](https://github.com/postcss/postcss) 的插件。 17 | 18 | 终端中输入 `npm i -D precss`, 添加 precss 进项目依赖。 19 | 20 | 简单的配置 `.postcssrc.js` 文件就ok了。 21 | ```js 22 | module.exports = { 23 | "plugins": { 24 | "precss": {}, // Add precss syntax support into project ! 25 | } 26 | } 27 | ``` 28 | 29 | ### Step 2: 添加 babel 对于 vue-stone 源码文件的支持 30 | 31 | 在 `webpack.config.js` 中,配置 `babel-loader` 的 `include` 32 | 33 | ```js 34 | { 35 | test: /\.js$/, 36 | loader: 'babel-loader', 37 | include: [ 38 | path.join(__dirname, '../src'), 39 | path.join(__dirname, '../node_modules/vue-stone') // 添加此项以增加 babel 对于 vue-stone 源码的编译 40 | ], 41 | }, 42 | ``` 43 | 44 | **注意 ⚠️ :** 由于 `babel-loader` 不能转译软链文件,因此使用 `cnpm install` 安装项目时可能会造成 babel 无法正确转译 vue-stone 源码的情况。 45 | 46 | 解决方案有两种: 47 | 48 | 1. 方案一: 49 | 50 | 使用 yarn 或者 npm 安装项目依赖。 51 | 52 | 2. 方案二: 53 | 54 | 为 babel-loader 配置真实的 vue-stone 地址 55 | 56 | ```js 57 | const fs = require('fs'); 58 | 59 | { 60 | test: /\.js$/, 61 | loader: 'babel-loader', 62 | include: [ 63 | path.join(__dirname, '../src'), 64 | fs.realpathSync(path.join(__dirname, '../node_modules/vue-stone')) // 获取真实的文件地址 65 | ], 66 | }, 67 | ``` 68 | 69 | ### Final step: 打包你需要的组件 70 | 71 | 首先需要改变组件库的引用方式。 72 | 73 | ```javascript 74 | // in project, (code snip 1) 75 | 76 | // 要注意,这里不需要再引入组件库的样式文件了。 77 | // import 'vue-stone/dist/vue-stone.css'; 78 | 79 | import Stone from 'vue-stone/src/index' // 直接引用 vue-stone 源码的入口文件 80 | 81 | Vue.use(Stone, { 82 |  components: ['panel', 'loading'] // 需要注册的组件列表 83 | }); 84 | ``` 85 | 86 | 要满足按需打包组件,需要借助 webpack 自带的`ContextReplacementPlugin`。 87 | 88 | 简单得说,将在项目中需要用到的组件,构成一个正则表达式,传入`ContextReplacementPlugin`的参数即可。 89 | 90 | ```js 91 | // webpack.config.js, (code snip 2) 92 | const ContextReplacementPlugin = require("webpack/lib/ContextReplacementPlugin"); 93 | const dependencies = require('vue-stone/libs/dependencies'); 94 | 95 | let components = ['panel', 'loading']; // 项目中所要用到的组件列表 96 | components = dependencies(components); // 构造真实的组件列表 97 | plugins: [ 98 | // ... 99 | new ContextReplacementPlugin( 100 | /vue-stone\/src\/components$/, // vue-stone 库单文件组件所在目录 101 | new RegExp(`(${components.join('|')})\.vue$`), 102 | ), 103 | // ... 104 | ] 105 | ``` 106 | 107 | 注意, 受限于 ES6 和 Webpack 的设计, 模块的设计思想必须是静态化的, 使得打包工具能够在编译期就能确定模块的依赖关系. 108 | 109 | 所以回到按需打包组件这个场景下, 必须在项目构建阶段就需要完成确定 `ContextReplacementPlugin` 的参数值. 这也是为什么按需打包功能并没有在 vue-stone 组件库中完成的原因所在. 同时也意味着当 webpack 处于运行状态时, 动态添加删除程序中(如 code snip 1所示)的所用到的组件列表时, 将不会生效, 必须通过重启 Webpack 构建进程方可. 110 | 111 | ## Referrence 112 | 113 | * [ContextReplacementPlugin](https://webpack.js.org/plugins/context-replacement-plugin/) 114 | 115 | EOF. 116 | 117 | 118 | -------------------------------------------------------------------------------- /wiki/how-to-generator-the-webfont.md: -------------------------------------------------------------------------------- 1 | ## 关于制作字体图标 2 | 3 | 当前 src/styles/fonts 中已经存在部分图标,但肯定是远远不能满足实际项目需求,所以如果后期迭代过程中需要新增或删除字体的话,可以按照以下方式来进行。 4 | 5 | 1. 在 [iconfont](http://www.iconfont.cn/) 找到项目中需要的图标,点击下载,颜色选择 *#000*,大小选设置为*200*,下载 *SVG 格式图标* ,必须为 SVG 格式。 6 | 2. 打开 [icomoon](https://icomoon.io/app/#/select),点击左上角 *Import Icons* 按钮,上传该项目`src/styles/fonts`目录下的`selection.json` 文件,这时会提示导入成功。 7 | 3. 继续上传在第一步中所找到的 SVG 图标,成功后,点击对应图标添加进来,之后点击右下角*Generator Font* 。 8 | 9 | 完成以上三步,此时应该是会得到一个压缩包,包含了*字体文件*,demo,更新后的`selection.json`以及更新后的`style.css`。将*字体文件*,`selection.json`,`style.css`中新增的内容拷贝至本项目对应目录。 10 | 11 | 如果操作正常,那么此时应当是可以使用新添加进来的图标。 12 | --------------------------------------------------------------------------------