diff --git a/README.md b/README.md index a0f49455a..766f5857c 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,17 @@ logo

-

Mobile UI Components built on Vue

+

Vant

+ +

Mobile UI Components built on Vue

- npm version - npm version - Coverage Status - downloads - Gzip Size + npm version + npm version + Coverage Status + downloads + Jsdelivr Hits + Gzip Size

diff --git a/README.zh-CN.md b/README.zh-CN.md index 0fd160821..e3804faf1 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,14 +1,18 @@

logo

-

轻量、可靠的移动端 Vue 组件库

+ +

Vant

+ +

轻量、可靠的移动端 Vue 组件库

- npm version - npm version - Coverage Status - downloads - Gzip Size + npm version + npm version + Coverage Status + downloads + Jsdelivr Hits + Gzip Size

diff --git a/docs/markdown/changelog.en-US.md b/docs/markdown/changelog.en-US.md index 54ed52e5e..986adf6c3 100644 --- a/docs/markdown/changelog.en-US.md +++ b/docs/markdown/changelog.en-US.md @@ -10,6 +10,26 @@ Vant follows [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/). - Minor version:released every one to two months, including backwards compatible features. - Major version:including breaking changes and new features. +### [v2.9.1-beta.1](https://github.com/youzan/vant/compare/v2.9.0...v2.9.1-beta.1) + +`2020-07-07` + +**Feature** + +- Field: add clear-trigger prop [#6699](https://github.com/youzan/vant/issues/6699) +- Search: add clear-trigger prop [#6700](https://github.com/youzan/vant/issues/6700) +- Uploader: add preview-cover slot [#6707](https://github.com/youzan/vant/issues/6707) +- Sku: improve message datetime picker [8d29e5](https://github.com/youzan/vant/commit/8d29e5c8c6df278800865596f285c17029150963) [7343e5](https://github.com/youzan/vant/commit/7343e55409900635a0e39063edb9f67493048a54) + +**Bug Fixes** + +- Calendar: subtitle not updated in some cases [#6723](https://github.com/youzan/vant/issues/6723) +- Checkbox: dynamic bind group [#6730](https://github.com/youzan/vant/issues/6730) +- Image: memory leak during SSR [#6721](https://github.com/youzan/vant/issues/6721) +- ImagePreview: swipeTo type should be optional [#6727](https://github.com/youzan/vant/issues/6727) +- Picker: click during momentum case incorrect result [#6724](https://github.com/youzan/vant/issues/6724) +- Popup: lock-scroll not work in some cases [#6698](https://github.com/youzan/vant/issues/6698) + ### [v2.9.0](https://github.com/youzan/vant/compare/v2.8.7...v2.9.0) `2020-07-03` diff --git a/docs/markdown/changelog.zh-CN.md b/docs/markdown/changelog.zh-CN.md index ba5b98011..89062cb62 100644 --- a/docs/markdown/changelog.zh-CN.md +++ b/docs/markdown/changelog.zh-CN.md @@ -10,6 +10,26 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。 - 次版本号:每隔一至二个月发布,包含新特性和较大的功能更新,向下兼容。 - 主版本号:发布时间不定,包含不兼容更新,预计下一个主版本会与 Vue 3.0 同期发布。 +### [v2.9.1-beta.1](https://github.com/youzan/vant/compare/v2.9.0...v2.9.1-beta.1) + +`2020-07-07` + +**Feature** + +- Field: 新增 clear-trigger 属性 [#6699](https://github.com/youzan/vant/issues/6699) +- Search: 新增 clear-trigger 属性 [#6700](https://github.com/youzan/vant/issues/6700) +- Uploader: 新增 preview-cover 插槽 [#6707](https://github.com/youzan/vant/issues/6707) +- Sku: 优化留言栏时间选择交互 [8d29e5](https://github.com/youzan/vant/commit/8d29e5c8c6df278800865596f285c17029150963) [7343e5](https://github.com/youzan/vant/commit/7343e55409900635a0e39063edb9f67493048a54) + +**Bug Fixes** + +- Calendar: 修复个别情况下日历标题不更新的问题 [#6723](https://github.com/youzan/vant/issues/6723) +- Checkbox: 修复动态设置 bind-group 时不生效的问题 [#6730](https://github.com/youzan/vant/issues/6730) +- Image: 修复 SSR 时 LazyLoad 属性存在内存泄露的问题 [#6721](https://github.com/youzan/vant/issues/6721) +- ImagePreview: 修复 swipeTo 方法类型定义错误 [#6727](https://github.com/youzan/vant/issues/6727) +- Picker: 修复惯性滚动过程中点击选项会导致选中结果错误的问题 [#6724](https://github.com/youzan/vant/issues/6724) +- Popup: 修复 lock-scroll 在个别场景下不生效的问题 [#6698](https://github.com/youzan/vant/issues/6698) + ### [v2.9.0](https://github.com/youzan/vant/compare/v2.8.7...v2.9.0) `2020-07-03` diff --git a/package.json b/package.json index 5495a37bc..51a6f4738 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vant", - "version": "2.9.0", + "version": "2.9.1-beta.1", "description": "Mobile UI Components built on Vue", "main": "lib/index.js", "module": "es/index.js", @@ -40,8 +40,12 @@ "url": "git@github.com:youzan/vant.git" }, "keywords": [ + "ui", "vue", - "component" + "frontend", + "mobile ui", + "component", + "components" ], "author": "youzanfe", "license": "MIT", diff --git a/src/form/demo/FieldTypeArea.vue b/src/form/demo/FieldTypeArea.vue index 01731324c..f8bcfeb5a 100644 --- a/src/form/demo/FieldTypeArea.vue +++ b/src/form/demo/FieldTypeArea.vue @@ -10,6 +10,7 @@ > + + + + + ); + }, +}); diff --git a/src/sku/components/SkuImgUploader.js b/src/sku/components/SkuImgUploader.js index a9d8003aa..b017c1eba 100644 --- a/src/sku/components/SkuImgUploader.js +++ b/src/sku/components/SkuImgUploader.js @@ -2,11 +2,11 @@ import { createNamespace } from '../../utils'; // Components -import Icon from '../../icon'; -import Loading from '../../loading'; import Uploader from '../../uploader'; -const [createComponent, bem, t] = createNamespace('sku-img-uploader'); +const namespace = createNamespace('sku-img-uploader'); +const createComponent = namespace[0]; +const t = namespace[2]; export default createComponent({ props: { @@ -20,26 +20,32 @@ export default createComponent({ data() { return { - // 正在上传的图片 base64 - paddingImg: '', - uploadFail: false, + fileList: [], }; }, + watch: { + value(val) { + if (val) { + this.fileList = [{ url: val, isImage: true }]; + } else { + this.fileList = []; + } + }, + }, + methods: { afterReadFile(file) { - // 上传文件 - this.paddingImg = file.content; - this.uploadFail = false; + file.status = 'uploading'; + file.message = t('uploading'); this.uploadImg(file.file, file.content) .then((img) => { + file.status = 'done'; this.$emit('input', img); - this.$nextTick(() => { - this.paddingImg = ''; - }); }) .catch(() => { - this.uploadFail = true; + file.status = 'failed'; + file.message = t('fail'); }); }, @@ -47,68 +53,21 @@ export default createComponent({ this.$toast(t('oversize', this.maxSize)); }, - genUploader(content, disabled = false) { - return ( - -

