├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── _config.yml ├── dist └── vue-qs-form.min.js ├── docs └── index.html ├── package-lock.json ├── package.json ├── src ├── index.js └── vue-qs-form.vue ├── test ├── karma.config.js └── specs │ └── vue-qs-form.spec.js ├── webpack.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | yarn-error.log 3 | node_modules 4 | .DS_Store 5 | /test/coverage/ 6 | /.vscode 7 | /.idea 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "7" 5 | 6 | before_script: 7 | - yarn install 8 | 9 | script: 10 | - yarn run lint 11 | - yarn run test 12 | - yarn run report-coverage -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Kong Fanbo 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-qs-form 2 | Vue quick step form, Vue快速问卷表单 3 | 4 | [![npm](https://img.shields.io/npm/v/vue-qs-form.svg)](https://www.npmjs.com/package/vue-qs-form) 5 | [![npm](https://img.shields.io/npm/dt/vue-qs-form.svg)](https://www.npmjs.com/package/vue-qs-form) 6 | [![npm](https://img.shields.io/npm/dm/vue-qs-form.svg)](https://www.npmjs.com/package/vue-qs-form) 7 | [![Build Status](https://travis-ci.org/xanke/vue-qs-form.svg?branch=master)](https://travis-ci.org/xanke/vue-qs-form) 8 | [![Codecov](https://img.shields.io/codecov/c/github/xanke/vue-qs-form.svg)](https://codecov.io/gh/xanke/vue-qs-form) 9 | [![npm](https://img.shields.io/npm/l/vue-qs-form.svg)](http://opensource.org/licenses/MIT) 10 | 11 | ****需配合element-ui使用 https://github.com/elemefe**** 12 | 13 | 14 | ## 快速开始 15 | ```js 16 | import Vue from 'vue' 17 | import vueQsForm from 'vue-qs-form' 18 | 19 | export default { 20 | name: 'App', 21 | 22 | components: { 23 | vueQsForm 24 | } 25 | } 26 | ``` 27 | 28 | ## 示例 29 | ```vue 30 | 33 | 34 | 66 | ``` 67 | 68 | ## Props 69 | |参数|说明|必须|类型|可选值|默认值| 70 | |-----|-----------|--------|----|----|-------| 71 | |data|表单数据|是|String|—|—| 72 | |height|表单高度|否|String|—|250px| 73 | |autoNext|是否自动下一步|否|Boolean|true/false|false| 74 | |prevBtnText|上一步按钮文字|否|String|—|上一步| 75 | |nextBtnText|下一步按钮文字|否|String|—|下一步| 76 | |submitBtnText|完成按钮文字|否|String|—|提交| 77 | 78 | ## Event 79 | |事件名称|说明|回调参数| 80 | |-----|-----------|--------| 81 | |submit|点击提交事件|表单数据| 82 | |atend|到达最后|-| 83 | 84 | ## Function 85 | |方法名称|说明|回调参数| 86 | |-----|-----------|--------| 87 | |restForm|重置表单|-| 88 | 89 | ## License 90 | 91 | Vue-qs-form is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /dist/vue-qs-form.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("VueQsForm",[],e):"object"==typeof exports?exports.VueQsForm=e():t.VueQsForm=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),i={install:function(t){t.component(r.a.name,r.a)}};r.a.install=i.install,e.default=r.a},function(t,e,n){"use strict";function r(t){n(2)}var i=n(8),o=n(9),s=n(7),a=r,u=s(i.a,o.a,!1,a,null,null);e.a=u.exports},function(t,e,n){var r=n(3);"string"==typeof r&&(r=[[t.i,r,""]]),r.locals&&(t.exports=r.locals);n(5)("e2012242",r,!0)},function(t,e,n){e=t.exports=n(4)(void 0),e.push([t.i,".xk-qs-form-body{position:relative;overflow:auto}.xk-qs-form-item{position:absolute;height:100%;width:100%}.xk-qs-title{color:#000;font-weight:block}.xk-qs-radio-group,.xk-qs-radio-item{width:100%!important}.xk-qs-radio-item{display:block!important;margin-left:0!important;margin-bottom:0!important;padding:12px 10px}.xk-qs-radio-item:hover{background-color:#f5f5f5!important}.xk-qs-radio-item .el-radio__label{white-space:normal!important;display:inline-block;line-height:1.5;padding-left:25px}.xk-qs-radio-item .el-radio__input{height:14px;position:absolute;top:50%;margin-top:-7px}.xk-qs-form-footer{margin-top:45px}.xk-qs-btn-left{float:left}.xk-qs-btn-right{float:right}.xs-qs-progress{display:inline}.xs-qs-progress .el-progress-bar__innerText{display:none!important}",""])},function(t,e){function n(t,e){var n=t[1]||"",i=t[3];if(!i)return n;if(e&&"function"==typeof btoa){var o=r(i);return[n].concat(i.sources.map(function(t){return"/*# sourceURL="+i.sourceRoot+t+" */"})).concat([o]).join("\n")}return[n].join("\n")}function r(t){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t))))+" */"}t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var r=n(e,t);return e[2]?"@media "+e[2]+"{"+r+"}":r}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},i=0;in.parts.length&&(r.parts.length=n.parts.length)}else{for(var s=[],i=0;i0&&this.step--},onSubmitHander:function(){this.$emit("submit")},onAtendHander:function(){this.$emit("atend")},onClickRadioHander:function(){var t=this;this.autoNext&&setTimeout(function(){t.onNextHander()},500)},resetForm:function(){this.form=this.valueInit()},valueInit:function(){var t={};return this.data.forEach(function(e){t[e.key]=""}),t}},watch:{form:function(){this.$emit("input",this.form)},data:function(){this.form=this.valueInit()}},mounted:function(){var t=this.value,e=this.valueInit();"{}"!=JSON.stringify(t)&&t?this.form=Object.assign(e,t):this.form=e}}},function(t,e,n){"use strict";var r=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{staticClass:"xk-qs-form-body",style:"height: "+t.height},[n("transition-group",{attrs:{name:"el-fade-in-linear"}},t._l(t.data,function(e,r){return n("div",{directives:[{name:"show",rawName:"v-show",value:t.step==r,expression:"step == index"}],key:r,staticClass:"xk-qs-form-item"},[n("p",{staticClass:"xk-qs-title"},[t._v(t._s(e.title))]),t._v(" "),n("div",{on:{"~click":function(e){t.onClickRadioHander(e)}}},[n("el-radio-group",{staticClass:"xk-qs-radio-group",model:{value:t.form[e.key],callback:function(n){t.$set(t.form,e.key,n)},expression:"form[item.key]"}},t._l(e.radios,function(e,r){return n("el-radio",{key:r,staticClass:"xk-qs-radio-item",attrs:{label:r+","+e[0]}},[t._v(t._s(e[1]))])}))],1)])}))],1),t._v(" "),n("div",{staticClass:"xk-qs-form-footer"},[n("el-button",{staticClass:"xk-qs-btn-left",attrs:{type:"default"},on:{click:t.onPrevHander}},[t._v(t._s(t.prevBtnText))]),t._v(" "),t.stepNow!=t.stepLength?n("el-button",{staticClass:"xk-qs-btn-right",attrs:{type:"primary"},on:{click:t.onNextHander}},[t._v(t._s(t.nextBtnText))]):t._e(),t._v(" "),t.stepNow==t.stepLength?n("el-button",{staticClass:"xk-qs-btn-right",attrs:{type:"primary"},on:{click:t.onSubmitHander}},[t._v(t._s(t.submitBtnText))]):t._e(),t._v(" "),n("el-progress",{staticClass:"xs-qs-progress",attrs:{"text-inside":!0,"stroke-width":5,percentage:t.percentage}})],1)])},i=[],o={render:r,staticRenderFns:i};e.a=o}])}); -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vue Qs Form demo 7 | 8 | 9 | 11 | 12 | 13 |
14 |
15 |
16 |
17 |

18 | Vue Qs Form 19 |

20 |

21 | Vue快速问卷表单 22 |

23 |
24 |
25 |
26 |
27 |
28 |
29 |

30 | 31 | 32 |

33 |
34 |
35 |
36 |
37 |
38 | 62 |
63 | 64 | 65 | 66 | 93 | 94 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-qs-form", 3 | "version": "0.5.2", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "async-validator": { 8 | "version": "1.8.1", 9 | "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.1.tgz", 10 | "integrity": "sha1-ZmV4jKOSaa93Dl7gLw5VfyQ40so=", 11 | "dev": true, 12 | "requires": { 13 | "babel-runtime": "6.26.0" 14 | } 15 | }, 16 | "babel-helper-vue-jsx-merge-props": { 17 | "version": "2.0.2", 18 | "resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.2.tgz", 19 | "integrity": "sha1-rOscNzWIJ54nVeoc/TXCI5T9M/g=", 20 | "dev": true 21 | }, 22 | "babel-runtime": { 23 | "version": "6.26.0", 24 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", 25 | "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", 26 | "dev": true, 27 | "requires": { 28 | "core-js": "2.5.1", 29 | "regenerator-runtime": "0.11.0" 30 | } 31 | }, 32 | "core-js": { 33 | "version": "2.5.1", 34 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", 35 | "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", 36 | "dev": true 37 | }, 38 | "deepmerge": { 39 | "version": "1.5.2", 40 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", 41 | "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", 42 | "dev": true 43 | }, 44 | "element-ui": { 45 | "version": "2.0.7", 46 | "resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.0.7.tgz", 47 | "integrity": "sha512-0pVUoYqq4ueEPDkcJBf3vYSqULA8LzubzkjnJyWyqxFSDEBvBCTn3voP3tNZrb1a7IU8yLjKhXCseS95TCHeLA==", 48 | "dev": true, 49 | "requires": { 50 | "async-validator": "1.8.1", 51 | "babel-helper-vue-jsx-merge-props": "2.0.2", 52 | "deepmerge": "1.5.2", 53 | "throttle-debounce": "1.0.1" 54 | } 55 | }, 56 | "regenerator-runtime": { 57 | "version": "0.11.0", 58 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", 59 | "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==", 60 | "dev": true 61 | }, 62 | "throttle-debounce": { 63 | "version": "1.0.1", 64 | "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.0.1.tgz", 65 | "integrity": "sha1-2tD+Ew+drzcZ/eoz3Dao5rp/MLU=", 66 | "dev": true 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-qs-form", 3 | "version": "0.5.5", 4 | "description": "Vue quick steps form tool", 5 | "author": "xank@qq.com", 6 | "main": "dist/vue-qs-form.min.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/xanke/vue-qs-form.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/xanke/vue-qs-form/issues" 13 | }, 14 | "keywords": [ 15 | "quick", 16 | "input", 17 | "text", 18 | "steps", 19 | "form", 20 | "vue", 21 | "vue.js" 22 | ], 23 | "homepage": "https://github.com/xanke/vue-qs-form", 24 | "license": "MIT", 25 | "dependencies": {}, 26 | "scripts": { 27 | "test": "cross-env BABEL_ENV=test ./node_modules/.bin/karma start test/karma.config.js", 28 | "test:watch": "cross-env BABEL_ENV=test ./node_modules/.bin/karma start test/karma.config.js --single-run=false", 29 | "lint": "./node_modules/.bin/eslint --ext .js,.vue src spec", 30 | "build": "./node_modules/.bin/webpack --hide-modules -p --progress", 31 | "report-coverage": "codecov" 32 | }, 33 | "devDependencies": { 34 | "avoriaz": "^4.0.0", 35 | "babel-core": "^6.26.0", 36 | "babel-loader": "^7.1.2", 37 | "babel-plugin-istanbul": "^4.1.4", 38 | "babel-preset-env": "^1.6.0", 39 | "chai": "^4.1.2", 40 | "clean-webpack-plugin": "^0.1.16", 41 | "codecov": "^2.3.0", 42 | "cross-env": "^5.0.5", 43 | "css-loader": "^0.28.7", 44 | "element-ui": "^2.0.7", 45 | "eslint": "^4.6.0", 46 | "eslint-plugin-vue": "3.13.1", 47 | "karma": "^1.7.1", 48 | "karma-coverage": "^1.1.1", 49 | "karma-mocha": "^1.3.0", 50 | "karma-phantomjs-launcher": "^1.0.4", 51 | "karma-sinon-chai": "^1.3.2", 52 | "karma-sourcemap-loader": "^0.3.7", 53 | "karma-spec-reporter": "^0.0.31", 54 | "karma-webpack": "^2.0.4", 55 | "mocha": "^3.5.0", 56 | "phantomjs-prebuilt": "^2.1.15", 57 | "sinon": "^3.2.1", 58 | "sinon-chai": "^2.13.0", 59 | "vue": "^2.4.2", 60 | "vue-loader": "^13.0.4", 61 | "vue-template-compiler": "^2.4.2", 62 | "webpack": "^3.5.5" 63 | }, 64 | "babel": { 65 | "presets": [ 66 | [ 67 | "env", 68 | { 69 | "uglify": true, 70 | "modules": false, 71 | "targets": { 72 | "browsers": [ 73 | "> 1%", 74 | "last 2 versions", 75 | "not ie <= 8" 76 | ] 77 | } 78 | } 79 | ] 80 | ], 81 | "env": { 82 | "test": { 83 | "plugins": [ 84 | "istanbul" 85 | ] 86 | } 87 | } 88 | }, 89 | "eslintConfig": { 90 | "extends": [ 91 | "eslint:recommended", 92 | "plugin:vue/recommended" 93 | ] 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import component from './vue-qs-form.vue' 2 | 3 | const plugin = { 4 | install: Vue => { 5 | Vue.component(component.name, component) 6 | } 7 | } 8 | 9 | component.install = plugin.install 10 | 11 | export default component 12 | -------------------------------------------------------------------------------- /src/vue-qs-form.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 142 | 143 | -------------------------------------------------------------------------------- /test/karma.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node, mocha */ 2 | var path = require('path') 3 | 4 | module.exports = config => { 5 | config.set({ 6 | browsers: ['PhantomJS'], 7 | frameworks: ['mocha', 'sinon-chai'], 8 | reporters: ['spec', 'coverage'], 9 | files: ['specs/*.spec.js'], 10 | preprocessors: { 11 | './specs/*.spec.js': ['webpack', 'sourcemap'] 12 | }, 13 | webpack: { 14 | devtool: '#inline-source-map', 15 | resolve: { 16 | extensions: ['.js', '.vue'], 17 | alias: { 18 | 'vue$': 'vue/dist/vue.esm.js', 19 | '@': path.resolve(__dirname, '../src') 20 | } 21 | }, 22 | module: { 23 | rules: [ 24 | { 25 | test: /\.vue$/, 26 | loader: 'vue-loader', 27 | options: { 28 | esModule: false 29 | } 30 | }, 31 | { 32 | test: /\.js$/, 33 | loader: 'babel-loader', 34 | exclude: /node_modules/ 35 | } 36 | ] 37 | } 38 | }, 39 | webpackMiddleware: { 40 | noInfo: true 41 | }, 42 | coverageReporter: { 43 | dir: './coverage', 44 | reporters: [ 45 | { type: 'lcov', subdir: '.' }, 46 | { type: 'text-summary' } 47 | ] 48 | }, 49 | singleRun: true 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /test/specs/vue-qs-form.spec.js: -------------------------------------------------------------------------------- 1 | /* eslint-env mocha */ 2 | import Vue from 'vue' 3 | import ElementUI from 'element-ui' 4 | import { expect } from 'chai' 5 | import { mount } from 'avoriaz' 6 | import vueQsForm from '@/vue-qs-form' 7 | 8 | Vue.use(ElementUI) 9 | 10 | describe('vue-birthday-input.vue', () => { 11 | it('data测试', () => { 12 | let data = [ 13 | { 14 | key: 'qa1', 15 | title: '问题一', 16 | radios: [ 17 | [0, '否'], 18 | [1, '是'] 19 | ] 20 | }, 21 | { 22 | key: 'qa2', 23 | title: '问题二', 24 | radios: [ 25 | [0, '否'], 26 | [1, '是'] 27 | ] 28 | } 29 | ] 30 | const wrapper = mount(vueQsForm, { propsData: { data: data }}) 31 | let ret = JSON.stringify(wrapper.data().form) 32 | 33 | expect(ret).to.equal('{"qa1":"","qa2":""}') 34 | }) 35 | 36 | }) 37 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | const path = require('path') 3 | const CleanWebpackPlugin = require('clean-webpack-plugin') 4 | 5 | module.exports = { 6 | context: __dirname, 7 | resolve: { 8 | modules: [ 9 | path.resolve(__dirname, 'src'), 10 | 'node_modules' 11 | ], 12 | alias: { 13 | 'vue$': 'vue/dist/vue.esm.js' 14 | }, 15 | extensions: ['.js', '.json', '.vue'] 16 | }, 17 | entry: './src/index.js', 18 | externals: { 19 | }, 20 | output: { 21 | path: path.resolve(__dirname, 'dist'), 22 | filename: "vue-qs-form.min.js", 23 | library: 'VueQsForm', 24 | libraryTarget: 'umd', 25 | umdNamedDefine: true 26 | }, 27 | module: { 28 | rules: [ 29 | { 30 | test: /\.vue$/, 31 | loader: 'vue-loader' 32 | }, 33 | { 34 | test: /\.js$/, 35 | loader: 'babel-loader', 36 | exclude: path.resolve(__dirname, 'node_modules') 37 | } 38 | ] 39 | }, 40 | plugins: [ 41 | new CleanWebpackPlugin(['./dist']) 42 | ], 43 | devtool: false, 44 | performance: { 45 | hints: false 46 | } 47 | } --------------------------------------------------------------------------------