diff --git a/docs/demos/common.js b/docs/demos/common.js index 21757d521..b2f7f208b 100644 --- a/docs/demos/common.js +++ b/docs/demos/common.js @@ -31,6 +31,8 @@ Vue.component('demo-section', DemoSection); Locale.add({ 'zh-CN': { + add: '增加', + decrease: '减少', red: '红色', orange: '橙色', yellow: '黄色', @@ -56,6 +58,8 @@ Locale.add({ passwordPlaceholder: '请输入密码' }, 'en-US': { + add: 'Add', + decrease: 'Decrease', red: 'Red', orange: 'Orange', yellow: 'Yellow', diff --git a/docs/demos/index.js b/docs/demos/index.js index 7a6113cf3..a3c210b92 100644 --- a/docs/demos/index.js +++ b/docs/demos/index.js @@ -31,6 +31,7 @@ export default { 'cell-swipe': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/cell-swipe'), 'cell-swipe')), 'cell-swipe')), 'cell': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/cell'), 'cell')), 'cell')), 'checkbox': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/checkbox'), 'checkbox')), 'checkbox')), + 'circle': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/circle'), 'circle')), 'circle')), 'contact': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/contact'), 'contact')), 'contact')), 'coupon': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/coupon'), 'coupon')), 'coupon')), 'datetime-picker': asyncWrapper(r => require.ensure([], () => r(componentWrapper(require('./views/datetime-picker'), 'datetime-picker')), 'datetime-picker')), diff --git a/docs/demos/views/circle.vue b/docs/demos/views/circle.vue new file mode 100644 index 000000000..276724745 --- /dev/null +++ b/docs/demos/views/circle.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/docs/demos/views/sku.vue b/docs/demos/views/sku.vue index 6a956a76c..b09bb9ae8 100644 --- a/docs/demos/views/sku.vue +++ b/docs/demos/views/sku.vue @@ -13,6 +13,7 @@ :reset-stepper-on-hide="true" :reset-selected-sku-on-hide="true" :disable-stepper-input="true" + :message-config="messageConfig" @buy-clicked="onBuyClicked" @add-cart="onAddCartClicked" /> @@ -23,7 +24,7 @@
- {{ $t('title2') }} + {{ $t('title2') }}
@@ -94,6 +95,7 @@ export default { return { showBase: false, showCustom: false, + showStepper: false, initialSku: { s1: '30349', s2: '1193' @@ -113,6 +115,14 @@ export default { } } } + }, + messageConfig: { + uploadImg: () => { + return new Promise((resolve) => { + setTimeout(() => resolve('https://img.yzcdn.cn/upload_files/2017/02/21/FjKTOxjVgnUuPmHJRdunvYky9OHP.jpg!100x100.jpg'), 1000); + }); + }, + uploadMaxSize: 3 } }; }, diff --git a/docs/markdown/en-US/actionsheet.md b/docs/markdown/en-US/actionsheet.md index 4bc0502c5..6a58204ed 100644 --- a/docs/markdown/en-US/actionsheet.md +++ b/docs/markdown/en-US/actionsheet.md @@ -61,6 +61,7 @@ Actionsheet will get another style if there is a `title` prop. | cancel-text | Text of cancel button | `String` | - | - | | overlay | Whether to show overlay | `Boolean` | - | - | | close-on-click-overlay | Whether to close when click overlay | `Boolean` | - | - | +| get-container | Return the mount node for actionsheet | `Function` | - | `() => HTMLElement` | ### Data struct of actions diff --git a/docs/markdown/en-US/circle.md b/docs/markdown/en-US/circle.md new file mode 100644 index 000000000..5e1bb8cda --- /dev/null +++ b/docs/markdown/en-US/circle.md @@ -0,0 +1,69 @@ +## Circle + +### Install +``` javascript +import { Circle } from 'vant'; + +Vue.use(Circle); +``` + +### Usage + +#### Basic Usage + +```html + +``` + +``` javascript +export default { + data() { + return { + currentRate: 0 + }; + }, + computed: { + text() { + return this.currentRate.toFixed(0) + '%' + } + } +}; +``` + +#### Custom style + +```html + +``` + + +### API + +| Attribute | Description | Type | Default | Accepted Values | +|-----------|-----------|-----------|-------------|-------------| +| v-model | Current rate | `Number` | - | - | +| rate | Target rate | `Number` | `100` | - | +| size | Circle size | `String` | `100px` | - | +| color | Progress bar color | `String` | `#38f` | - | +| layer-color | Layer color | `String` | `#fff` | - | +| fill | Fill color | `String` | `none` | - | +| speed | Animate speed(rate/s)| `Number` | - | - | +| text | Text | `String` | - | - | +| stroke-width | Stroke width | `Number` | `40` | - | +| clockwise | Is clockwise | `Boolean` | `true` | - | diff --git a/docs/markdown/en-US/popup.md b/docs/markdown/en-US/popup.md index a87291505..4c7474c94 100644 --- a/docs/markdown/en-US/popup.md +++ b/docs/markdown/en-US/popup.md @@ -48,3 +48,4 @@ Use `position` prop to set popup display position | close-on-click-overlay | Close popup when click overlay | `Boolean` | `true` | - | | transition | Transition | `String` | `popup-slide` | - | | prevent-scroll | Prevent background scroll | `Boolean` | `false` | - | +| get-container | Return the mount node for Popup | `Function` | - | `() => HTMLElement` | diff --git a/docs/markdown/en-US/sku.md b/docs/markdown/en-US/sku.md index 3c35d5bf3..e0706870c 100644 --- a/docs/markdown/en-US/sku.md +++ b/docs/markdown/en-US/sku.md @@ -22,6 +22,7 @@ Vue.use(Sku); :reset-stepper-on-hide="resetStepperOnHide" :reset-selected-sku-on-hide="resetSelectedSkuOnHide" :disable-stepper-input="disableStepperInput" + :message-config="messageConfig" @buy-clicked="onBuyClicked" @add-cart="onAddCartClicked" /> @@ -90,6 +91,8 @@ Vue.use(Sku); | disable-stepper-input | Whether to disable stepper input | `Boolean` | `false` | - | | stepper-title | Quantity title | `String` | `Quantity` | - | | custom-stepper-config | Custom stepper related config | `Object` | `{}` | - | +| message-config | Message related config | `Object` | `{}` | - | +| get-container | Return the mount node for sku | `Function` | - | `() => HTMLElement` | ### Event @@ -200,6 +203,26 @@ customStepperConfig: { } ``` +#### messageConfig Data Structure +```javascript +messageConfig: { + // the upload image callback + uploadImg: () => { + return new Promise((resolve) => { + setTimeout(() => resolve('https://img.yzcdn.cn/upload_files/2017/02/21/FjKTOxjVgnUuPmHJRdunvYky9OHP.jpg!100x100.jpg'), 1000); + }); + }, + // max file size (MB) + uploadMaxSize: 3, + // placehold config + placeholderMap: { + text: 'xxx', + tel: 'xxx', + ... + } +} +``` + #### Event Params Data Structure ```javascript diff --git a/docs/markdown/index.js b/docs/markdown/index.js index 124f4cefe..e5108c2a8 100644 --- a/docs/markdown/index.js +++ b/docs/markdown/index.js @@ -25,6 +25,7 @@ export default { 'zh-CN/changelog-generated': wrapper(r => require.ensure([], () => r(require('./zh-CN/changelog-generated.md')), 'zh-CN/changelog-generated')), 'zh-CN/changelog': wrapper(r => require.ensure([], () => r(require('./zh-CN/changelog.md')), 'zh-CN/changelog')), 'zh-CN/checkbox': wrapper(r => require.ensure([], () => r(require('./zh-CN/checkbox.md')), 'zh-CN/checkbox')), + 'zh-CN/circle': wrapper(r => require.ensure([], () => r(require('./zh-CN/circle.md')), 'zh-CN/circle')), 'zh-CN/contact': wrapper(r => require.ensure([], () => r(require('./zh-CN/contact.md')), 'zh-CN/contact')), 'zh-CN/coupon': wrapper(r => require.ensure([], () => r(require('./zh-CN/coupon.md')), 'zh-CN/coupon')), 'zh-CN/datetime-picker': wrapper(r => require.ensure([], () => r(require('./zh-CN/datetime-picker.md')), 'zh-CN/datetime-picker')), @@ -77,6 +78,7 @@ export default { 'en-US/cell': wrapper(r => require.ensure([], () => r(require('./en-US/cell.md')), 'en-US/cell')), 'en-US/changelog': wrapper(r => require.ensure([], () => r(require('./en-US/changelog.md')), 'en-US/changelog')), 'en-US/checkbox': wrapper(r => require.ensure([], () => r(require('./en-US/checkbox.md')), 'en-US/checkbox')), + 'en-US/circle': wrapper(r => require.ensure([], () => r(require('./en-US/circle.md')), 'en-US/circle')), 'en-US/contact': wrapper(r => require.ensure([], () => r(require('./en-US/contact.md')), 'en-US/contact')), 'en-US/coupon': wrapper(r => require.ensure([], () => r(require('./en-US/coupon.md')), 'en-US/coupon')), 'en-US/datetime-picker': wrapper(r => require.ensure([], () => r(require('./en-US/datetime-picker.md')), 'en-US/datetime-picker')), diff --git a/docs/markdown/zh-CN/actionsheet.md b/docs/markdown/zh-CN/actionsheet.md index 310808041..a91d53b94 100644 --- a/docs/markdown/zh-CN/actionsheet.md +++ b/docs/markdown/zh-CN/actionsheet.md @@ -72,6 +72,7 @@ export default { | cancel-text | 取消按钮文案 | `String` | - | - | | overlay | 是否显示遮罩 | `Boolean` | - | - | | close-on-click-overlay | 点击遮罩是否关闭`Actionsheet` | `Boolean` | - | - | +| get-container | 指定挂载的 HTML 节点 | `Function` | - | `() => HTMLElement` | ### actions diff --git a/docs/markdown/zh-CN/circle.md b/docs/markdown/zh-CN/circle.md new file mode 100644 index 000000000..e0c2fee3e --- /dev/null +++ b/docs/markdown/zh-CN/circle.md @@ -0,0 +1,70 @@ +## Circle 环形进度条 + +### 使用指南 +``` javascript +import { Circle } from 'vant'; + +Vue.use(Circle); +``` + +### 代码演示 + +#### 基础用法 +通过 `rate` 指定目标进度,`v-model` 代表当前进度,`speed` 控制动画速度 + +```html + +``` + +``` javascript +export default { + data() { + return { + currentRate: 0 + }; + }, + computed: { + text() { + return this.currentRate.toFixed(0) + '%' + } + } +}; +``` + +#### 样式定制 + +```html + +``` + + +### API + +| 参数 | 说明 | 类型 | 默认值 | 可选值 | +|-----------|-----------|-----------|-------------|-------------| +| v-model | 当前进度 | `Number` | - | - | +| rate | 目标进度 | `Number` | `100` | - | +| size | 圆环直径 | `String` | `100px` | - | +| color | 进度条颜色 | `String` | `#38f` | - | +| layer-color | 轨道颜色 | `String` | `#fff` | - | +| fill | 填充颜色 | `String` | `none` | - | +| speed | 动画速度(单位为 rate/s)| `Number` | - | - | +| text | 文字 | `String` | - | - | +| stroke-width | 进度条宽度 | `Number` | `40` | - | +| clockwise | 是否顺时针增加 | `Boolean` | `true` | - | diff --git a/docs/markdown/zh-CN/popup.md b/docs/markdown/zh-CN/popup.md index e0ed9e492..47b33a47b 100644 --- a/docs/markdown/zh-CN/popup.md +++ b/docs/markdown/zh-CN/popup.md @@ -48,3 +48,4 @@ export default { | close-on-click-overlay | 点击蒙层是否关闭 Popup | `Boolean` | `true` | - | | transition | transition 名称 | `String` | `popup-slide` | - | | prevent-scroll | 是否防止滚动穿透 | `Boolean` | `false` | - | +| get-container | 指定弹出层挂载的 HTML 节点 | `Function` | - | `() => HTMLElement` | diff --git a/docs/markdown/zh-CN/sku.md b/docs/markdown/zh-CN/sku.md index 21b4f3a19..d5fec3c72 100644 --- a/docs/markdown/zh-CN/sku.md +++ b/docs/markdown/zh-CN/sku.md @@ -22,6 +22,7 @@ Vue.use(Sku); :reset-stepper-on-hide="resetStepperOnHide" :reset-selected-sku-on-hide="resetSelectedSkuOnHide" :disable-stepper-input="disableStepperInput" + :message-config="messageConfig" @buy-clicked="onBuyClicked" @add-cart="onAddCartClicked" /> @@ -91,6 +92,8 @@ Vue.use(Sku); | disable-stepper-input | 是否禁用sku中stepper的input框 | `Boolean` | `false` | - | | stepper-title | 数量选择组件左侧文案 | `String` | `购买数量` | - | | custom-stepper-config | 步进器相关自定义配置 | `Object` | `{}` | - | +| message-config | 留言相关配置 | `Object` | `{}` | - | +| get-container | 指定挂载的 HTML 节点 | `Function` | - | `() => HTMLElement` | ### Event @@ -206,6 +209,26 @@ customStepperConfig: { } ``` +#### messageConfig Data Structure +```javascript +messageConfig: { + // 图片上传回调,需要返回一个promise,promise正确执行的结果需要是一个图片url + uploadImg: () => { + return new Promise((resolve) => { + setTimeout(() => resolve('https://img.yzcdn.cn/upload_files/2017/02/21/FjKTOxjVgnUuPmHJRdunvYky9OHP.jpg!100x100.jpg'), 1000); + }); + }, + // 最大上传体积 (MB) + uploadMaxSize: 3, + // placehold配置 + placeholderMap: { + text: 'xxx', + tel: 'xxx', + ... + } +} +``` + #### 添加购物车和点击购买回调函数接收的 skuData 对象结构 ```javascript skuData: { diff --git a/docs/src/doc.config.js b/docs/src/doc.config.js index 6a4a29ffd..77189b041 100644 --- a/docs/src/doc.config.js +++ b/docs/src/doc.config.js @@ -80,6 +80,10 @@ module.exports = { path: '/cell', title: 'Cell - 单元格' }, + { + path: '/circle', + title: 'Circle - 环形进度条' + }, { path: '/icon', title: 'Icon - 图标' @@ -358,6 +362,10 @@ module.exports = { path: '/cell', title: 'Cell' }, + { + path: '/circle', + title: 'Circle' + }, { path: '/icon', title: 'Icon' diff --git a/packages/actionsheet/index.vue b/packages/actionsheet/index.vue index ec1333ffa..0cc15f580 100644 --- a/packages/actionsheet/index.vue +++ b/packages/actionsheet/index.vue @@ -60,10 +60,6 @@ export default create({ } }, - mounted() { - this.value && this.open(); - }, - methods: { onClickItem(item) { if (typeof item.callback === 'function') { diff --git a/packages/circle/index.vue b/packages/circle/index.vue new file mode 100644 index 000000000..1040124da --- /dev/null +++ b/packages/circle/index.vue @@ -0,0 +1,126 @@ + + + diff --git a/packages/coupon-list/index.vue b/packages/coupon-list/index.vue index b3dddeda5..a2e40cc17 100644 --- a/packages/coupon-list/index.vue +++ b/packages/coupon-list/index.vue @@ -53,7 +53,6 @@ import Cell from '../cell'; import CellGroup from '../cell-group'; import CouponItem from './Item'; import Field from '../field'; -import Popup from '../popup'; import VanButton from '../button'; export default create({ @@ -64,7 +63,6 @@ export default create({ Cell, CellGroup, Field, - Popup, CouponItem }, diff --git a/packages/index.js b/packages/index.js index cbd7e654f..f0c6cd13c 100644 --- a/packages/index.js +++ b/packages/index.js @@ -12,6 +12,7 @@ import CellGroup from './cell-group'; import CellSwipe from './cell-swipe'; import Checkbox from './checkbox'; import CheckboxGroup from './checkbox-group'; +import Circle from './circle'; import Col from './col'; import ContactCard from './contact-card'; import ContactEdit from './contact-edit'; @@ -77,6 +78,7 @@ const components = [ CellSwipe, Checkbox, CheckboxGroup, + Circle, Col, ContactCard, ContactEdit, @@ -149,6 +151,7 @@ export { CellSwipe, Checkbox, CheckboxGroup, + Circle, Col, ContactCard, ContactEdit, diff --git a/packages/locale/lang/en-US.js b/packages/locale/lang/en-US.js index 1523d74cd..d3fe13f4c 100644 --- a/packages/locale/lang/en-US.js +++ b/packages/locale/lang/en-US.js @@ -113,10 +113,12 @@ export default { }, vanSkuMessages: { fill: 'Please fill', + upload: 'Please upload', number: 'Please fill in the correct number format message', email: 'Please fill in the correct email message', idcard: 'Please fill in the correct ID number message', overlimit: 'not more than 200 words', + onePic: 'only one picture', placeholder: { 'id_no': 'Idcard Number', text: 'Text', @@ -127,6 +129,15 @@ export default { textarea: 'Text' } }, + vanSkuImgUploader: { + or: 'Or', + uploading: 'Uploading...', + rephoto: 'Take Again', + photo: 'Take', + reselect: 'Reselect', + select: 'Select Photo', + maxSize: maxSize => `The upload limit is up to ${maxSize}MB,please try to compress the photo` + }, vanSkuStepper: { title: 'Quantity', remain: count => `Remain ${count} items`, diff --git a/packages/locale/lang/zh-CN.js b/packages/locale/lang/zh-CN.js index 074fa1f3c..582b3c79a 100644 --- a/packages/locale/lang/zh-CN.js +++ b/packages/locale/lang/zh-CN.js @@ -117,10 +117,12 @@ export default { }, vanSkuMessages: { fill: '请填写', + upload: '请上传', number: '请填写正确的数字格式留言', email: '请填写正确的邮箱', 'id_no': '请填写正确的身份证号码', overlimit: '写的太多了,不要超过200字', + onePic: '仅限一张', placeholder: { 'id_no': '输入18位身份证号码', text: '输入文本', @@ -131,6 +133,15 @@ export default { textarea: '点击填写段落文本' } }, + vanSkuImgUploader: { + or: '或', + uploading: '正在上传...', + rephoto: '重拍', + photo: '拍照', + reselect: '重新选择照片', + select: '选择照片', + maxSize: maxSize => `最大可上传图片为${maxSize}MB,请尝试压缩图片尺寸` + }, vanSkuStepper: { title: '购买数量', remain: count => `剩余${count}件`, diff --git a/packages/mixins/popup/index.js b/packages/mixins/popup/index.js index 7b51213ea..399f38edf 100644 --- a/packages/mixins/popup/index.js +++ b/packages/mixins/popup/index.js @@ -19,6 +19,8 @@ export default { zIndex: [String, Number], // prevent touchmove scroll preventScroll: Boolean, + // return the mount node for popup + getContainer: Function, // prevent body scroll lockOnScroll: { type: Boolean, @@ -26,17 +28,8 @@ export default { } }, - watch: { - value(val) { - this[val ? 'open' : 'close'](); - } - }, - - beforeMount() { - this._popupId = 'popup-' + context.plusKey('idSeed'); - }, - data() { + this._popupId = 'popup-' + context.plusKey('idSeed'); return { opened: false, pos: { @@ -46,6 +39,29 @@ export default { }; }, + watch: { + value(val) { + this[val ? 'open' : 'close'](); + }, + + getContainer() { + this.move(); + } + }, + + mounted() { + if (this.getContainer) { + this.move(); + } + if (this.value) { + this.open(); + } + }, + + beforeDestroy() { + this.doAfterClose(); + }, + methods: { recordPosition(e) { this.pos = { @@ -65,12 +81,14 @@ export default { let status = '11'; + /* istanbul ignore next */ if (scrollTop === 0) { status = offsetHeight >= scrollHeight ? '00' : '01'; } else if (scrollTop + offsetHeight >= scrollHeight) { status = '10'; } + /* istanbul ignore next */ if ( status !== '11' && isVertical && @@ -82,6 +100,7 @@ export default { }, open() { + /* istanbul ignore next */ if (this.opened || this.$isServer) { return; } @@ -137,10 +156,14 @@ export default { off(document, 'touchstart', this.recordPosition); off(document, 'touchmove', this.watchTouchMove); } - } - }, + }, - beforeDestroy() { - this.doAfterClose(); + move() { + if (this.getContainer) { + this.getContainer().appendChild(this.$el); + } else if (this.$parent) { + this.$parent.$el.appendChild(this.$el); + } + } } }; diff --git a/packages/mixins/popup/manager.js b/packages/mixins/popup/manager.js index 319c8da89..bf2e1c104 100644 --- a/packages/mixins/popup/manager.js +++ b/packages/mixins/popup/manager.js @@ -41,6 +41,7 @@ const manager = { const { id, dom } = config; const exist = context.stack.some(item => item.id === id); + /* istanbul ignore next */ if (!exist) { const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body; context.stack.push({ instance, id, config, targetNode }); diff --git a/packages/picker/PickerColumn.vue b/packages/picker/PickerColumn.vue index 365973601..97e6da7e1 100644 --- a/packages/picker/PickerColumn.vue +++ b/packages/picker/PickerColumn.vue @@ -13,6 +13,7 @@
  • {{ cancelButtonText || $t('cancel') }}
    +
    {{ confirmButtonText || $t('confirm') }}
    -
    diff --git a/packages/popup/index.vue b/packages/popup/index.vue index 9700ce2ce..a6291cfa5 100644 --- a/packages/popup/index.vue +++ b/packages/popup/index.vue @@ -41,12 +41,6 @@ export default create({ currentValue: false, currentTransition: transition }; - }, - - mounted() { - if (this.value) { - this.open(); - } } }); diff --git a/packages/sku/Sku.vue b/packages/sku/Sku.vue index 7d503a2ab..807ebfe77 100644 --- a/packages/sku/Sku.vue +++ b/packages/sku/Sku.vue @@ -1,5 +1,12 @@