{content}
- - ); - }, - - genMask() { - return ( -
- {this.uploadFail ? ( - [ - , -
, - ] - ) : ( - - )} -
- ); + onDelete() { + this.$emit('input', ''); }, }, render() { return ( -
- {this.value && - this.genUploader( - [ - , - { - this.$emit('input', ''); - }} - />, - ], - true - )} - - {this.paddingImg && - this.genUploader( - [, this.genMask()], - !this.uploadFail - )} - - {!this.value && - !this.paddingImg && - this.genUploader( -
- -
- )} -
+ ); }, }); diff --git a/src/sku/components/SkuMessages.js b/src/sku/components/SkuMessages.js index 854e046a3..7c50eda87 100644 --- a/src/sku/components/SkuMessages.js +++ b/src/sku/components/SkuMessages.js @@ -7,6 +7,7 @@ import { isNumeric } from '../../utils/validate/number'; import Cell from '../../cell'; import Field from '../../field'; import SkuImgUploader from './SkuImgUploader'; +import SkuDateTimeField from './SkuDateTimeField'; const [createComponent, bem, t] = createNamespace('sku-messages'); @@ -48,18 +49,14 @@ export default createComponent({ if (message.type === 'id_no') { return 'text'; } - return message.datetime > 0 ? 'datetime-local' : message.type; + return message.datetime > 0 ? 'datetime' : message.type; }, getMessages() { const messages = {}; this.messageValues.forEach((item, index) => { - let { value } = item; - if (this.messages[index].datetime > 0) { - value = value.replace(/T/g, ' '); - } - messages[`message_${index}`] = value; + messages[`message_${index}`] = item.value; }); return messages; @@ -69,12 +66,8 @@ export default createComponent({ const messages = {}; this.messageValues.forEach((item, index) => { - let { value } = item; const message = this.messages[index]; - if (message.datetime > 0) { - value = value.replace(/T/g, ' '); - } - messages[message.name] = value; + messages[message.name] = item.value; }); return messages; @@ -125,7 +118,6 @@ export default createComponent({ +
{t('imageLabel')}
); } + // 时间和日期使用的vant选择器 + const isDateOrTime = ['date', 'time'].indexOf(message.type) > -1; + if (isDateOrTime) { + return ( + + ); + } + return ( `最大可上传图片为${maxSize}MB,请尝试压缩图片尺寸`, - fail: '上传失败
重新上传', + fail: '上传失败', + uploading: '上传中...', }, vanSkuStepper: { quotaLimit: (quota: number) => `限购${quota}件`, @@ -45,18 +46,32 @@ export default { id_no: '请填写正确的身份证号码', }, placeholder: { - id_no: '输入身份证号码', - text: '输入文本', - tel: '输入数字', - email: '输入邮箱', - date: '点击选择日期', - time: '点击选择时间', - textarea: '点击填写段落文本', - mobile: '输入手机号码', + id_no: '请填写身份证号', + text: '请填写留言', + tel: '请填写数字', + email: '请填写邮箱', + date: '请选择日期', + time: '请选择时间', + textarea: '请填写留言', + mobile: '请填写手机号', }, }, vanSkuRow: { multiple: '可多选', }, + vanSkuDatetimeField: { + title: { + date: '选择年月日', + time: '选择时间', + datetime: '选择日期时间', + }, + format: { + year: '年', + month: '月', + day: '日', + hour: '时', + minute: '分', + }, + }, }, }; diff --git a/src/sku/test/index.spec.js b/src/sku/test/index.spec.js index 7dcf2cc5e..01efb6f04 100644 --- a/src/sku/test/index.spec.js +++ b/src/sku/test/index.spec.js @@ -1,6 +1,7 @@ import { mount } from '../../../test'; import Sku from '..'; import { getSkuData, initialSku } from '../demo/data'; +import { stringToDate, dateToString } from '../utils/time-helper'; const skuData = getSkuData(); @@ -30,3 +31,14 @@ test('resetSelectedSku method', () => { wrapper.find('.van-button--danger').trigger('click'); expect(wrapper.emitted('buy-clicked').length).toEqual(1); }); + +test('stringToDate', () => { + expect(dateToString(stringToDate(''))).toEqual(''); + expect(dateToString(stringToDate('2020-07-01'))).toEqual('2020-07-01'); + expect(dateToString(stringToDate('2020-07-01 22:44'), 'datetime')).toEqual( + '2020-07-01 22:44' + ); + expect(dateToString(stringToDate('2020-12-31 23:59'), 'datetime')).toEqual( + '2020-12-31 23:59' + ); +}); diff --git a/src/sku/utils/time-helper.js b/src/sku/utils/time-helper.js new file mode 100644 index 000000000..2010e10b8 --- /dev/null +++ b/src/sku/utils/time-helper.js @@ -0,0 +1,28 @@ +import { padZero } from '../../utils/format/string'; + +// 字符串转 Date +// 只处理 YYYY-MM-DD 或者 YYYY-MM-DD HH:MM 格式 +export function stringToDate(timeString) { + if (!timeString) { + return null; + } + return new Date(timeString.replace(/-/g, '/')); +} + +// Date 转字符串 +// type: date or datetime +export function dateToString(date, type = 'date') { + if (!date) { + return ''; + } + const year = date.getFullYear(); + const month = date.getMonth() + 1; + const day = date.getDate(); + let timeString = `${year}-${padZero(month)}-${padZero(day)}`; + if (type === 'datetime') { + const hours = date.getHours(); + const minute = date.getMinutes(); + timeString += ` ${padZero(hours)}:${padZero(minute)}`; + } + return timeString; +} diff --git a/types/image-preview.d.ts b/types/image-preview.d.ts index 4792825b0..01a209c91 100644 --- a/types/image-preview.d.ts +++ b/types/image-preview.d.ts @@ -20,9 +20,9 @@ export type ImagePreviewOptions = closeOnPopstate?: boolean; closeIconPosition?: string; getContainer?: string | (() => Element); - onClose?: () => void; - onChange?: (index: number) => void; - swipeTo(index: number, options?: SwipeToOptions): void; + onClose?(): void; + onChange?(index: number): void; + swipeTo?(index: number, options?: SwipeToOptions): void; }; export class VanImagePreview extends VanPopupMixin {