Showing
98 changed files
with
1045 additions
and
323 deletions
| 1 | import { VantComponent } from '../common/component'; | 1 | import { VantComponent } from '../common/component'; |
| 2 | import { button } from '../mixins/button'; | 2 | import { button } from '../mixins/button'; |
| 3 | VantComponent({ | 3 | VantComponent({ |
| 4 | + classes: ['list-class'], | ||
| 4 | mixins: [button], | 5 | mixins: [button], |
| 5 | props: { | 6 | props: { |
| 6 | show: Boolean, | 7 | show: Boolean, |
| ... | @@ -35,6 +36,10 @@ VantComponent({ | ... | @@ -35,6 +36,10 @@ VantComponent({ |
| 35 | type: Boolean, | 36 | type: Boolean, |
| 36 | value: true, | 37 | value: true, |
| 37 | }, | 38 | }, |
| 39 | + rootPortal: { | ||
| 40 | + type: Boolean, | ||
| 41 | + value: false, | ||
| 42 | + }, | ||
| 38 | }, | 43 | }, |
| 39 | methods: { | 44 | methods: { |
| 40 | onSelect(event) { | 45 | onSelect(event) { | ... | ... |
| ... | @@ -6,9 +6,10 @@ | ... | @@ -6,9 +6,10 @@ |
| 6 | round="{{ round }}" | 6 | round="{{ round }}" |
| 7 | z-index="{{ zIndex }}" | 7 | z-index="{{ zIndex }}" |
| 8 | overlay="{{ overlay }}" | 8 | overlay="{{ overlay }}" |
| 9 | - custom-class="van-action-sheet" | 9 | + custom-class="van-action-sheet custom-class" |
| 10 | safe-area-inset-bottom="{{ safeAreaInsetBottom }}" | 10 | safe-area-inset-bottom="{{ safeAreaInsetBottom }}" |
| 11 | close-on-click-overlay="{{ closeOnClickOverlay }}" | 11 | close-on-click-overlay="{{ closeOnClickOverlay }}" |
| 12 | + root-portal="{{ rootPortal }}" | ||
| 12 | bind:close="onClickOverlay" | 13 | bind:close="onClickOverlay" |
| 13 | > | 14 | > |
| 14 | <view wx:if="{{ title }}" class="van-action-sheet__header"> | 15 | <view wx:if="{{ title }}" class="van-action-sheet__header"> |
| ... | @@ -22,7 +23,7 @@ | ... | @@ -22,7 +23,7 @@ |
| 22 | <view wx:if="{{ description }}" class="van-action-sheet__description van-hairline--bottom"> | 23 | <view wx:if="{{ description }}" class="van-action-sheet__description van-hairline--bottom"> |
| 23 | {{ description }} | 24 | {{ description }} |
| 24 | </view> | 25 | </view> |
| 25 | - <view wx:if="{{ actions && actions.length }}"> | 26 | + <view wx:if="{{ actions && actions.length }}" class="list-class"> |
| 26 | <!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 --> | 27 | <!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 --> |
| 27 | <button | 28 | <button |
| 28 | wx:for="{{ actions }}" | 29 | wx:for="{{ actions }}" | ... | ... |
| ... | @@ -2,10 +2,10 @@ | ... | @@ -2,10 +2,10 @@ |
| 2 | <wxs src="./index.wxs" module="computed" /> | 2 | <wxs src="./index.wxs" module="computed" /> |
| 3 | 3 | ||
| 4 | <button | 4 | <button |
| 5 | - id="{{ id }}" | 5 | + id="{{ id || buttonId }}" |
| 6 | data-detail="{{ dataset }}" | 6 | data-detail="{{ dataset }}" |
| 7 | class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}" | 7 | class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}" |
| 8 | - hover-class="van-button--active hover-class" | 8 | + hover-class="{{ disabled || loading ? '' : 'van-button--active hover-class'}}" |
| 9 | lang="{{ lang }}" | 9 | lang="{{ lang }}" |
| 10 | form-type="{{ formType }}" | 10 | form-type="{{ formType }}" |
| 11 | style="{{ computed.rootStyle({ plain, color, customStyle }) }}" | 11 | style="{{ computed.rootStyle({ plain, color, customStyle }) }}" |
| ... | @@ -22,9 +22,12 @@ | ... | @@ -22,9 +22,12 @@ |
| 22 | bindgetuserinfo="onGetUserInfo" | 22 | bindgetuserinfo="onGetUserInfo" |
| 23 | bindcontact="onContact" | 23 | bindcontact="onContact" |
| 24 | bindgetphonenumber="onGetPhoneNumber" | 24 | bindgetphonenumber="onGetPhoneNumber" |
| 25 | + bindgetrealtimephonenumber="onGetRealTimePhoneNumber" | ||
| 26 | + bindagreeprivacyauthorization="onAgreePrivacyAuthorization" | ||
| 25 | binderror="onError" | 27 | binderror="onError" |
| 26 | bindlaunchapp="onLaunchApp" | 28 | bindlaunchapp="onLaunchApp" |
| 27 | bindopensetting="onOpenSetting" | 29 | bindopensetting="onOpenSetting" |
| 30 | + bindchooseavatar="onChooseAvatar" | ||
| 28 | > | 31 | > |
| 29 | <block wx:if="{{ loading }}"> | 32 | <block wx:if="{{ loading }}"> |
| 30 | <van-loading | 33 | <van-loading | ... | ... |
| 1 | +<wxs src="./index.wxs" module="computed" /> | ||
| 2 | +<wxs src="../wxs/utils.wxs" module="utils" /> | ||
| 1 | <view class="van-calendar"> | 3 | <view class="van-calendar"> |
| 2 | <header | 4 | <header |
| 3 | title="{{ title }}" | 5 | title="{{ title }}" |
| ... | @@ -54,12 +56,12 @@ | ... | @@ -54,12 +56,12 @@ |
| 54 | type="danger" | 56 | type="danger" |
| 55 | color="{{ color }}" | 57 | color="{{ color }}" |
| 56 | custom-class="van-calendar__confirm" | 58 | custom-class="van-calendar__confirm" |
| 57 | - disabled="{{ computed.getButtonDisabled(type, currentDate) }}" | 59 | + disabled="{{ computed.getButtonDisabled(type, currentDate, minRange) }}" |
| 58 | nativeType="text" | 60 | nativeType="text" |
| 59 | bind:click="onConfirm" | 61 | bind:click="onConfirm" |
| 60 | > | 62 | > |
| 61 | {{ | 63 | {{ |
| 62 | - computed.getButtonDisabled(type, currentDate) | 64 | + computed.getButtonDisabled(type, currentDate, minRange) |
| 63 | ? confirmDisabledText | 65 | ? confirmDisabledText |
| 64 | : confirmText | 66 | : confirmText |
| 65 | }} | 67 | }} | ... | ... |
| ... | @@ -40,6 +40,7 @@ VantComponent({ | ... | @@ -40,6 +40,7 @@ VantComponent({ |
| 40 | }, | 40 | }, |
| 41 | defaultDate: { | 41 | defaultDate: { |
| 42 | type: null, | 42 | type: null, |
| 43 | + value: getToday().getTime(), | ||
| 43 | observer(val) { | 44 | observer(val) { |
| 44 | this.setData({ currentDate: val }); | 45 | this.setData({ currentDate: val }); |
| 45 | this.scrollIntoView(); | 46 | this.scrollIntoView(); |
| ... | @@ -103,17 +104,33 @@ VantComponent({ | ... | @@ -103,17 +104,33 @@ VantComponent({ |
| 103 | type: null, | 104 | type: null, |
| 104 | value: null, | 105 | value: null, |
| 105 | }, | 106 | }, |
| 107 | + minRange: { | ||
| 108 | + type: Number, | ||
| 109 | + value: 1, | ||
| 110 | + }, | ||
| 106 | firstDayOfWeek: { | 111 | firstDayOfWeek: { |
| 107 | type: Number, | 112 | type: Number, |
| 108 | value: 0, | 113 | value: 0, |
| 109 | }, | 114 | }, |
| 110 | readonly: Boolean, | 115 | readonly: Boolean, |
| 116 | + rootPortal: { | ||
| 117 | + type: Boolean, | ||
| 118 | + value: false, | ||
| 119 | + }, | ||
| 111 | }, | 120 | }, |
| 112 | data: { | 121 | data: { |
| 113 | subtitle: '', | 122 | subtitle: '', |
| 114 | currentDate: null, | 123 | currentDate: null, |
| 115 | scrollIntoView: '', | 124 | scrollIntoView: '', |
| 116 | }, | 125 | }, |
| 126 | + watch: { | ||
| 127 | + minDate() { | ||
| 128 | + this.initRect(); | ||
| 129 | + }, | ||
| 130 | + maxDate() { | ||
| 131 | + this.initRect(); | ||
| 132 | + }, | ||
| 133 | + }, | ||
| 117 | created() { | 134 | created() { |
| 118 | this.setData({ | 135 | this.setData({ |
| 119 | currentDate: this.getInitialDate(this.data.defaultDate), | 136 | currentDate: this.getInitialDate(this.data.defaultDate), |
| ... | @@ -127,7 +144,7 @@ VantComponent({ | ... | @@ -127,7 +144,7 @@ VantComponent({ |
| 127 | }, | 144 | }, |
| 128 | methods: { | 145 | methods: { |
| 129 | reset() { | 146 | reset() { |
| 130 | - this.setData({ currentDate: this.getInitialDate() }); | 147 | + this.setData({ currentDate: this.getInitialDate(this.data.defaultDate) }); |
| 131 | this.scrollIntoView(); | 148 | this.scrollIntoView(); |
| 132 | }, | 149 | }, |
| 133 | initRect() { | 150 | initRect() { |
| ... | @@ -159,15 +176,19 @@ VantComponent({ | ... | @@ -159,15 +176,19 @@ VantComponent({ |
| 159 | return date; | 176 | return date; |
| 160 | }, | 177 | }, |
| 161 | getInitialDate(defaultDate = null) { | 178 | getInitialDate(defaultDate = null) { |
| 162 | - const { type, minDate, maxDate } = this.data; | 179 | + const { type, minDate, maxDate, allowSameDay } = this.data; |
| 180 | + if (!defaultDate) | ||
| 181 | + return []; | ||
| 163 | const now = getToday().getTime(); | 182 | const now = getToday().getTime(); |
| 164 | if (type === 'range') { | 183 | if (type === 'range') { |
| 165 | if (!Array.isArray(defaultDate)) { | 184 | if (!Array.isArray(defaultDate)) { |
| 166 | defaultDate = []; | 185 | defaultDate = []; |
| 167 | } | 186 | } |
| 168 | const [startDay, endDay] = defaultDate || []; | 187 | const [startDay, endDay] = defaultDate || []; |
| 169 | - const start = this.limitDateRange(startDay || now, minDate, getPrevDay(new Date(maxDate)).getTime()); | 188 | + const startDate = getTime(startDay || now); |
| 170 | - const end = this.limitDateRange(endDay || now, getNextDay(new Date(minDate)).getTime()); | 189 | + const start = this.limitDateRange(startDate, minDate, allowSameDay ? startDate : getPrevDay(new Date(maxDate)).getTime()); |
| 190 | + const date = getTime(endDay || now); | ||
| 191 | + const end = this.limitDateRange(date, allowSameDay ? date : getNextDay(new Date(minDate)).getTime()); | ||
| 171 | return [start, end]; | 192 | return [start, end]; |
| 172 | } | 193 | } |
| 173 | if (type === 'multiple') { | 194 | if (type === 'multiple') { |
| ... | @@ -184,6 +205,8 @@ VantComponent({ | ... | @@ -184,6 +205,8 @@ VantComponent({ |
| 184 | scrollIntoView() { | 205 | scrollIntoView() { |
| 185 | requestAnimationFrame(() => { | 206 | requestAnimationFrame(() => { |
| 186 | const { currentDate, type, show, poppable, minDate, maxDate } = this.data; | 207 | const { currentDate, type, show, poppable, minDate, maxDate } = this.data; |
| 208 | + if (!currentDate) | ||
| 209 | + return; | ||
| 187 | // @ts-ignore | 210 | // @ts-ignore |
| 188 | const targetDate = type === 'single' ? currentDate : currentDate[0]; | 211 | const targetDate = type === 'single' ? currentDate : currentDate[0]; |
| 189 | const displayed = show || !poppable; | 212 | const displayed = show || !poppable; |
| ... | @@ -240,7 +263,7 @@ VantComponent({ | ... | @@ -240,7 +263,7 @@ VantComponent({ |
| 240 | this.select([date, null]); | 263 | this.select([date, null]); |
| 241 | } | 264 | } |
| 242 | else if (allowSameDay) { | 265 | else if (allowSameDay) { |
| 243 | - this.select([date, date]); | 266 | + this.select([date, date], true); |
| 244 | } | 267 | } |
| 245 | } | 268 | } |
| 246 | else { | 269 | else { | ... | ... |
| ... | @@ -12,6 +12,8 @@ | ... | @@ -12,6 +12,8 @@ |
| 12 | position="{{ position }}" | 12 | position="{{ position }}" |
| 13 | closeable="{{ showTitle || showSubtitle }}" | 13 | closeable="{{ showTitle || showSubtitle }}" |
| 14 | close-on-click-overlay="{{ closeOnClickOverlay }}" | 14 | close-on-click-overlay="{{ closeOnClickOverlay }}" |
| 15 | + safe-area-inset-bottom="{{ safeAreaInsetBottom }}" | ||
| 16 | + root-portal="{{ rootPortal }}" | ||
| 15 | bind:enter="onOpen" | 17 | bind:enter="onOpen" |
| 16 | bind:close="onClose" | 18 | bind:close="onClose" |
| 17 | bind:after-enter="onOpened" | 19 | bind:after-enter="onOpened" | ... | ... |
| ... | @@ -15,7 +15,7 @@ function getMonths(minDate, maxDate) { | ... | @@ -15,7 +15,7 @@ function getMonths(minDate, maxDate) { |
| 15 | return months; | 15 | return months; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | -function getButtonDisabled(type, currentDate) { | 18 | +function getButtonDisabled(type, currentDate, minRange) { |
| 19 | if (currentDate == null) { | 19 | if (currentDate == null) { |
| 20 | return true; | 20 | return true; |
| 21 | } | 21 | } |
| ... | @@ -25,7 +25,7 @@ function getButtonDisabled(type, currentDate) { | ... | @@ -25,7 +25,7 @@ function getButtonDisabled(type, currentDate) { |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | if (type === 'multiple') { | 27 | if (type === 'multiple') { |
| 28 | - return !currentDate.length; | 28 | + return currentDate.length < minRange; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | return !currentDate; | 31 | return !currentDate; | ... | ... |
| 1 | -@import '../common/index.wxss';.van-calendar{background-color:var(--calendar-background-color,#fff);display:flex;flex-direction:column;height:var(--calendar-height,100%)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:var(--calendar-popup-height,80%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{-webkit-overflow-scrolling:touch;flex:1;overflow:auto}.van-calendar__footer{flex-shrink:0;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:var(--calendar-confirm-button-height,36px)!important;line-height:var(--calendar-confirm-button-line-height,34px)!important;margin:var(--calendar-confirm-button-margin,7px 0)!important} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-calendar{background-color:var(--calendar-background-color,#fff);display:flex;flex-direction:column;height:var(--calendar-height,100%)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:var(--calendar-popup-height,90%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{-webkit-overflow-scrolling:touch;flex:1;overflow:auto}.van-calendar__footer{flex-shrink:0;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:var(--calendar-confirm-button-height,36px)!important;line-height:var(--calendar-confirm-button-line-height,34px)!important;margin:var(--calendar-confirm-button-margin,7px 0)!important} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | export declare const ROW_HEIGHT = 64; | 1 | export declare const ROW_HEIGHT = 64; |
| 2 | export declare function formatMonthTitle(date: Date): string; | 2 | export declare function formatMonthTitle(date: Date): string; |
| 3 | -export declare function compareMonth(date1: Date | number, date2: Date | number): 1 | -1 | 0; | 3 | +export declare function compareMonth(date1: Date | number, date2: Date | number): 0 | 1 | -1; |
| 4 | -export declare function compareDay(day1: Date | number, day2: Date | number): 1 | -1 | 0; | 4 | +export declare function compareDay(day1: Date | number, day2: Date | number): 0 | 1 | -1; |
| 5 | export declare function getDayByOffset(date: Date, offset: number): Date; | 5 | export declare function getDayByOffset(date: Date, offset: number): Date; |
| 6 | export declare function getPrevDay(date: Date): Date; | 6 | export declare function getPrevDay(date: Date): Date; |
| 7 | export declare function getNextDay(date: Date): Date; | 7 | export declare function getNextDay(date: Date): Date; | ... | ... |
| 1 | +export {}; |
src/components/vant-weapp/cascader/index.js
0 → 100644
| 1 | +import { VantComponent } from '../common/component'; | ||
| 2 | +var FieldName; | ||
| 3 | +(function (FieldName) { | ||
| 4 | + FieldName["TEXT"] = "text"; | ||
| 5 | + FieldName["VALUE"] = "value"; | ||
| 6 | + FieldName["CHILDREN"] = "children"; | ||
| 7 | +})(FieldName || (FieldName = {})); | ||
| 8 | +const defaultFieldNames = { | ||
| 9 | + text: FieldName.TEXT, | ||
| 10 | + value: FieldName.VALUE, | ||
| 11 | + children: FieldName.CHILDREN, | ||
| 12 | +}; | ||
| 13 | +VantComponent({ | ||
| 14 | + props: { | ||
| 15 | + title: String, | ||
| 16 | + value: { | ||
| 17 | + type: String, | ||
| 18 | + }, | ||
| 19 | + placeholder: { | ||
| 20 | + type: String, | ||
| 21 | + value: '请选择', | ||
| 22 | + }, | ||
| 23 | + activeColor: { | ||
| 24 | + type: String, | ||
| 25 | + value: '#1989fa', | ||
| 26 | + }, | ||
| 27 | + options: { | ||
| 28 | + type: Array, | ||
| 29 | + value: [], | ||
| 30 | + }, | ||
| 31 | + swipeable: { | ||
| 32 | + type: Boolean, | ||
| 33 | + value: false, | ||
| 34 | + }, | ||
| 35 | + closeable: { | ||
| 36 | + type: Boolean, | ||
| 37 | + value: true, | ||
| 38 | + }, | ||
| 39 | + ellipsis: { | ||
| 40 | + type: Boolean, | ||
| 41 | + value: true, | ||
| 42 | + }, | ||
| 43 | + showHeader: { | ||
| 44 | + type: Boolean, | ||
| 45 | + value: true, | ||
| 46 | + }, | ||
| 47 | + closeIcon: { | ||
| 48 | + type: String, | ||
| 49 | + value: 'cross', | ||
| 50 | + }, | ||
| 51 | + fieldNames: { | ||
| 52 | + type: Object, | ||
| 53 | + value: defaultFieldNames, | ||
| 54 | + observer: 'updateFieldNames', | ||
| 55 | + }, | ||
| 56 | + useTitleSlot: Boolean, | ||
| 57 | + }, | ||
| 58 | + data: { | ||
| 59 | + tabs: [], | ||
| 60 | + activeTab: 0, | ||
| 61 | + textKey: FieldName.TEXT, | ||
| 62 | + valueKey: FieldName.VALUE, | ||
| 63 | + childrenKey: FieldName.CHILDREN, | ||
| 64 | + innerValue: '', | ||
| 65 | + }, | ||
| 66 | + watch: { | ||
| 67 | + options() { | ||
| 68 | + this.updateTabs(); | ||
| 69 | + }, | ||
| 70 | + value(newVal) { | ||
| 71 | + this.updateValue(newVal); | ||
| 72 | + }, | ||
| 73 | + }, | ||
| 74 | + created() { | ||
| 75 | + this.updateTabs(); | ||
| 76 | + }, | ||
| 77 | + methods: { | ||
| 78 | + updateValue(val) { | ||
| 79 | + if (val !== undefined) { | ||
| 80 | + const values = this.data.tabs.map((tab) => tab.selected && tab.selected[this.data.valueKey]); | ||
| 81 | + if (values.indexOf(val) > -1) { | ||
| 82 | + return; | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + this.innerValue = val; | ||
| 86 | + this.updateTabs(); | ||
| 87 | + }, | ||
| 88 | + updateFieldNames() { | ||
| 89 | + const { text = 'text', value = 'value', children = 'children', } = this.data.fieldNames || defaultFieldNames; | ||
| 90 | + this.setData({ | ||
| 91 | + textKey: text, | ||
| 92 | + valueKey: value, | ||
| 93 | + childrenKey: children, | ||
| 94 | + }); | ||
| 95 | + }, | ||
| 96 | + getSelectedOptionsByValue(options, value) { | ||
| 97 | + for (let i = 0; i < options.length; i++) { | ||
| 98 | + const option = options[i]; | ||
| 99 | + if (option[this.data.valueKey] === value) { | ||
| 100 | + return [option]; | ||
| 101 | + } | ||
| 102 | + if (option[this.data.childrenKey]) { | ||
| 103 | + const selectedOptions = this.getSelectedOptionsByValue(option[this.data.childrenKey], value); | ||
| 104 | + if (selectedOptions) { | ||
| 105 | + return [option, ...selectedOptions]; | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + } | ||
| 109 | + }, | ||
| 110 | + updateTabs() { | ||
| 111 | + const { options } = this.data; | ||
| 112 | + const { innerValue } = this; | ||
| 113 | + if (!options.length) { | ||
| 114 | + return; | ||
| 115 | + } | ||
| 116 | + if (innerValue !== undefined) { | ||
| 117 | + const selectedOptions = this.getSelectedOptionsByValue(options, innerValue); | ||
| 118 | + if (selectedOptions) { | ||
| 119 | + let optionsCursor = options; | ||
| 120 | + const tabs = selectedOptions.map((option) => { | ||
| 121 | + const tab = { | ||
| 122 | + options: optionsCursor, | ||
| 123 | + selected: option, | ||
| 124 | + }; | ||
| 125 | + const next = optionsCursor.find((item) => item[this.data.valueKey] === option[this.data.valueKey]); | ||
| 126 | + if (next) { | ||
| 127 | + optionsCursor = next[this.data.childrenKey]; | ||
| 128 | + } | ||
| 129 | + return tab; | ||
| 130 | + }); | ||
| 131 | + if (optionsCursor) { | ||
| 132 | + tabs.push({ | ||
| 133 | + options: optionsCursor, | ||
| 134 | + selected: null, | ||
| 135 | + }); | ||
| 136 | + } | ||
| 137 | + this.setData({ | ||
| 138 | + tabs, | ||
| 139 | + }); | ||
| 140 | + wx.nextTick(() => { | ||
| 141 | + this.setData({ | ||
| 142 | + activeTab: tabs.length - 1, | ||
| 143 | + }); | ||
| 144 | + }); | ||
| 145 | + return; | ||
| 146 | + } | ||
| 147 | + } | ||
| 148 | + this.setData({ | ||
| 149 | + tabs: [ | ||
| 150 | + { | ||
| 151 | + options, | ||
| 152 | + selected: null, | ||
| 153 | + }, | ||
| 154 | + ], | ||
| 155 | + activeTab: 0, | ||
| 156 | + }); | ||
| 157 | + }, | ||
| 158 | + onClose() { | ||
| 159 | + this.$emit('close'); | ||
| 160 | + }, | ||
| 161 | + onClickTab(e) { | ||
| 162 | + const { index: tabIndex, title } = e.detail; | ||
| 163 | + this.$emit('click-tab', { title, tabIndex }); | ||
| 164 | + this.setData({ | ||
| 165 | + activeTab: tabIndex, | ||
| 166 | + }); | ||
| 167 | + }, | ||
| 168 | + // 选中 | ||
| 169 | + onSelect(e) { | ||
| 170 | + const { option, tabIndex } = e.currentTarget.dataset; | ||
| 171 | + if (option && option.disabled) { | ||
| 172 | + return; | ||
| 173 | + } | ||
| 174 | + const { valueKey, childrenKey } = this.data; | ||
| 175 | + let { tabs } = this.data; | ||
| 176 | + tabs[tabIndex].selected = option; | ||
| 177 | + if (tabs.length > tabIndex + 1) { | ||
| 178 | + tabs = tabs.slice(0, tabIndex + 1); | ||
| 179 | + } | ||
| 180 | + if (option[childrenKey]) { | ||
| 181 | + const nextTab = { | ||
| 182 | + options: option[childrenKey], | ||
| 183 | + selected: null, | ||
| 184 | + }; | ||
| 185 | + if (tabs[tabIndex + 1]) { | ||
| 186 | + tabs[tabIndex + 1] = nextTab; | ||
| 187 | + } | ||
| 188 | + else { | ||
| 189 | + tabs.push(nextTab); | ||
| 190 | + } | ||
| 191 | + wx.nextTick(() => { | ||
| 192 | + this.setData({ | ||
| 193 | + activeTab: tabIndex + 1, | ||
| 194 | + }); | ||
| 195 | + }); | ||
| 196 | + } | ||
| 197 | + this.setData({ | ||
| 198 | + tabs, | ||
| 199 | + }); | ||
| 200 | + const selectedOptions = tabs.map((tab) => tab.selected).filter(Boolean); | ||
| 201 | + const value = option[valueKey]; | ||
| 202 | + const params = { | ||
| 203 | + value, | ||
| 204 | + tabIndex, | ||
| 205 | + selectedOptions, | ||
| 206 | + }; | ||
| 207 | + this.innerValue = value; | ||
| 208 | + this.$emit('change', params); | ||
| 209 | + if (!option[childrenKey]) { | ||
| 210 | + this.$emit('finish', params); | ||
| 211 | + } | ||
| 212 | + }, | ||
| 213 | + }, | ||
| 214 | +}); |
| 1 | +<wxs src="./index.wxs" module="utils" /> | ||
| 2 | + | ||
| 3 | +<view wx:if="{{ showHeader }}" class="van-cascader__header"> | ||
| 4 | + <slot name="title" wx:if="{{ useTitleSlot }}"></slot> | ||
| 5 | + <text class="van-cascader__title" wx:else>{{ title }}</text> | ||
| 6 | + <van-icon | ||
| 7 | + wx:if="{{ closeable }}" | ||
| 8 | + name="{{ closeIcon }}" | ||
| 9 | + class="van-cascader__close-icon" | ||
| 10 | + bind:tap="onClose" | ||
| 11 | + /> | ||
| 12 | +</view> | ||
| 13 | + | ||
| 14 | +<van-tabs | ||
| 15 | + active="{{ activeTab }}" | ||
| 16 | + custom-class="van-cascader__tabs" | ||
| 17 | + wrap-class="van-cascader__tabs-wrap" | ||
| 18 | + tab-class="van-cascader__tab" | ||
| 19 | + color="{{ activeColor }}" | ||
| 20 | + border="{{ false }}" | ||
| 21 | + swipeable="{{ swipeable }}" | ||
| 22 | + ellipsis="{{ ellipsis }}" | ||
| 23 | + bind:click="onClickTab" | ||
| 24 | +> | ||
| 25 | + <van-tab | ||
| 26 | + wx:for="{{ tabs }}" | ||
| 27 | + wx:for-item="tab" | ||
| 28 | + wx:for-index="tabIndex" | ||
| 29 | + wx:key="tabIndex" | ||
| 30 | + title="{{ tab.selected ? tab.selected[textKey] : placeholder }}" | ||
| 31 | + style="width: 100%;" | ||
| 32 | + title-style="{{ !tab.selected ? 'color: #969799;font-weight:normal;' : '' }}" | ||
| 33 | + > | ||
| 34 | + <!-- 暂不支持 --> | ||
| 35 | + <!-- <slot name="options-top"></slot> --> | ||
| 36 | + | ||
| 37 | + <view class="van-cascader__options"> | ||
| 38 | + <view | ||
| 39 | + wx:for="{{ tab.options }}" | ||
| 40 | + wx:for-item="option" | ||
| 41 | + wx:key="index" | ||
| 42 | + class="{{ option.className }} {{ utils.optionClass(tab, valueKey, option) }}" | ||
| 43 | + style="{{ utils.optionStyle({ tab, valueKey, option, activeColor }) }}" | ||
| 44 | + data-option="{{ option }}" | ||
| 45 | + data-tab-index="{{ tabIndex }}" | ||
| 46 | + bind:tap="onSelect" | ||
| 47 | + > | ||
| 48 | + <text>{{ option[textKey] }}</text> | ||
| 49 | + <van-icon wx:if="{{ utils.isSelected(tab, valueKey, option) }}" name="success" size="18" /> | ||
| 50 | + </view> | ||
| 51 | + </view> | ||
| 52 | + <!-- 暂不支持 --> | ||
| 53 | + <!-- <slot name="options-bottom"></slot> --> | ||
| 54 | + </van-tab> | ||
| 55 | +</van-tabs> |
src/components/vant-weapp/cascader/index.wxs
0 → 100644
| 1 | +var utils = require('../wxs/utils.wxs'); | ||
| 2 | +var style = require('../wxs/style.wxs'); | ||
| 3 | + | ||
| 4 | +function isSelected(tab, valueKey, option) { | ||
| 5 | + return tab.selected && tab.selected[valueKey] === option[valueKey] | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +function optionClass(tab, valueKey, option) { | ||
| 9 | + return utils.bem('cascader__option', { selected: isSelected(tab, valueKey, option), disabled: option.disabled }) | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +function optionStyle(data) { | ||
| 13 | + var color = data.option.color || (isSelected(data.tab, data.valueKey, data.option) ? data.activeColor : undefined); | ||
| 14 | + return style({ | ||
| 15 | + color | ||
| 16 | + }); | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +module.exports = { | ||
| 21 | + isSelected: isSelected, | ||
| 22 | + optionClass: optionClass, | ||
| 23 | + optionStyle: optionStyle, | ||
| 24 | +}; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-cascader__header{align-items:center;display:flex;height:48px;justify-content:space-between;padding:0 16px}.van-cascader__title{font-size:16px;font-weight:600;line-height:20px}.van-cascader__close-icon{color:#c8c9cc;font-size:22px;height:22px}.van-cascader__tabs-wrap{height:48px!important;padding:0 8px}.van-cascader__tab{color:#323233!important;flex:none!important;font-weight:600!important;padding:0 8px!important}.van-cascader__tab--unselected{color:#969799!important;font-weight:400!important}.van-cascader__option{align-items:center;cursor:pointer;display:flex;font-size:14px;justify-content:space-between;line-height:20px;padding:10px 16px}.van-cascader__option:active{background-color:#f2f3f5}.van-cascader__option--selected{color:#1989fa;font-weight:600}.van-cascader__option--disabled{color:#c8c9cc;cursor:not-allowed}.van-cascader__option--disabled:active{background-color:initial}.van-cascader__options{-webkit-overflow-scrolling:touch;box-sizing:border-box;height:384px;overflow-y:auto;padding-top:6px} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /// <reference types="miniprogram-api-typings" /> | 1 | /// <reference types="miniprogram-api-typings" /> |
| 2 | -declare type CanvasContext = WechatMiniprogram.CanvasContext; | 2 | +type CanvasContext = WechatMiniprogram.CanvasContext; |
| 3 | export declare function adaptor(ctx: CanvasContext & Record<string, unknown>): CanvasContext; | 3 | export declare function adaptor(ctx: CanvasContext & Record<string, unknown>): CanvasContext; |
| 4 | export {}; | 4 | export {}; | ... | ... |
| ... | @@ -93,6 +93,8 @@ VantComponent({ | ... | @@ -93,6 +93,8 @@ VantComponent({ |
| 93 | const { color, size } = this.data; | 93 | const { color, size } = this.data; |
| 94 | if (isObj(color)) { | 94 | if (isObj(color)) { |
| 95 | return this.getContext().then((context) => { | 95 | return this.getContext().then((context) => { |
| 96 | + if (!context) | ||
| 97 | + return; | ||
| 96 | const LinearColor = context.createLinearGradient(size, 0, 0, 0); | 98 | const LinearColor = context.createLinearGradient(size, 0, 0, 0); |
| 97 | Object.keys(color) | 99 | Object.keys(color) |
| 98 | .sort((a, b) => parseFloat(a) - parseFloat(b)) | 100 | .sort((a, b) => parseFloat(a) - parseFloat(b)) |
| ... | @@ -134,6 +136,8 @@ VantComponent({ | ... | @@ -134,6 +136,8 @@ VantComponent({ |
| 134 | drawCircle(currentValue) { | 136 | drawCircle(currentValue) { |
| 135 | const { size } = this.data; | 137 | const { size } = this.data; |
| 136 | this.getContext().then((context) => { | 138 | this.getContext().then((context) => { |
| 139 | + if (!context) | ||
| 140 | + return; | ||
| 137 | context.clearRect(0, 0, size, size); | 141 | context.clearRect(0, 0, size, size); |
| 138 | this.renderLayerCircle(context); | 142 | this.renderLayerCircle(context); |
| 139 | const formatValue = format(currentValue); | 143 | const formatValue = format(currentValue); | ... | ... |
| ... | @@ -24,6 +24,7 @@ VantComponent({ | ... | @@ -24,6 +24,7 @@ VantComponent({ |
| 24 | }, | 24 | }, |
| 25 | data: { | 25 | data: { |
| 26 | expanded: false, | 26 | expanded: false, |
| 27 | + parentBorder: true, | ||
| 27 | }, | 28 | }, |
| 28 | mounted() { | 29 | mounted() { |
| 29 | this.updateExpanded(); | 30 | this.updateExpanded(); |
| ... | @@ -34,7 +35,7 @@ VantComponent({ | ... | @@ -34,7 +35,7 @@ VantComponent({ |
| 34 | if (!this.parent) { | 35 | if (!this.parent) { |
| 35 | return; | 36 | return; |
| 36 | } | 37 | } |
| 37 | - const { value, accordion } = this.parent.data; | 38 | + const { value, accordion, border } = this.parent.data; |
| 38 | const { children = [] } = this.parent; | 39 | const { children = [] } = this.parent; |
| 39 | const { name } = this.data; | 40 | const { name } = this.data; |
| 40 | const index = children.indexOf(this); | 41 | const index = children.indexOf(this); |
| ... | @@ -45,7 +46,7 @@ VantComponent({ | ... | @@ -45,7 +46,7 @@ VantComponent({ |
| 45 | if (expanded !== this.data.expanded) { | 46 | if (expanded !== this.data.expanded) { |
| 46 | setContentAnimate(this, expanded, this.mounted); | 47 | setContentAnimate(this, expanded, this.mounted); |
| 47 | } | 48 | } |
| 48 | - this.setData({ index, expanded }); | 49 | + this.setData({ index, expanded, parentBorder: border }); |
| 49 | }, | 50 | }, |
| 50 | onClick() { | 51 | onClick() { |
| 51 | if (this.data.disabled) { | 52 | if (this.data.disabled) { | ... | ... |
| 1 | <wxs src="../wxs/utils.wxs" module="utils" /> | 1 | <wxs src="../wxs/utils.wxs" module="utils" /> |
| 2 | 2 | ||
| 3 | -<view class="van-collapse-item custom-class {{ index !== 0 ? 'van-hairline--top' : '' }}"> | 3 | +<view class="van-collapse-item custom-class {{ index !== 0 && parentBorder ? 'van-hairline--top' : '' }}"> |
| 4 | <van-cell | 4 | <van-cell |
| 5 | size="{{ size }}" | 5 | size="{{ size }}" |
| 6 | title="{{ title }}" | 6 | title="{{ title }}" | ... | ... |
| ... | @@ -11,6 +11,7 @@ function VantComponent(vantOptions) { | ... | @@ -11,6 +11,7 @@ function VantComponent(vantOptions) { |
| 11 | mapKeys(vantOptions, options, { | 11 | mapKeys(vantOptions, options, { |
| 12 | data: 'data', | 12 | data: 'data', |
| 13 | props: 'properties', | 13 | props: 'properties', |
| 14 | + watch: 'observers', | ||
| 14 | mixins: 'behaviors', | 15 | mixins: 'behaviors', |
| 15 | methods: 'methods', | 16 | methods: 'methods', |
| 16 | beforeCreate: 'created', | 17 | beforeCreate: 'created', | ... | ... |
| 1 | /// <reference types="miniprogram-api-typings" /> | 1 | /// <reference types="miniprogram-api-typings" /> |
| 2 | -declare type TrivialInstance = WechatMiniprogram.Component.TrivialInstance; | 2 | +type TrivialInstance = WechatMiniprogram.Component.TrivialInstance; |
| 3 | export declare function useParent(name: string, onEffect?: (this: TrivialInstance) => void): { | 3 | export declare function useParent(name: string, onEffect?: (this: TrivialInstance) => void): { |
| 4 | relations: { | 4 | relations: { |
| 5 | [x: string]: WechatMiniprogram.Component.RelationOption; | 5 | [x: string]: WechatMiniprogram.Component.RelationOption; | ... | ... |
| 1 | -/// <reference types="miniprogram-api-typings" /> | ||
| 2 | /// <reference types="node" /> | 1 | /// <reference types="node" /> |
| 2 | +/// <reference types="miniprogram-api-typings" /> | ||
| 3 | +/// <reference types="miniprogram-api-typings" /> | ||
| 4 | +/// <reference types="miniprogram-api-typings" /> | ||
| 5 | +/// <reference types="miniprogram-api-typings" /> | ||
| 3 | export { isDef } from './validator'; | 6 | export { isDef } from './validator'; |
| 7 | +export { getSystemInfoSync } from './version'; | ||
| 4 | export declare function range(num: number, min: number, max: number): number; | 8 | export declare function range(num: number, min: number, max: number): number; |
| 5 | export declare function nextTick(cb: (...args: any[]) => void): void; | 9 | export declare function nextTick(cb: (...args: any[]) => void): void; |
| 6 | -export declare function getSystemInfoSync(): WechatMiniprogram.SystemInfo; | ||
| 7 | export declare function addUnit(value?: string | number): string | undefined; | 10 | export declare function addUnit(value?: string | number): string | undefined; |
| 8 | -export declare function requestAnimationFrame(cb: () => void): NodeJS.Timeout | WechatMiniprogram.NodesRef; | 11 | +export declare function requestAnimationFrame(cb: () => void): NodeJS.Timeout; |
| 9 | export declare function pickExclude(obj: unknown, keys: string[]): {}; | 12 | export declare function pickExclude(obj: unknown, keys: string[]): {}; |
| 10 | export declare function getRect(context: WechatMiniprogram.Component.TrivialInstance, selector: string): Promise<WechatMiniprogram.BoundingClientRectCallbackResult>; | 13 | export declare function getRect(context: WechatMiniprogram.Component.TrivialInstance, selector: string): Promise<WechatMiniprogram.BoundingClientRectCallbackResult>; |
| 11 | export declare function getAllRect(context: WechatMiniprogram.Component.TrivialInstance, selector: string): Promise<WechatMiniprogram.BoundingClientRectCallbackResult[]>; | 14 | export declare function getAllRect(context: WechatMiniprogram.Component.TrivialInstance, selector: string): Promise<WechatMiniprogram.BoundingClientRectCallbackResult[]>; |
| 12 | export declare function groupSetData(context: WechatMiniprogram.Component.TrivialInstance, cb: () => void): void; | 15 | export declare function groupSetData(context: WechatMiniprogram.Component.TrivialInstance, cb: () => void): void; |
| 13 | export declare function toPromise(promiseLike: Promise<unknown> | unknown): Promise<unknown>; | 16 | export declare function toPromise(promiseLike: Promise<unknown> | unknown): Promise<unknown>; |
| 17 | +export declare function addNumber(num1: any, num2: any): number; | ||
| 18 | +export declare const clamp: (num: any, min: any, max: any) => number; | ||
| 14 | export declare function getCurrentPage<T>(): T & WechatMiniprogram.OptionalInterface<WechatMiniprogram.Page.ILifetime> & WechatMiniprogram.Page.InstanceProperties & WechatMiniprogram.Page.InstanceMethods<WechatMiniprogram.IAnyObject> & WechatMiniprogram.Page.Data<WechatMiniprogram.IAnyObject> & WechatMiniprogram.IAnyObject; | 19 | export declare function getCurrentPage<T>(): T & WechatMiniprogram.OptionalInterface<WechatMiniprogram.Page.ILifetime> & WechatMiniprogram.Page.InstanceProperties & WechatMiniprogram.Page.InstanceMethods<WechatMiniprogram.IAnyObject> & WechatMiniprogram.Page.Data<WechatMiniprogram.IAnyObject> & WechatMiniprogram.IAnyObject; |
| 20 | +export declare const isPC: boolean; | ||
| 21 | +export declare const isWxWork: boolean; | ... | ... |
| 1 | import { isDef, isNumber, isPlainObject, isPromise } from './validator'; | 1 | import { isDef, isNumber, isPlainObject, isPromise } from './validator'; |
| 2 | -import { canIUseGroupSetData, canIUseNextTick } from './version'; | 2 | +import { canIUseGroupSetData, canIUseNextTick, getSystemInfoSync, } from './version'; |
| 3 | export { isDef } from './validator'; | 3 | export { isDef } from './validator'; |
| 4 | +export { getSystemInfoSync } from './version'; | ||
| 4 | export function range(num, min, max) { | 5 | export function range(num, min, max) { |
| 5 | return Math.min(Math.max(num, min), max); | 6 | return Math.min(Math.max(num, min), max); |
| 6 | } | 7 | } |
| ... | @@ -14,13 +15,6 @@ export function nextTick(cb) { | ... | @@ -14,13 +15,6 @@ export function nextTick(cb) { |
| 14 | }, 1000 / 30); | 15 | }, 1000 / 30); |
| 15 | } | 16 | } |
| 16 | } | 17 | } |
| 17 | -let systemInfo; | ||
| 18 | -export function getSystemInfoSync() { | ||
| 19 | - if (systemInfo == null) { | ||
| 20 | - systemInfo = wx.getSystemInfoSync(); | ||
| 21 | - } | ||
| 22 | - return systemInfo; | ||
| 23 | -} | ||
| 24 | export function addUnit(value) { | 18 | export function addUnit(value) { |
| 25 | if (!isDef(value)) { | 19 | if (!isDef(value)) { |
| 26 | return undefined; | 20 | return undefined; |
| ... | @@ -29,19 +23,9 @@ export function addUnit(value) { | ... | @@ -29,19 +23,9 @@ export function addUnit(value) { |
| 29 | return isNumber(value) ? `${value}px` : value; | 23 | return isNumber(value) ? `${value}px` : value; |
| 30 | } | 24 | } |
| 31 | export function requestAnimationFrame(cb) { | 25 | export function requestAnimationFrame(cb) { |
| 32 | - const systemInfo = getSystemInfoSync(); | ||
| 33 | - if (systemInfo.platform === 'devtools') { | ||
| 34 | return setTimeout(() => { | 26 | return setTimeout(() => { |
| 35 | cb(); | 27 | cb(); |
| 36 | }, 1000 / 30); | 28 | }, 1000 / 30); |
| 37 | - } | ||
| 38 | - return wx | ||
| 39 | - .createSelectorQuery() | ||
| 40 | - .selectViewport() | ||
| 41 | - .boundingClientRect() | ||
| 42 | - .exec(() => { | ||
| 43 | - cb(); | ||
| 44 | - }); | ||
| 45 | } | 29 | } |
| 46 | export function pickExclude(obj, keys) { | 30 | export function pickExclude(obj, keys) { |
| 47 | if (!isPlainObject(obj)) { | 31 | if (!isPlainObject(obj)) { |
| ... | @@ -86,7 +70,17 @@ export function toPromise(promiseLike) { | ... | @@ -86,7 +70,17 @@ export function toPromise(promiseLike) { |
| 86 | } | 70 | } |
| 87 | return Promise.resolve(promiseLike); | 71 | return Promise.resolve(promiseLike); |
| 88 | } | 72 | } |
| 73 | +// 浮点数精度处理 | ||
| 74 | +export function addNumber(num1, num2) { | ||
| 75 | + const cardinal = Math.pow(10, 10); | ||
| 76 | + return Math.round((num1 + num2) * cardinal) / cardinal; | ||
| 77 | +} | ||
| 78 | +// 限制value在[min, max]之间 | ||
| 79 | +export const clamp = (num, min, max) => Math.min(Math.max(num, min), max); | ||
| 89 | export function getCurrentPage() { | 80 | export function getCurrentPage() { |
| 90 | const pages = getCurrentPages(); | 81 | const pages = getCurrentPages(); |
| 91 | return pages[pages.length - 1]; | 82 | return pages[pages.length - 1]; |
| 92 | } | 83 | } |
| 84 | +export const isPC = ['mac', 'windows'].includes(getSystemInfoSync().platform); | ||
| 85 | +// 是否企业微信 | ||
| 86 | +export const isWxWork = getSystemInfoSync().environment === 'wxwork'; | ... | ... |
| 1 | +/// <reference types="miniprogram-api-typings" /> | ||
| 2 | +interface WxWorkSystemInfo extends WechatMiniprogram.SystemInfo { | ||
| 3 | + environment?: 'wxwork'; | ||
| 4 | +} | ||
| 5 | +interface SystemInfo extends WxWorkSystemInfo, WechatMiniprogram.SystemInfo { | ||
| 6 | +} | ||
| 7 | +export declare function getSystemInfoSync(): SystemInfo; | ||
| 1 | export declare function canIUseModel(): boolean; | 8 | export declare function canIUseModel(): boolean; |
| 2 | export declare function canIUseFormFieldButton(): boolean; | 9 | export declare function canIUseFormFieldButton(): boolean; |
| 3 | export declare function canIUseAnimate(): boolean; | 10 | export declare function canIUseAnimate(): boolean; |
| ... | @@ -5,3 +12,4 @@ export declare function canIUseGroupSetData(): boolean; | ... | @@ -5,3 +12,4 @@ export declare function canIUseGroupSetData(): boolean; |
| 5 | export declare function canIUseNextTick(): boolean; | 12 | export declare function canIUseNextTick(): boolean; |
| 6 | export declare function canIUseCanvas2d(): boolean; | 13 | export declare function canIUseCanvas2d(): boolean; |
| 7 | export declare function canIUseGetUserProfile(): boolean; | 14 | export declare function canIUseGetUserProfile(): boolean; |
| 15 | +export {}; | ... | ... |
| 1 | -import { getSystemInfoSync } from './utils'; | 1 | +let systemInfo; |
| 2 | +export function getSystemInfoSync() { | ||
| 3 | + if (systemInfo == null) { | ||
| 4 | + systemInfo = wx.getSystemInfoSync(); | ||
| 5 | + } | ||
| 6 | + return systemInfo; | ||
| 7 | +} | ||
| 2 | function compareVersion(v1, v2) { | 8 | function compareVersion(v1, v2) { |
| 3 | v1 = v1.split('.'); | 9 | v1 = v1.split('.'); |
| 4 | v2 = v2.split('.'); | 10 | v2 = v2.split('.'); |
| ... | @@ -38,7 +44,12 @@ export function canIUseGroupSetData() { | ... | @@ -38,7 +44,12 @@ export function canIUseGroupSetData() { |
| 38 | return gte('2.4.0'); | 44 | return gte('2.4.0'); |
| 39 | } | 45 | } |
| 40 | export function canIUseNextTick() { | 46 | export function canIUseNextTick() { |
| 47 | + try { | ||
| 41 | return wx.canIUse('nextTick'); | 48 | return wx.canIUse('nextTick'); |
| 49 | + } | ||
| 50 | + catch (e) { | ||
| 51 | + return gte('2.7.1'); | ||
| 52 | + } | ||
| 42 | } | 53 | } |
| 43 | export function canIUseCanvas2d() { | 54 | export function canIUseCanvas2d() { |
| 44 | return gte('2.9.0'); | 55 | return gte('2.9.0'); | ... | ... |
| ... | @@ -97,30 +97,7 @@ VantComponent({ | ... | @@ -97,30 +97,7 @@ VantComponent({ |
| 97 | return this.picker; | 97 | return this.picker; |
| 98 | }, | 98 | }, |
| 99 | updateColumns() { | 99 | updateColumns() { |
| 100 | - // const { formatter = defaultFormatter } = this.data; | 100 | + const { formatter = defaultFormatter } = this.data; |
| 101 | - let { formatter } = this.data; | ||
| 102 | - if (defaultFormatter) { | ||
| 103 | - formatter = defaultFormatter; | ||
| 104 | - } | ||
| 105 | - // 默认写死配置 | ||
| 106 | - formatter = (type, value) => { | ||
| 107 | - if (type === 'year') { | ||
| 108 | - return `${value}年`; | ||
| 109 | - } | ||
| 110 | - if (type === 'month') { | ||
| 111 | - return `${value}月`; | ||
| 112 | - } | ||
| 113 | - if (type === 'day') { | ||
| 114 | - return `${value}日`; | ||
| 115 | - } | ||
| 116 | - if (type === 'hour') { | ||
| 117 | - return `${value}时`; | ||
| 118 | - } | ||
| 119 | - if (type === 'minute') { | ||
| 120 | - return `${value}分`; | ||
| 121 | - } | ||
| 122 | - return value; | ||
| 123 | - } | ||
| 124 | const results = this.getOriginColumns().map((column) => ({ | 101 | const results = this.getOriginColumns().map((column) => ({ |
| 125 | values: column.values.map((value) => formatter(column.type, value)), | 102 | values: column.values.map((value) => formatter(column.type, value)), |
| 126 | })); | 103 | })); |
| ... | @@ -285,26 +262,7 @@ VantComponent({ | ... | @@ -285,26 +262,7 @@ VantComponent({ |
| 285 | updateColumnValue(value) { | 262 | updateColumnValue(value) { |
| 286 | let values = []; | 263 | let values = []; |
| 287 | const { type } = this.data; | 264 | const { type } = this.data; |
| 288 | - let formatter = this.data.formatter || defaultFormatter; | 265 | + const formatter = this.data.formatter || defaultFormatter; |
| 289 | - // 默认写死配置 | ||
| 290 | - formatter = (type, value) => { | ||
| 291 | - if (type === 'year') { | ||
| 292 | - return `${value}年`; | ||
| 293 | - } | ||
| 294 | - if (type === 'month') { | ||
| 295 | - return `${value}月`; | ||
| 296 | - } | ||
| 297 | - if (type === 'day') { | ||
| 298 | - return `${value}日`; | ||
| 299 | - } | ||
| 300 | - if (type === 'hour') { | ||
| 301 | - return `${value}时`; | ||
| 302 | - } | ||
| 303 | - if (type === 'minute') { | ||
| 304 | - return `${value}分`; | ||
| 305 | - } | ||
| 306 | - return value; | ||
| 307 | - } | ||
| 308 | const picker = this.getPicker(); | 266 | const picker = this.getPicker(); |
| 309 | if (type === 'time') { | 267 | if (type === 'time') { |
| 310 | const pair = value.split(':'); | 268 | const pair = value.split(':'); | ... | ... |
| ... | @@ -4,8 +4,9 @@ interface VantComponentInstance { | ... | @@ -4,8 +4,9 @@ interface VantComponentInstance { |
| 4 | children: WechatMiniprogram.Component.TrivialInstance[]; | 4 | children: WechatMiniprogram.Component.TrivialInstance[]; |
| 5 | index: number; | 5 | index: number; |
| 6 | $emit: (name: string, detail?: unknown, options?: WechatMiniprogram.Component.TriggerEventOption) => void; | 6 | $emit: (name: string, detail?: unknown, options?: WechatMiniprogram.Component.TriggerEventOption) => void; |
| 7 | + setView: (value: Record<string, any>, callback?: () => void) => void; | ||
| 7 | } | 8 | } |
| 8 | -export declare type VantComponentOptions<Data extends WechatMiniprogram.Component.DataOption, Props extends WechatMiniprogram.Component.PropertyOption, Methods extends WechatMiniprogram.Component.MethodOption> = { | 9 | +export type VantComponentOptions<Data extends WechatMiniprogram.Component.DataOption, Props extends WechatMiniprogram.Component.PropertyOption, Methods extends WechatMiniprogram.Component.MethodOption> = { |
| 9 | data?: Data; | 10 | data?: Data; |
| 10 | field?: boolean; | 11 | field?: boolean; |
| 11 | classes?: string[]; | 12 | classes?: string[]; |
| ... | @@ -15,6 +16,7 @@ export declare type VantComponentOptions<Data extends WechatMiniprogram.Componen | ... | @@ -15,6 +16,7 @@ export declare type VantComponentOptions<Data extends WechatMiniprogram.Componen |
| 15 | relations: Record<string, WechatMiniprogram.Component.RelationOption>; | 16 | relations: Record<string, WechatMiniprogram.Component.RelationOption>; |
| 16 | mixin: string; | 17 | mixin: string; |
| 17 | }; | 18 | }; |
| 19 | + watch?: Record<string, (...args: any[]) => any>; | ||
| 18 | methods?: Methods; | 20 | methods?: Methods; |
| 19 | beforeCreate?: () => void; | 21 | beforeCreate?: () => void; |
| 20 | created?: () => void; | 22 | created?: () => void; | ... | ... |
| 1 | /// <reference types="miniprogram-api-typings" /> | 1 | /// <reference types="miniprogram-api-typings" /> |
| 2 | -export declare type Action = 'confirm' | 'cancel' | 'overlay'; | 2 | +/// <reference types="miniprogram-api-typings" /> |
| 3 | +export type Action = 'confirm' | 'cancel' | 'overlay'; | ||
| 4 | +type DialogContext = WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance; | ||
| 3 | interface DialogOptions { | 5 | interface DialogOptions { |
| 4 | lang?: string; | 6 | lang?: string; |
| 5 | show?: boolean; | 7 | show?: boolean; |
| ... | @@ -7,11 +9,14 @@ interface DialogOptions { | ... | @@ -7,11 +9,14 @@ interface DialogOptions { |
| 7 | width?: string | number | null; | 9 | width?: string | number | null; |
| 8 | zIndex?: number; | 10 | zIndex?: number; |
| 9 | theme?: string; | 11 | theme?: string; |
| 10 | - context?: WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance; | 12 | + context?: (() => DialogContext) | DialogContext; |
| 11 | message?: string; | 13 | message?: string; |
| 12 | overlay?: boolean; | 14 | overlay?: boolean; |
| 13 | selector?: string; | 15 | selector?: string; |
| 14 | ariaLabel?: string; | 16 | ariaLabel?: string; |
| 17 | + /** | ||
| 18 | + * @deprecated use custom-class instead | ||
| 19 | + */ | ||
| 15 | className?: string; | 20 | className?: string; |
| 16 | customStyle?: string; | 21 | customStyle?: string; |
| 17 | transition?: string; | 22 | transition?: string; | ... | ... |
| ... | @@ -30,7 +30,9 @@ function getContext() { | ... | @@ -30,7 +30,9 @@ function getContext() { |
| 30 | const Dialog = (options) => { | 30 | const Dialog = (options) => { |
| 31 | options = Object.assign(Object.assign({}, currentOptions), options); | 31 | options = Object.assign(Object.assign({}, currentOptions), options); |
| 32 | return new Promise((resolve, reject) => { | 32 | return new Promise((resolve, reject) => { |
| 33 | - const context = options.context || getContext(); | 33 | + const context = (typeof options.context === 'function' |
| 34 | + ? options.context() | ||
| 35 | + : options.context) || getContext(); | ||
| 34 | const dialog = context.selectComponent(options.selector); | 36 | const dialog = context.selectComponent(options.selector); |
| 35 | delete options.context; | 37 | delete options.context; |
| 36 | delete options.selector; | 38 | delete options.selector; | ... | ... |
| ... | @@ -4,6 +4,7 @@ import { GRAY, RED } from '../common/color'; | ... | @@ -4,6 +4,7 @@ import { GRAY, RED } from '../common/color'; |
| 4 | import { toPromise } from '../common/utils'; | 4 | import { toPromise } from '../common/utils'; |
| 5 | VantComponent({ | 5 | VantComponent({ |
| 6 | mixins: [button], | 6 | mixins: [button], |
| 7 | + classes: ['cancle-button-class', 'confirm-button-class'], | ||
| 7 | props: { | 8 | props: { |
| 8 | show: { | 9 | show: { |
| 9 | type: Boolean, | 10 | type: Boolean, |
| ... | @@ -17,14 +18,17 @@ VantComponent({ | ... | @@ -17,14 +18,17 @@ VantComponent({ |
| 17 | type: String, | 18 | type: String, |
| 18 | value: 'default', | 19 | value: 'default', |
| 19 | }, | 20 | }, |
| 20 | - useSlot: Boolean, | 21 | + confirmButtonId: String, |
| 21 | className: String, | 22 | className: String, |
| 22 | customStyle: String, | 23 | customStyle: String, |
| 23 | asyncClose: Boolean, | 24 | asyncClose: Boolean, |
| 24 | messageAlign: String, | 25 | messageAlign: String, |
| 25 | beforeClose: null, | 26 | beforeClose: null, |
| 26 | overlayStyle: String, | 27 | overlayStyle: String, |
| 28 | + useSlot: Boolean, | ||
| 27 | useTitleSlot: Boolean, | 29 | useTitleSlot: Boolean, |
| 30 | + useConfirmButtonSlot: Boolean, | ||
| 31 | + useCancelButtonSlot: Boolean, | ||
| 28 | showCancelButton: Boolean, | 32 | showCancelButton: Boolean, |
| 29 | closeOnClickOverlay: Boolean, | 33 | closeOnClickOverlay: Boolean, |
| 30 | confirmButtonOpenType: String, | 34 | confirmButtonOpenType: String, |
| ... | @@ -61,6 +65,10 @@ VantComponent({ | ... | @@ -61,6 +65,10 @@ VantComponent({ |
| 61 | type: String, | 65 | type: String, |
| 62 | value: 'scale', | 66 | value: 'scale', |
| 63 | }, | 67 | }, |
| 68 | + rootPortal: { | ||
| 69 | + type: Boolean, | ||
| 70 | + value: false, | ||
| 71 | + }, | ||
| 64 | }, | 72 | }, |
| 65 | data: { | 73 | data: { |
| 66 | loading: { | 74 | loading: { |
| ... | @@ -81,13 +89,15 @@ VantComponent({ | ... | @@ -81,13 +89,15 @@ VantComponent({ |
| 81 | }, | 89 | }, |
| 82 | close(action) { | 90 | close(action) { |
| 83 | this.setData({ show: false }); | 91 | this.setData({ show: false }); |
| 84 | - wx.nextTick(() => { | 92 | + this.closeAction = action; |
| 93 | + }, | ||
| 94 | + onAfterLeave() { | ||
| 95 | + const { closeAction: action } = this; | ||
| 85 | this.$emit('close', action); | 96 | this.$emit('close', action); |
| 86 | const { callback } = this.data; | 97 | const { callback } = this.data; |
| 87 | if (callback) { | 98 | if (callback) { |
| 88 | callback(action, this); | 99 | callback(action, this); |
| 89 | } | 100 | } |
| 90 | - }); | ||
| 91 | }, | 101 | }, |
| 92 | stopLoading() { | 102 | stopLoading() { |
| 93 | this.setData({ | 103 | this.setData({ | ... | ... |
| ... | @@ -5,11 +5,13 @@ | ... | @@ -5,11 +5,13 @@ |
| 5 | z-index="{{ zIndex }}" | 5 | z-index="{{ zIndex }}" |
| 6 | overlay="{{ overlay }}" | 6 | overlay="{{ overlay }}" |
| 7 | transition="{{ transition }}" | 7 | transition="{{ transition }}" |
| 8 | - custom-class="van-dialog van-dialog--{{ theme }} {{ className }}" | 8 | + custom-class="van-dialog van-dialog--{{ theme }}{{ className }} custom-class" |
| 9 | custom-style="width: {{ utils.addUnit(width) }};{{ customStyle }}" | 9 | custom-style="width: {{ utils.addUnit(width) }};{{ customStyle }}" |
| 10 | overlay-style="{{ overlayStyle }}" | 10 | overlay-style="{{ overlayStyle }}" |
| 11 | close-on-click-overlay="{{ closeOnClickOverlay }}" | 11 | close-on-click-overlay="{{ closeOnClickOverlay }}" |
| 12 | + root-portal="{{ rootPortal }}" | ||
| 12 | bind:close="onClickOverlay" | 13 | bind:close="onClickOverlay" |
| 14 | + bind:after-leave="onAfterLeave" | ||
| 13 | > | 15 | > |
| 14 | <view | 16 | <view |
| 15 | wx:if="{{ title || useTitleSlot }}" | 17 | wx:if="{{ title || useTitleSlot }}" |
| ... | @@ -33,7 +35,7 @@ | ... | @@ -33,7 +35,7 @@ |
| 33 | size="large" | 35 | size="large" |
| 34 | loading="{{ loading.cancel }}" | 36 | loading="{{ loading.cancel }}" |
| 35 | class="van-dialog__button van-hairline--right" | 37 | class="van-dialog__button van-hairline--right" |
| 36 | - custom-class="van-dialog__cancel" | 38 | + custom-class="van-dialog__cancel cancle-button-class" |
| 37 | custom-style="color: {{ cancelButtonColor }}" | 39 | custom-style="color: {{ cancelButtonColor }}" |
| 38 | bind:click="onCancel" | 40 | bind:click="onCancel" |
| 39 | > | 41 | > |
| ... | @@ -44,9 +46,9 @@ | ... | @@ -44,9 +46,9 @@ |
| 44 | size="large" | 46 | size="large" |
| 45 | class="van-dialog__button" | 47 | class="van-dialog__button" |
| 46 | loading="{{ loading.confirm }}" | 48 | loading="{{ loading.confirm }}" |
| 47 | - custom-class="van-dialog__confirm" | 49 | + custom-class="van-dialog__confirm confirm-button-class" |
| 48 | custom-style="color: {{ confirmButtonColor }}" | 50 | custom-style="color: {{ confirmButtonColor }}" |
| 49 | - | 51 | + button-id="{{ confirmButtonId }}" |
| 50 | open-type="{{ confirmButtonOpenType }}" | 52 | open-type="{{ confirmButtonOpenType }}" |
| 51 | lang="{{ lang }}" | 53 | lang="{{ lang }}" |
| 52 | business-id="{{ businessId }}" | 54 | business-id="{{ businessId }}" |
| ... | @@ -56,7 +58,8 @@ | ... | @@ -56,7 +58,8 @@ |
| 56 | send-message-img="{{ sendMessageImg }}" | 58 | send-message-img="{{ sendMessageImg }}" |
| 57 | show-message-card="{{ showMessageCard }}" | 59 | show-message-card="{{ showMessageCard }}" |
| 58 | app-parameter="{{ appParameter }}" | 60 | app-parameter="{{ appParameter }}" |
| 59 | - | 61 | + bindagreeprivacyauthorization="onAgreePrivacyAuthorization" |
| 62 | + bindgetRealTimePhoneNumber="onGetRealTimePhoneNumber" | ||
| 60 | bind:click="onConfirm" | 63 | bind:click="onConfirm" |
| 61 | bindgetuserinfo="onGetUserInfo" | 64 | bindgetuserinfo="onGetUserInfo" |
| 62 | bindcontact="onContact" | 65 | bindcontact="onContact" |
| ... | @@ -69,26 +72,34 @@ | ... | @@ -69,26 +72,34 @@ |
| 69 | </van-goods-action-button> | 72 | </van-goods-action-button> |
| 70 | </van-goods-action> | 73 | </van-goods-action> |
| 71 | 74 | ||
| 72 | - <view wx:else class="van-hairline--top van-dialog__footer"> | 75 | + <view wx:elif="{{ showCancelButton || showConfirmButton }}" class="van-hairline--top van-dialog__footer"> |
| 76 | + <block wx:if="{{ showCancelButton }}"> | ||
| 77 | + <slot wx:if="{{ useCancelButtonSlot }}" name="cancel-button" /> | ||
| 78 | + | ||
| 73 | <van-button | 79 | <van-button |
| 74 | - wx:if="{{ showCancelButton }}" | 80 | + wx:else |
| 75 | size="large" | 81 | size="large" |
| 76 | loading="{{ loading.cancel }}" | 82 | loading="{{ loading.cancel }}" |
| 77 | class="van-dialog__button van-hairline--right" | 83 | class="van-dialog__button van-hairline--right" |
| 78 | - custom-class="van-dialog__cancel" | 84 | + custom-class="van-dialog__cancel cancle-button-class" |
| 79 | custom-style="color: {{ cancelButtonColor }}" | 85 | custom-style="color: {{ cancelButtonColor }}" |
| 80 | bind:click="onCancel" | 86 | bind:click="onCancel" |
| 81 | > | 87 | > |
| 82 | {{ cancelButtonText }} | 88 | {{ cancelButtonText }} |
| 83 | </van-button> | 89 | </van-button> |
| 90 | + </block> | ||
| 91 | + | ||
| 92 | + <block wx:if="{{ showConfirmButton }}"> | ||
| 93 | + <slot wx:if="{{ useConfirmButtonSlot }}" name="confirm-button" /> | ||
| 94 | + | ||
| 84 | <van-button | 95 | <van-button |
| 85 | - wx:if="{{ showConfirmButton }}" | 96 | + wx:else |
| 86 | size="large" | 97 | size="large" |
| 87 | class="van-dialog__button" | 98 | class="van-dialog__button" |
| 88 | loading="{{ loading.confirm }}" | 99 | loading="{{ loading.confirm }}" |
| 89 | - custom-class="van-dialog__confirm" | 100 | + custom-class="van-dialog__confirm confirm-button-class" |
| 90 | custom-style="color: {{ confirmButtonColor }}" | 101 | custom-style="color: {{ confirmButtonColor }}" |
| 91 | - | 102 | + button-id="{{ confirmButtonId }}" |
| 92 | open-type="{{ confirmButtonOpenType }}" | 103 | open-type="{{ confirmButtonOpenType }}" |
| 93 | lang="{{ lang }}" | 104 | lang="{{ lang }}" |
| 94 | business-id="{{ businessId }}" | 105 | business-id="{{ businessId }}" |
| ... | @@ -98,7 +109,8 @@ | ... | @@ -98,7 +109,8 @@ |
| 98 | send-message-img="{{ sendMessageImg }}" | 109 | send-message-img="{{ sendMessageImg }}" |
| 99 | show-message-card="{{ showMessageCard }}" | 110 | show-message-card="{{ showMessageCard }}" |
| 100 | app-parameter="{{ appParameter }}" | 111 | app-parameter="{{ appParameter }}" |
| 101 | - | 112 | + bindagreeprivacyauthorization="onAgreePrivacyAuthorization" |
| 113 | + bindgetRealTimePhoneNumber="onGetRealTimePhoneNumber" | ||
| 102 | bind:click="onConfirm" | 114 | bind:click="onConfirm" |
| 103 | bindgetuserinfo="onGetUserInfo" | 115 | bindgetuserinfo="onGetUserInfo" |
| 104 | bindcontact="onContact" | 116 | bindcontact="onContact" |
| ... | @@ -109,5 +121,6 @@ | ... | @@ -109,5 +121,6 @@ |
| 109 | > | 121 | > |
| 110 | {{ confirmButtonText }} | 122 | {{ confirmButtonText }} |
| 111 | </van-button> | 123 | </van-button> |
| 124 | + </block> | ||
| 112 | </view> | 125 | </view> |
| 113 | </van-popup> | 126 | </van-popup> | ... | ... |
| 1 | -@import '../common/index.wxss';.van-dialog{background-color:var(--dialog-background-color,#fff);border-radius:var(--dialog-border-radius,16px);font-size:var(--dialog-font-size,16px);overflow:hidden;top:45%!important;width:var(--dialog-width,320px)}@media (max-width:321px){.van-dialog{width:var(--dialog-small-screen-width,90%)}}.van-dialog__header{font-weight:var(--dialog-header-font-weight,500);line-height:var(--dialog-header-line-height,24px);padding-top:var(--dialog-header-padding-top,24px);text-align:center}.van-dialog__header--isolated{padding:var(--dialog-header-isolated-padding,24px 0)}.van-dialog__message{-webkit-overflow-scrolling:touch;font-size:var(--dialog-message-font-size,14px);line-height:var(--dialog-message-line-height,20px);max-height:var(--dialog-message-max-height,60vh);overflow-y:auto;padding:var(--dialog-message-padding,24px);text-align:center}.van-dialog__message-text{word-wrap:break-word}.van-dialog__message--hasTitle{color:var(--dialog-has-title-message-text-color,#646566);padding-top:var(--dialog-has-title-message-padding-top,8px)}.van-dialog__message--round-button{color:#323233;padding-bottom:16px}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:flex}.van-dialog__footer--round-button{padding:8px 24px 16px!important;position:relative!important}.van-dialog__button{flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog-bounce-enter{opacity:0;transform:translate3d(-50%,-50%,0) scale(.7)}.van-dialog-bounce-leave-active{opacity:0;transform:translate3d(-50%,-50%,0) scale(.9)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-dialog{background-color:var(--dialog-background-color,#fff);border-radius:var(--dialog-border-radius,16px);font-size:var(--dialog-font-size,16px);overflow:hidden;top:45%!important;width:var(--dialog-width,320px)}@media (max-width:321px){.van-dialog{width:var(--dialog-small-screen-width,90%)}}.van-dialog__header{font-weight:var(--dialog-header-font-weight,500);line-height:var(--dialog-header-line-height,24px);padding-top:var(--dialog-header-padding-top,24px);text-align:center}.van-dialog__header--isolated{padding:var(--dialog-header-isolated-padding,24px 0)}.van-dialog__message{-webkit-overflow-scrolling:touch;font-size:var(--dialog-message-font-size,14px);line-height:var(--dialog-message-line-height,20px);max-height:var(--dialog-message-max-height,60vh);overflow-y:auto;padding:var(--dialog-message-padding,24px);text-align:center}.van-dialog__message-text{word-wrap:break-word}.van-dialog__message--hasTitle{color:var(--dialog-has-title-message-text-color,#646566);padding-top:var(--dialog-has-title-message-padding-top,8px)}.van-dialog__message--round-button{color:#323233;padding-bottom:16px}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__message--justify{text-align:justify}.van-dialog__footer{display:flex}.van-dialog__footer--round-button{padding:8px 24px 16px!important;position:relative!important}.van-dialog__button{flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog-bounce-enter{opacity:0;transform:translate3d(-50%,-50%,0) scale(.7)}.van-dialog-bounce-leave-active{opacity:0;transform:translate3d(-50%,-50%,0) scale(.9)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | import { useParent } from '../common/relation'; | 1 | import { useParent } from '../common/relation'; |
| 2 | import { VantComponent } from '../common/component'; | 2 | import { VantComponent } from '../common/component'; |
| 3 | VantComponent({ | 3 | VantComponent({ |
| 4 | + classes: ['item-title-class'], | ||
| 4 | field: true, | 5 | field: true, |
| 5 | relation: useParent('dropdown-menu', function () { | 6 | relation: useParent('dropdown-menu', function () { |
| 6 | this.updateDataFromParent(); | 7 | this.updateDataFromParent(); |
| ... | @@ -25,12 +26,21 @@ VantComponent({ | ... | @@ -25,12 +26,21 @@ VantComponent({ |
| 25 | observer: 'rerender', | 26 | observer: 'rerender', |
| 26 | }, | 27 | }, |
| 27 | popupStyle: String, | 28 | popupStyle: String, |
| 29 | + useBeforeToggle: { | ||
| 30 | + type: Boolean, | ||
| 31 | + value: false, | ||
| 32 | + }, | ||
| 33 | + rootPortal: { | ||
| 34 | + type: Boolean, | ||
| 35 | + value: false, | ||
| 36 | + }, | ||
| 28 | }, | 37 | }, |
| 29 | data: { | 38 | data: { |
| 30 | transition: true, | 39 | transition: true, |
| 31 | showPopup: false, | 40 | showPopup: false, |
| 32 | showWrapper: false, | 41 | showWrapper: false, |
| 33 | displayTitle: '', | 42 | displayTitle: '', |
| 43 | + safeAreaTabBar: false, | ||
| 34 | }, | 44 | }, |
| 35 | methods: { | 45 | methods: { |
| 36 | rerender() { | 46 | rerender() { |
| ... | @@ -41,13 +51,14 @@ VantComponent({ | ... | @@ -41,13 +51,14 @@ VantComponent({ |
| 41 | }, | 51 | }, |
| 42 | updateDataFromParent() { | 52 | updateDataFromParent() { |
| 43 | if (this.parent) { | 53 | if (this.parent) { |
| 44 | - const { overlay, duration, activeColor, closeOnClickOverlay, direction, } = this.parent.data; | 54 | + const { overlay, duration, activeColor, closeOnClickOverlay, direction, safeAreaTabBar, } = this.parent.data; |
| 45 | this.setData({ | 55 | this.setData({ |
| 46 | overlay, | 56 | overlay, |
| 47 | duration, | 57 | duration, |
| 48 | activeColor, | 58 | activeColor, |
| 49 | closeOnClickOverlay, | 59 | closeOnClickOverlay, |
| 50 | direction, | 60 | direction, |
| 61 | + safeAreaTabBar, | ||
| 51 | }); | 62 | }); |
| 52 | } | 63 | } |
| 53 | }, | 64 | }, |
| ... | @@ -76,7 +87,6 @@ VantComponent({ | ... | @@ -76,7 +87,6 @@ VantComponent({ |
| 76 | } | 87 | } |
| 77 | }, | 88 | }, |
| 78 | toggle(show, options = {}) { | 89 | toggle(show, options = {}) { |
| 79 | - var _a; | ||
| 80 | const { showPopup } = this.data; | 90 | const { showPopup } = this.data; |
| 81 | if (typeof show !== 'boolean') { | 91 | if (typeof show !== 'boolean') { |
| 82 | show = !showPopup; | 92 | show = !showPopup; |
| ... | @@ -84,6 +94,11 @@ VantComponent({ | ... | @@ -84,6 +94,11 @@ VantComponent({ |
| 84 | if (show === showPopup) { | 94 | if (show === showPopup) { |
| 85 | return; | 95 | return; |
| 86 | } | 96 | } |
| 97 | + this.onBeforeToggle(show).then((status) => { | ||
| 98 | + var _a; | ||
| 99 | + if (!status) { | ||
| 100 | + return; | ||
| 101 | + } | ||
| 87 | this.setData({ | 102 | this.setData({ |
| 88 | transition: !options.immediate, | 103 | transition: !options.immediate, |
| 89 | showPopup: show, | 104 | showPopup: show, |
| ... | @@ -97,6 +112,19 @@ VantComponent({ | ... | @@ -97,6 +112,19 @@ VantComponent({ |
| 97 | else { | 112 | else { |
| 98 | this.rerender(); | 113 | this.rerender(); |
| 99 | } | 114 | } |
| 115 | + }); | ||
| 116 | + }, | ||
| 117 | + onBeforeToggle(status) { | ||
| 118 | + const { useBeforeToggle } = this.data; | ||
| 119 | + if (!useBeforeToggle) { | ||
| 120 | + return Promise.resolve(true); | ||
| 121 | + } | ||
| 122 | + return new Promise((resolve) => { | ||
| 123 | + this.$emit('before-toggle', { | ||
| 124 | + status, | ||
| 125 | + callback: (value) => resolve(value), | ||
| 126 | + }); | ||
| 127 | + }); | ||
| 100 | }, | 128 | }, |
| 101 | }, | 129 | }, |
| 102 | }); | 130 | }); | ... | ... |
| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | ||
| 3 | <view | 3 | <view |
| 4 | wx:if="{{ showWrapper }}" | 4 | wx:if="{{ showWrapper }}" |
| 5 | - class="{{ utils.bem('dropdown-item', direction) }}" | 5 | + class="{{ utils.bem('dropdown-item', direction) }} custom-class" |
| 6 | style="{{ wrapperStyle }}" | 6 | style="{{ wrapperStyle }}" |
| 7 | > | 7 | > |
| 8 | <van-popup | 8 | <van-popup |
| ... | @@ -12,7 +12,9 @@ | ... | @@ -12,7 +12,9 @@ |
| 12 | overlay="{{ overlay }}" | 12 | overlay="{{ overlay }}" |
| 13 | position="{{ direction === 'down' ? 'top' : 'bottom' }}" | 13 | position="{{ direction === 'down' ? 'top' : 'bottom' }}" |
| 14 | duration="{{ transition ? duration : 0 }}" | 14 | duration="{{ transition ? duration : 0 }}" |
| 15 | + safe-area-tab-bar="{{ safeAreaTabBar }}" | ||
| 15 | close-on-click-overlay="{{ closeOnClickOverlay }}" | 16 | close-on-click-overlay="{{ closeOnClickOverlay }}" |
| 17 | + rootPortal="{{ rootPortal }}" | ||
| 16 | bind:enter="onOpen" | 18 | bind:enter="onOpen" |
| 17 | bind:leave="onClose" | 19 | bind:leave="onClose" |
| 18 | bind:close="toggle" | 20 | bind:close="toggle" |
| ... | @@ -30,7 +32,7 @@ | ... | @@ -30,7 +32,7 @@ |
| 30 | > | 32 | > |
| 31 | <view | 33 | <view |
| 32 | slot="title" | 34 | slot="title" |
| 33 | - class="van-dropdown-item__title" | 35 | + class="van-dropdown-item__title item-title-class" |
| 34 | style="{{ item.value === value ? 'color:' + activeColor : '' }}" | 36 | style="{{ item.value === value ? 'color:' + activeColor : '' }}" |
| 35 | > | 37 | > |
| 36 | {{ item.text }} | 38 | {{ item.text }} | ... | ... |
| ... | @@ -4,6 +4,7 @@ import { addUnit, getRect, getSystemInfoSync } from '../common/utils'; | ... | @@ -4,6 +4,7 @@ import { addUnit, getRect, getSystemInfoSync } from '../common/utils'; |
| 4 | let ARRAY = []; | 4 | let ARRAY = []; |
| 5 | VantComponent({ | 5 | VantComponent({ |
| 6 | field: true, | 6 | field: true, |
| 7 | + classes: ['title-class'], | ||
| 7 | relation: useChildren('dropdown-item', function () { | 8 | relation: useChildren('dropdown-item', function () { |
| 8 | this.updateItemListData(); | 9 | this.updateItemListData(); |
| 9 | }), | 10 | }), |
| ... | @@ -31,6 +32,10 @@ VantComponent({ | ... | @@ -31,6 +32,10 @@ VantComponent({ |
| 31 | value: 'down', | 32 | value: 'down', |
| 32 | observer: 'updateChildrenData', | 33 | observer: 'updateChildrenData', |
| 33 | }, | 34 | }, |
| 35 | + safeAreaTabBar: { | ||
| 36 | + type: Boolean, | ||
| 37 | + value: false, | ||
| 38 | + }, | ||
| 34 | closeOnClickOverlay: { | 39 | closeOnClickOverlay: { |
| 35 | type: Boolean, | 40 | type: Boolean, |
| 36 | value: true, | 41 | value: true, | ... | ... |
| ... | @@ -10,7 +10,7 @@ | ... | @@ -10,7 +10,7 @@ |
| 10 | bind:tap="onTitleTap" | 10 | bind:tap="onTitleTap" |
| 11 | > | 11 | > |
| 12 | <view | 12 | <view |
| 13 | - class="{{ item.titleClass }} {{ utils.bem('dropdown-menu__title', { active: item.showPopup, down: item.showPopup === (direction === 'down') }) }}" | 13 | + class="{{ item.titleClass }} {{ utils.bem('dropdown-menu__title', { active: item.showPopup, down: item.showPopup === (direction === 'down') }) }} title-class" |
| 14 | style="{{ item.showPopup ? 'color:' + activeColor : '' }}" | 14 | style="{{ item.showPopup ? 'color:' + activeColor : '' }}" |
| 15 | > | 15 | > |
| 16 | <view class="van-ellipsis"> | 16 | <view class="van-ellipsis"> | ... | ... |
| 1 | -@import '../common/index.wxss';.van-dropdown-menu{background-color:var(--dropdown-menu-background-color,#fff);box-shadow:var(--dropdown-menu-box-shadow,0 2px 12px hsla(210,1%,40%,.12));display:flex;height:var(--dropdown-menu-height,50px);-webkit-user-select:none;user-select:none}.van-dropdown-menu__item{align-items:center;display:flex;flex:1;justify-content:center;min-width:0}.van-dropdown-menu__item:active{opacity:.7}.van-dropdown-menu__item--disabled:active{opacity:1}.van-dropdown-menu__item--disabled .van-dropdown-menu__title{color:var(--dropdown-menu-title-disabled-text-color,#969799)}.van-dropdown-menu__title{box-sizing:border-box;color:var(--dropdown-menu-title-text-color,#323233);font-size:var(--dropdown-menu-title-font-size,15px);line-height:var(--dropdown-menu-title-line-height,18px);max-width:100%;padding:var(--dropdown-menu-title-padding,0 8px);position:relative}.van-dropdown-menu__title:after{border-color:transparent transparent currentcolor currentcolor;border-style:solid;border-width:3px;content:"";margin-top:-5px;opacity:.8;position:absolute;right:-4px;top:50%;transform:rotate(-45deg)}.van-dropdown-menu__title--active{color:var(--dropdown-menu-title-active-text-color,#ee0a24)}.van-dropdown-menu__title--down:after{margin-top:-1px;transform:rotate(135deg)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-dropdown-menu{background-color:var(--dropdown-menu-background-color,#fff);box-shadow:var(--dropdown-menu-box-shadow,0 2px 12px hsla(210,1%,40%,.12));display:flex;height:var(--dropdown-menu-height,50px);-webkit-user-select:none;user-select:none}.van-dropdown-menu__item{align-items:center;display:flex;flex:1;justify-content:center;min-width:0}.van-dropdown-menu__item:active{opacity:.7}.van-dropdown-menu__item--disabled:active{opacity:1}.van-dropdown-menu__item--disabled .van-dropdown-menu__title{color:var(--dropdown-menu-title-disabled-text-color,#969799)}.van-dropdown-menu__title{box-sizing:border-box;color:var(--dropdown-menu-title-text-color,#323233);font-size:var(--dropdown-menu-title-font-size,15px);line-height:var(--dropdown-menu-title-line-height,18px);max-width:100%;padding:var(--dropdown-menu-title-padding,0 24px 0 8px);position:relative}.van-dropdown-menu__title:after{border-color:transparent transparent currentcolor currentcolor;border-style:solid;border-width:3px;content:"";margin-top:-5px;opacity:.8;position:absolute;right:11px;top:50%;transform:rotate(-45deg)}.van-dropdown-menu__title--active{color:var(--dropdown-menu-title-active-text-color,#ee0a24)}.van-dropdown-menu__title--down:after{margin-top:-1px;transform:rotate(135deg)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -22,22 +22,45 @@ VantComponent({ | ... | @@ -22,22 +22,45 @@ VantComponent({ |
| 22 | }, clearIcon: { | 22 | }, clearIcon: { |
| 23 | type: String, | 23 | type: String, |
| 24 | value: 'clear', | 24 | value: 'clear', |
| 25 | + }, extraEventParams: { | ||
| 26 | + type: Boolean, | ||
| 27 | + value: false, | ||
| 25 | } }), | 28 | } }), |
| 26 | data: { | 29 | data: { |
| 27 | focused: false, | 30 | focused: false, |
| 28 | innerValue: '', | 31 | innerValue: '', |
| 29 | showClear: false, | 32 | showClear: false, |
| 30 | }, | 33 | }, |
| 34 | + watch: { | ||
| 35 | + value(value) { | ||
| 36 | + if (value !== this.value) { | ||
| 37 | + this.setData({ innerValue: value }); | ||
| 38 | + this.value = value; | ||
| 39 | + this.setShowClear(); | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + clearTrigger() { | ||
| 43 | + this.setShowClear(); | ||
| 44 | + }, | ||
| 45 | + }, | ||
| 31 | created() { | 46 | created() { |
| 32 | this.value = this.data.value; | 47 | this.value = this.data.value; |
| 33 | this.setData({ innerValue: this.value }); | 48 | this.setData({ innerValue: this.value }); |
| 34 | }, | 49 | }, |
| 35 | methods: { | 50 | methods: { |
| 51 | + formatValue(value) { | ||
| 52 | + const { maxlength } = this.data; | ||
| 53 | + if (maxlength !== -1 && value.length > maxlength) { | ||
| 54 | + return value.slice(0, maxlength); | ||
| 55 | + } | ||
| 56 | + return value; | ||
| 57 | + }, | ||
| 36 | onInput(event) { | 58 | onInput(event) { |
| 37 | const { value = '' } = event.detail || {}; | 59 | const { value = '' } = event.detail || {}; |
| 38 | - this.value = value; | 60 | + const formatValue = this.formatValue(value); |
| 61 | + this.value = formatValue; | ||
| 39 | this.setShowClear(); | 62 | this.setShowClear(); |
| 40 | - this.emitChange(); | 63 | + return this.emitChange(Object.assign(Object.assign({}, event.detail), { value: formatValue })); |
| 41 | }, | 64 | }, |
| 42 | onFocus(event) { | 65 | onFocus(event) { |
| 43 | this.focused = true; | 66 | this.focused = true; |
| ... | @@ -60,7 +83,7 @@ VantComponent({ | ... | @@ -60,7 +83,7 @@ VantComponent({ |
| 60 | this.value = ''; | 83 | this.value = ''; |
| 61 | this.setShowClear(); | 84 | this.setShowClear(); |
| 62 | nextTick(() => { | 85 | nextTick(() => { |
| 63 | - this.emitChange(); | 86 | + this.emitChange({ value: '' }); |
| 64 | this.$emit('clear', ''); | 87 | this.$emit('clear', ''); |
| 65 | }); | 88 | }); |
| 66 | }, | 89 | }, |
| ... | @@ -76,7 +99,7 @@ VantComponent({ | ... | @@ -76,7 +99,7 @@ VantComponent({ |
| 76 | if (value === '') { | 99 | if (value === '') { |
| 77 | this.setData({ innerValue: '' }); | 100 | this.setData({ innerValue: '' }); |
| 78 | } | 101 | } |
| 79 | - this.emitChange(); | 102 | + this.emitChange({ value }); |
| 80 | }, | 103 | }, |
| 81 | onLineChange(event) { | 104 | onLineChange(event) { |
| 82 | this.$emit('linechange', event.detail); | 105 | this.$emit('linechange', event.detail); |
| ... | @@ -84,12 +107,20 @@ VantComponent({ | ... | @@ -84,12 +107,20 @@ VantComponent({ |
| 84 | onKeyboardHeightChange(event) { | 107 | onKeyboardHeightChange(event) { |
| 85 | this.$emit('keyboardheightchange', event.detail); | 108 | this.$emit('keyboardheightchange', event.detail); |
| 86 | }, | 109 | }, |
| 87 | - emitChange() { | 110 | + onBindNicknameReview(event) { |
| 88 | - this.setData({ value: this.value }); | 111 | + this.$emit('nicknamereview', event.detail); |
| 89 | - nextTick(() => { | 112 | + }, |
| 90 | - this.$emit('input', this.value); | 113 | + emitChange(detail) { |
| 91 | - this.$emit('change', this.value); | 114 | + const { extraEventParams } = this.data; |
| 92 | - }); | 115 | + this.setData({ value: detail.value }); |
| 116 | + let result; | ||
| 117 | + const data = extraEventParams | ||
| 118 | + ? Object.assign(Object.assign({}, detail), { callback: (data) => { | ||
| 119 | + result = data; | ||
| 120 | + } }) : detail.value; | ||
| 121 | + this.$emit('input', data); | ||
| 122 | + this.$emit('change', data); | ||
| 123 | + return result; | ||
| 93 | }, | 124 | }, |
| 94 | setShowClear() { | 125 | setShowClear() { |
| 95 | const { clearable, readonly, clearTrigger } = this.data; | 126 | const { clearable, readonly, clearTrigger } = this.data; |
| ... | @@ -100,7 +131,7 @@ VantComponent({ | ... | @@ -100,7 +131,7 @@ VantComponent({ |
| 100 | const trigger = clearTrigger === 'always' || (clearTrigger === 'focus' && focused); | 131 | const trigger = clearTrigger === 'always' || (clearTrigger === 'focus' && focused); |
| 101 | showClear = hasValue && trigger; | 132 | showClear = hasValue && trigger; |
| 102 | } | 133 | } |
| 103 | - this.setData({ showClear }); | 134 | + this.setView({ showClear }); |
| 104 | }, | 135 | }, |
| 105 | noop() { }, | 136 | noop() { }, |
| 106 | }, | 137 | }, | ... | ... |
| ... | @@ -13,12 +13,12 @@ | ... | @@ -13,12 +13,12 @@ |
| 13 | title-style="margin-right: 12px;" | 13 | title-style="margin-right: 12px;" |
| 14 | custom-style="{{ customStyle }}" | 14 | custom-style="{{ customStyle }}" |
| 15 | arrow-direction="{{ arrowDirection }}" | 15 | arrow-direction="{{ arrowDirection }}" |
| 16 | - custom-class="van-field" | 16 | + custom-class="custom-class van-field" |
| 17 | > | 17 | > |
| 18 | <slot name="left-icon" slot="icon" /> | 18 | <slot name="left-icon" slot="icon" /> |
| 19 | - <view wx:if="{{ label }}" class="label-class {{ utils.bem('field__label', { disabled }) }}" slot="title"> | 19 | + <label for="{{ name }}" wx:if="{{ label }}" class="label-class {{ utils.bem('field__label', { disabled }) }}" slot="title"> |
| 20 | {{ label }} | 20 | {{ label }} |
| 21 | - </view> | 21 | + </label> |
| 22 | <slot wx:else name="label" slot="title" /> | 22 | <slot wx:else name="label" slot="title" /> |
| 23 | <view class="{{ utils.bem('field__body', [type]) }}"> | 23 | <view class="{{ utils.bem('field__body', [type]) }}"> |
| 24 | <view class="{{ utils.bem('field__control', [inputAlign, 'custom']) }}" bindtap="onClickInput"> | 24 | <view class="{{ utils.bem('field__control', [inputAlign, 'custom']) }}" bindtap="onClickInput"> |
| ... | @@ -47,10 +47,10 @@ | ... | @@ -47,10 +47,10 @@ |
| 47 | <slot name="button" /> | 47 | <slot name="button" /> |
| 48 | </view> | 48 | </view> |
| 49 | </view> | 49 | </view> |
| 50 | - <view wx:if="{{ showWordLimit && maxlength }}" class="van-field__word-limit"> | 50 | + <label for="{{ name }}" wx:if="{{ showWordLimit && maxlength }}" class="van-field__word-limit"> |
| 51 | <view class="{{ utils.bem('field__word-num', { full: value.length >= maxlength }) }}">{{ value.length >= maxlength ? maxlength : value.length }}</view>/{{ maxlength }} | 51 | <view class="{{ utils.bem('field__word-num', { full: value.length >= maxlength }) }}">{{ value.length >= maxlength ? maxlength : value.length }}</view>/{{ maxlength }} |
| 52 | - </view> | 52 | + </label> |
| 53 | - <view wx:if="{{ errorMessage }}" class="{{ utils.bem('field__error-message', [errorMessageAlign, { disabled, error }]) }}"> | 53 | + <label for="{{ name }}" wx:if="{{ errorMessage }}" class="{{ utils.bem('field__error-message', [errorMessageAlign, { disabled, error }]) }}"> |
| 54 | {{ errorMessage }} | 54 | {{ errorMessage }} |
| 55 | - </view> | 55 | + </label> |
| 56 | </van-cell> | 56 | </van-cell> | ... | ... |
| 1 | -@import '../common/index.wxss';.van-field{--cell-icon-size:var(--field-icon-size,16px)}.van-field__label{color:var(--field-label-color,#646566)}.van-field__label--disabled{color:var(--field-disabled-text-color,#c8c9cc)}.van-field__body{align-items:center;display:flex}.van-field__body--textarea{box-sizing:border-box;line-height:1.2em;min-height:var(--cell-line-height,24px);padding:3.6px 0}.van-field__control:empty+.van-field__control{display:block}.van-field__control{background-color:initial;border:0;box-sizing:border-box;color:var(--field-input-text-color,#323233);display:none;height:var(--cell-line-height,24px);line-height:inherit;margin:0;min-height:var(--cell-line-height,24px);padding:0;position:relative;resize:none;text-align:left;width:100%}.van-field__control:empty{display:none}.van-field__control--textarea{height:var(--field-text-area-min-height,18px);min-height:var(--field-text-area-min-height,18px)}.van-field__control--error{color:var(--field-input-error-text-color,#ee0a24)}.van-field__control--disabled{background-color:initial;color:var(--field-input-disabled-text-color,#c8c9cc);opacity:1}.van-field__control--center{text-align:center}.van-field__control--right{text-align:right}.van-field__control--custom{align-items:center;display:flex;min-height:var(--cell-line-height,24px)}.van-field__placeholder{color:var(--field-placeholder-text-color,#c8c9cc);left:0;pointer-events:none;position:absolute;right:0;top:0}.van-field__placeholder--error{color:var(--field-error-message-color,#ee0a24)}.van-field__icon-root{align-items:center;display:flex;min-height:var(--cell-line-height,24px)}.van-field__clear-root,.van-field__icon-container{line-height:inherit;margin-right:calc(var(--padding-xs, 8px)*-1);padding:0 var(--padding-xs,8px);vertical-align:middle}.van-field__button,.van-field__clear-root,.van-field__icon-container{flex-shrink:0}.van-field__clear-root{color:var(--field-clear-icon-color,#c8c9cc);font-size:var(--field-clear-icon-size,16px)}.van-field__icon-container{color:var(--field-icon-container-color,#969799);font-size:var(--field-icon-size,16px)}.van-field__icon-container:empty{display:none}.van-field__button{padding-left:var(--padding-xs,8px)}.van-field__button:empty{display:none}.van-field__error-message{color:var(--field-error-message-color,#ee0a24);font-size:var(--field-error-message-text-font-size,12px);text-align:left}.van-field__error-message--center{text-align:center}.van-field__error-message--right{text-align:right}.van-field__word-limit{color:var(--field-word-limit-color,#646566);font-size:var(--field-word-limit-font-size,12px);line-height:var(--field-word-limit-line-height,16px);margin-top:var(--padding-base,4px);text-align:right}.van-field__word-num{display:inline}.van-field__word-num--full{color:var(--field-word-num-full-color,#ee0a24)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-field{--cell-icon-size:var(--field-icon-size,16px)}.van-field__label{color:var(--field-label-color,#646566)}.van-field__label--disabled{color:var(--field-disabled-text-color,#c8c9cc)}.van-field__body{align-items:center;display:flex}.van-field__body--textarea{box-sizing:border-box;line-height:1.2em;min-height:var(--cell-line-height,24px);padding:3.6px 0}.van-field__control:empty+.van-field__control{display:block}.van-field__control{background-color:initial;border:0;box-sizing:border-box;color:var(--field-input-text-color,#323233);display:none;height:var(--cell-line-height,24px);line-height:inherit;margin:0;min-height:var(--cell-line-height,24px);padding:0;position:relative;resize:none;text-align:left;width:100%}.van-field__control:empty{display:none}.van-field__control--textarea{height:var(--field-text-area-min-height,18px);min-height:var(--field-text-area-min-height,18px)}.van-field__control--error{color:var(--field-input-error-text-color,#ee0a24)}.van-field__control--disabled{background-color:initial;color:var(--field-input-disabled-text-color,#c8c9cc);opacity:1}.van-field__control--center{text-align:center}.van-field__control--right{text-align:right}.van-field__control--custom{align-items:center;display:flex;min-height:var(--cell-line-height,24px)}.van-field__placeholder{color:var(--field-placeholder-text-color,#c8c9cc);left:0;pointer-events:none;position:absolute;right:0;top:0}.van-field__placeholder--error{color:var(--field-error-message-color,#ee0a24)}.van-field__icon-root{align-items:center;display:flex;min-height:var(--cell-line-height,24px)}.van-field__clear-root,.van-field__icon-container{line-height:inherit;margin-right:calc(var(--padding-xs, 8px)*-1);padding:0 var(--padding-xs,8px);vertical-align:middle}.van-field__button,.van-field__clear-root,.van-field__icon-container{flex-shrink:0}.van-field__clear-root{color:var(--field-clear-icon-color,#c8c9cc);font-size:var(--field-clear-icon-size,16px)}.van-field__icon-container{color:var(--field-icon-container-color,#969799);font-size:var(--field-icon-size,16px)}.van-field__icon-container:empty{display:none}.van-field__button{padding-left:var(--padding-xs,8px)}.van-field__button:empty{display:none}.van-field__error-message{color:var(--field-error-message-color,#ee0a24);display:block;font-size:var(--field-error-message-text-font-size,12px);text-align:left}.van-field__error-message--center{text-align:center}.van-field__error-message--right{text-align:right}.van-field__word-limit{color:var(--field-word-limit-color,#646566);font-size:var(--field-word-limit-font-size,12px);line-height:var(--field-word-limit-line-height,16px);margin-top:var(--padding-base,4px);text-align:right}.van-field__word-num{display:inline}.van-field__word-num--full{color:var(--field-word-num-full-color,#ee0a24)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | +<wxs src="../wxs/utils.wxs" module="utils" /> | ||
| 1 | <input | 2 | <input |
| 3 | + id="{{ name }}" | ||
| 2 | class="{{ utils.bem('field__control', [inputAlign, { disabled, error }]) }} input-class" | 4 | class="{{ utils.bem('field__control', [inputAlign, { disabled, error }]) }} input-class" |
| 3 | type="{{ type }}" | 5 | type="{{ type }}" |
| 4 | focus="{{ focus }}" | 6 | focus="{{ focus }}" |
| ... | @@ -25,4 +27,5 @@ | ... | @@ -25,4 +27,5 @@ |
| 25 | bindfocus="onFocus" | 27 | bindfocus="onFocus" |
| 26 | bindconfirm="onConfirm" | 28 | bindconfirm="onConfirm" |
| 27 | bindkeyboardheightchange="onKeyboardHeightChange" | 29 | bindkeyboardheightchange="onKeyboardHeightChange" |
| 30 | + bindnicknamereview="onBindNicknameReview" | ||
| 28 | /> | 31 | /> | ... | ... |
| 1 | export const commonProps = { | 1 | export const commonProps = { |
| 2 | - value: { | 2 | + value: String, |
| 3 | - type: String, | ||
| 4 | - observer(value) { | ||
| 5 | - if (value !== this.value) { | ||
| 6 | - this.setData({ innerValue: value }); | ||
| 7 | - this.value = value; | ||
| 8 | - } | ||
| 9 | - }, | ||
| 10 | - }, | ||
| 11 | placeholder: String, | 3 | placeholder: String, |
| 12 | placeholderStyle: String, | 4 | placeholderStyle: String, |
| 13 | placeholderClass: String, | 5 | placeholderClass: String, | ... | ... |
| 1 | +<wxs src="../wxs/utils.wxs" module="utils" /> | ||
| 2 | +<wxs src="./index.wxs" module="computed" /> | ||
| 1 | <textarea | 3 | <textarea |
| 4 | + id="{{ name }}" | ||
| 2 | class="{{ utils.bem('field__control', [inputAlign, type, { disabled, error }]) }} input-class" | 5 | class="{{ utils.bem('field__control', [inputAlign, type, { disabled, error }]) }} input-class" |
| 3 | fixed="{{ fixed }}" | 6 | fixed="{{ fixed }}" |
| 4 | focus="{{ focus }}" | 7 | focus="{{ focus }}" | ... | ... |
src/components/vant-weapp/field/types.d.ts
0 → 100644
src/components/vant-weapp/field/types.js
0 → 100644
| 1 | +export {}; |
| ... | @@ -8,6 +8,10 @@ VantComponent({ | ... | @@ -8,6 +8,10 @@ VantComponent({ |
| 8 | props: { | 8 | props: { |
| 9 | text: String, | 9 | text: String, |
| 10 | color: String, | 10 | color: String, |
| 11 | + size: { | ||
| 12 | + type: String, | ||
| 13 | + value: 'normal', | ||
| 14 | + }, | ||
| 11 | loading: Boolean, | 15 | loading: Boolean, |
| 12 | disabled: Boolean, | 16 | disabled: Boolean, |
| 13 | plain: Boolean, | 17 | plain: Boolean, |
| ... | @@ -15,6 +19,10 @@ VantComponent({ | ... | @@ -15,6 +19,10 @@ VantComponent({ |
| 15 | type: String, | 19 | type: String, |
| 16 | value: 'danger', | 20 | value: 'danger', |
| 17 | }, | 21 | }, |
| 22 | + customStyle: { | ||
| 23 | + type: String, | ||
| 24 | + value: '', | ||
| 25 | + }, | ||
| 18 | }, | 26 | }, |
| 19 | methods: { | 27 | methods: { |
| 20 | onClick(event) { | 28 | onClick(event) { | ... | ... |
| 1 | <wxs src="../wxs/utils.wxs" module="utils" /> | 1 | <wxs src="../wxs/utils.wxs" module="utils" /> |
| 2 | <van-button | 2 | <van-button |
| 3 | id="{{ id }}" | 3 | id="{{ id }}" |
| 4 | + button-id="{{ buttonId }}" | ||
| 4 | lang="{{ lang }}" | 5 | lang="{{ lang }}" |
| 5 | type="{{ type }}" | 6 | type="{{ type }}" |
| 7 | + size="{{ size }}" | ||
| 6 | color="{{ color }}" | 8 | color="{{ color }}" |
| 7 | plain="{{ plain }}" | 9 | plain="{{ plain }}" |
| 8 | loading="{{ loading }}" | 10 | loading="{{ loading }}" |
| 9 | disabled="{{ disabled }}" | 11 | disabled="{{ disabled }}" |
| 10 | open-type="{{ openType }}" | 12 | open-type="{{ openType }}" |
| 11 | class="{{ utils.bem('goods-action-button', [type, { first: isFirst, last: isLast, plain: plain }])}}" | 13 | class="{{ utils.bem('goods-action-button', [type, { first: isFirst, last: isLast, plain: plain }])}}" |
| 12 | - custom-class="van-goods-action-button__inner" | 14 | + custom-class="van-goods-action-button__inner custom-class" |
| 15 | + custom-style="{{customStyle}}" | ||
| 13 | business-id="{{ businessId }}" | 16 | business-id="{{ businessId }}" |
| 14 | session-from="{{ sessionFrom }}" | 17 | session-from="{{ sessionFrom }}" |
| 15 | app-parameter="{{ appParameter }}" | 18 | app-parameter="{{ appParameter }}" |
| ... | @@ -22,6 +25,8 @@ | ... | @@ -22,6 +25,8 @@ |
| 22 | bindcontact="onContact" | 25 | bindcontact="onContact" |
| 23 | bindopensetting="onOpenSetting" | 26 | bindopensetting="onOpenSetting" |
| 24 | bindgetuserinfo="onGetUserInfo" | 27 | bindgetuserinfo="onGetUserInfo" |
| 28 | + bindagreeprivacyauthorization="onAgreePrivacyAuthorization" | ||
| 29 | + bindgetRealTimePhoneNumber="onGetRealTimePhoneNumber" | ||
| 25 | bindgetphonenumber="onGetPhoneNumber" | 30 | bindgetphonenumber="onGetPhoneNumber" |
| 26 | bindlaunchapp="onLaunchApp" | 31 | bindlaunchapp="onLaunchApp" |
| 27 | > | 32 | > | ... | ... |
| ... | @@ -2,13 +2,15 @@ import { VantComponent } from '../common/component'; | ... | @@ -2,13 +2,15 @@ import { VantComponent } from '../common/component'; |
| 2 | import { button } from '../mixins/button'; | 2 | import { button } from '../mixins/button'; |
| 3 | import { link } from '../mixins/link'; | 3 | import { link } from '../mixins/link'; |
| 4 | VantComponent({ | 4 | VantComponent({ |
| 5 | - classes: ['icon-class', 'text-class'], | 5 | + classes: ['icon-class', 'text-class', 'info-class'], |
| 6 | mixins: [link, button], | 6 | mixins: [link, button], |
| 7 | props: { | 7 | props: { |
| 8 | text: String, | 8 | text: String, |
| 9 | dot: Boolean, | 9 | dot: Boolean, |
| 10 | info: String, | 10 | info: String, |
| 11 | icon: String, | 11 | icon: String, |
| 12 | + size: String, | ||
| 13 | + color: String, | ||
| 12 | classPrefix: { | 14 | classPrefix: { |
| 13 | type: String, | 15 | type: String, |
| 14 | value: 'van-icon', | 16 | value: 'van-icon', | ... | ... |
| ... | @@ -27,10 +27,15 @@ | ... | @@ -27,10 +27,15 @@ |
| 27 | name="{{ icon }}" | 27 | name="{{ icon }}" |
| 28 | dot="{{ dot }}" | 28 | dot="{{ dot }}" |
| 29 | info="{{ info }}" | 29 | info="{{ info }}" |
| 30 | + size="{{ size }}" | ||
| 31 | + color="{{ color }}" | ||
| 30 | class-prefix="{{ classPrefix }}" | 32 | class-prefix="{{ classPrefix }}" |
| 31 | class="van-goods-action-icon__icon" | 33 | class="van-goods-action-icon__icon" |
| 32 | custom-class="icon-class" | 34 | custom-class="icon-class" |
| 35 | + info-class="info-class" | ||
| 33 | /> | 36 | /> |
| 34 | - <slot wx:else name="icon" /> | 37 | + <view wx:else> |
| 38 | + <slot name="icon" /> | ||
| 39 | + </view> | ||
| 35 | <text class="text-class">{{ text }}</text> | 40 | <text class="text-class">{{ text }}</text> |
| 36 | </van-button> | 41 | </van-button> | ... | ... |
| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | wx:if="{{ info !== null || dot }}" | 9 | wx:if="{{ info !== null || dot }}" |
| 10 | dot="{{ dot }}" | 10 | dot="{{ dot }}" |
| 11 | info="{{ info }}" | 11 | info="{{ info }}" |
| 12 | - custom-class="van-icon__info" | 12 | + custom-class="van-icon__info info-class" |
| 13 | /> | 13 | /> |
| 14 | <image | 14 | <image |
| 15 | wx:if="{{ computed.isImage(name) }}" | 15 | wx:if="{{ computed.isImage(name) }}" | ... | ... |
| ... | @@ -9,6 +9,10 @@ function isImage(name) { | ... | @@ -9,6 +9,10 @@ function isImage(name) { |
| 9 | function rootClass(data) { | 9 | function rootClass(data) { |
| 10 | var classes = ['custom-class']; | 10 | var classes = ['custom-class']; |
| 11 | 11 | ||
| 12 | + if (data.classPrefix !== 'van-icon') { | ||
| 13 | + classes.push('van-icon--custom') | ||
| 14 | + } | ||
| 15 | + | ||
| 12 | if (data.classPrefix != null) { | 16 | if (data.classPrefix != null) { |
| 13 | classes.push(data.classPrefix); | 17 | classes.push(data.classPrefix); |
| 14 | } | 18 | } | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -25,6 +25,10 @@ VantComponent({ | ... | @@ -25,6 +25,10 @@ VantComponent({ |
| 25 | type: String, | 25 | type: String, |
| 26 | value: 'fill', | 26 | value: 'fill', |
| 27 | }, | 27 | }, |
| 28 | + webp: { | ||
| 29 | + type: Boolean, | ||
| 30 | + value: false, | ||
| 31 | + }, | ||
| 28 | showError: { | 32 | showError: { |
| 29 | type: Boolean, | 33 | type: Boolean, |
| 30 | value: true, | 34 | value: true, | ... | ... |
| ... | @@ -11,6 +11,7 @@ | ... | @@ -11,6 +11,7 @@ |
| 11 | src="{{ src }}" | 11 | src="{{ src }}" |
| 12 | mode="{{ computed.mode(fit) }}" | 12 | mode="{{ computed.mode(fit) }}" |
| 13 | lazy-load="{{ lazyLoad }}" | 13 | lazy-load="{{ lazyLoad }}" |
| 14 | + webp="{{ webp }}" | ||
| 14 | class="image-class van-image__img" | 15 | class="image-class van-image__img" |
| 15 | show-menu-by-longpress="{{ showMenuByLongpress }}" | 16 | show-menu-by-longpress="{{ showMenuByLongpress }}" |
| 16 | bind:load="onLoad" | 17 | bind:load="onLoad" | ... | ... |
| 1 | -@import '../common/index.wxss';.van-image{display:inline-block;position:relative}.van-image--round{border-radius:50%;overflow:hidden}.van-image--round .van-image__img{border-radius:inherit}.van-image__error,.van-image__img,.van-image__loading{display:block;height:100%;width:100%}.van-image__error,.van-image__loading{align-items:center;background-color:var(--image-placeholder-background-color,#f7f8fa);color:var(--image-placeholder-text-color,#969799);display:flex;flex-direction:column;font-size:var(--image-placeholder-font-size,14px);justify-content:center;left:0;position:absolute;top:0}.van-image__loading-icon{color:var(--image-loading-icon-color,#dcdee0);font-size:var(--image-loading-icon-size,32px)!important}.van-image__error-icon{color:var(--image-error-icon-color,#dcdee0);font-size:var(--image-error-icon-size,32px)!important} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-image{display:inline-block;position:relative;vertical-align:top}.van-image--round{border-radius:50%;overflow:hidden}.van-image--round .van-image__img{border-radius:inherit}.van-image__error,.van-image__img,.van-image__loading{display:block;height:100%;width:100%}.van-image__error,.van-image__loading{align-items:center;background-color:var(--image-placeholder-background-color,#f7f8fa);color:var(--image-placeholder-text-color,#969799);display:flex;flex-direction:column;font-size:var(--image-placeholder-font-size,14px);justify-content:center;left:0;position:absolute;top:0}.van-image__loading-icon{color:var(--image-loading-icon-color,#dcdee0);font-size:var(--image-loading-icon-size,32px)!important}.van-image__error-icon{color:var(--image-error-icon-color,#dcdee0);font-size:var(--image-error-icon-size,32px)!important} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -7,5 +7,20 @@ export const basic = Behavior({ | ... | @@ -7,5 +7,20 @@ export const basic = Behavior({ |
| 7 | this.setData(data); | 7 | this.setData(data); |
| 8 | return new Promise((resolve) => wx.nextTick(resolve)); | 8 | return new Promise((resolve) => wx.nextTick(resolve)); |
| 9 | }, | 9 | }, |
| 10 | + // high performance setData | ||
| 11 | + setView(data, callback) { | ||
| 12 | + const target = {}; | ||
| 13 | + let hasChange = false; | ||
| 14 | + Object.keys(data).forEach((key) => { | ||
| 15 | + if (data[key] !== this.data[key]) { | ||
| 16 | + target[key] = data[key]; | ||
| 17 | + hasChange = true; | ||
| 18 | + } | ||
| 19 | + }); | ||
| 20 | + if (hasChange) { | ||
| 21 | + return this.setData(target, callback); | ||
| 22 | + } | ||
| 23 | + return callback && callback(); | ||
| 24 | + }, | ||
| 10 | }, | 25 | }, |
| 11 | }); | 26 | }); | ... | ... |
| ... | @@ -3,6 +3,7 @@ export const button = Behavior({ | ... | @@ -3,6 +3,7 @@ export const button = Behavior({ |
| 3 | externalClasses: ['hover-class'], | 3 | externalClasses: ['hover-class'], |
| 4 | properties: { | 4 | properties: { |
| 5 | id: String, | 5 | id: String, |
| 6 | + buttonId: String, | ||
| 6 | lang: String, | 7 | lang: String, |
| 7 | businessId: Number, | 8 | businessId: Number, |
| 8 | sessionFrom: String, | 9 | sessionFrom: String, |
| ... | @@ -28,6 +29,9 @@ export const button = Behavior({ | ... | @@ -28,6 +29,9 @@ export const button = Behavior({ |
| 28 | onGetPhoneNumber(event) { | 29 | onGetPhoneNumber(event) { |
| 29 | this.triggerEvent('getphonenumber', event.detail); | 30 | this.triggerEvent('getphonenumber', event.detail); |
| 30 | }, | 31 | }, |
| 32 | + onGetRealTimePhoneNumber(event) { | ||
| 33 | + this.triggerEvent('getrealtimephonenumber', event.detail); | ||
| 34 | + }, | ||
| 31 | onError(event) { | 35 | onError(event) { |
| 32 | this.triggerEvent('error', event.detail); | 36 | this.triggerEvent('error', event.detail); |
| 33 | }, | 37 | }, |
| ... | @@ -37,5 +41,11 @@ export const button = Behavior({ | ... | @@ -37,5 +41,11 @@ export const button = Behavior({ |
| 37 | onOpenSetting(event) { | 41 | onOpenSetting(event) { |
| 38 | this.triggerEvent('opensetting', event.detail); | 42 | this.triggerEvent('opensetting', event.detail); |
| 39 | }, | 43 | }, |
| 44 | + onAgreePrivacyAuthorization(event) { | ||
| 45 | + this.triggerEvent('agreeprivacyauthorization', event.detail); | ||
| 46 | + }, | ||
| 47 | + onChooseAvatar(event) { | ||
| 48 | + this.triggerEvent('chooseavatar', event.detail); | ||
| 49 | + }, | ||
| 40 | }, | 50 | }, |
| 41 | }); | 51 | }); | ... | ... |
| 1 | /// <reference types="miniprogram-api-typings" /> | 1 | /// <reference types="miniprogram-api-typings" /> |
| 2 | -declare type IPageScrollOption = WechatMiniprogram.Page.IPageScrollOption; | 2 | +/// <reference types="miniprogram-api-typings" /> |
| 3 | -declare type Scroller = (this: WechatMiniprogram.Component.TrivialInstance, event?: IPageScrollOption) => void; | 3 | +type IPageScrollOption = WechatMiniprogram.Page.IPageScrollOption; |
| 4 | -export declare const pageScrollMixin: (scroller: Scroller) => string; | 4 | +type Scroller = (this: WechatMiniprogram.Component.TrivialInstance, event?: IPageScrollOption) => void; |
| 5 | +export declare function pageScrollMixin(scroller: Scroller): string; | ||
| 5 | export {}; | 6 | export {}; | ... | ... |
| 1 | +import { isFunction } from '../common/validator'; | ||
| 1 | import { getCurrentPage, isDef } from '../common/utils'; | 2 | import { getCurrentPage, isDef } from '../common/utils'; |
| 2 | function onPageScroll(event) { | 3 | function onPageScroll(event) { |
| 3 | const { vanPageScroller = [] } = getCurrentPage(); | 4 | const { vanPageScroller = [] } = getCurrentPage(); |
| ... | @@ -8,29 +9,34 @@ function onPageScroll(event) { | ... | @@ -8,29 +9,34 @@ function onPageScroll(event) { |
| 8 | } | 9 | } |
| 9 | }); | 10 | }); |
| 10 | } | 11 | } |
| 11 | -export const pageScrollMixin = (scroller) => Behavior({ | 12 | +export function pageScrollMixin(scroller) { |
| 13 | + return Behavior({ | ||
| 12 | attached() { | 14 | attached() { |
| 13 | const page = getCurrentPage(); | 15 | const page = getCurrentPage(); |
| 14 | if (!isDef(page)) { | 16 | if (!isDef(page)) { |
| 15 | return; | 17 | return; |
| 16 | } | 18 | } |
| 17 | - if (Array.isArray(page.vanPageScroller)) { | 19 | + const _scroller = scroller.bind(this); |
| 18 | - page.vanPageScroller.push(scroller.bind(this)); | 20 | + const { vanPageScroller = [] } = page; |
| 19 | - } | 21 | + if (isFunction(page.onPageScroll) && page.onPageScroll !== onPageScroll) { |
| 20 | - else { | 22 | + vanPageScroller.push(page.onPageScroll.bind(page)); |
| 21 | - page.vanPageScroller = | ||
| 22 | - typeof page.onPageScroll === 'function' | ||
| 23 | - ? [page.onPageScroll.bind(page), scroller.bind(this)] | ||
| 24 | - : [scroller.bind(this)]; | ||
| 25 | } | 23 | } |
| 24 | + vanPageScroller.push(_scroller); | ||
| 25 | + page.vanPageScroller = vanPageScroller; | ||
| 26 | page.onPageScroll = onPageScroll; | 26 | page.onPageScroll = onPageScroll; |
| 27 | + this._scroller = _scroller; | ||
| 27 | }, | 28 | }, |
| 28 | detached() { | 29 | detached() { |
| 29 | - var _a; | ||
| 30 | const page = getCurrentPage(); | 30 | const page = getCurrentPage(); |
| 31 | - if (isDef(page)) { | 31 | + if (!isDef(page) || !isDef(page.vanPageScroller)) { |
| 32 | - page.vanPageScroller = | 32 | + return; |
| 33 | - ((_a = page.vanPageScroller) === null || _a === void 0 ? void 0 : _a.filter((item) => item !== scroller)) || []; | 33 | + } |
| 34 | + const { vanPageScroller } = page; | ||
| 35 | + const index = vanPageScroller.findIndex((v) => v === this._scroller); | ||
| 36 | + if (index > -1) { | ||
| 37 | + page.vanPageScroller.splice(index, 1); | ||
| 34 | } | 38 | } |
| 39 | + this._scroller = undefined; | ||
| 35 | }, | 40 | }, |
| 36 | -}); | 41 | + }); |
| 42 | +} | ... | ... |
| ... | @@ -21,7 +21,6 @@ export function transition(showDefaultValue) { | ... | @@ -21,7 +21,6 @@ export function transition(showDefaultValue) { |
| 21 | duration: { | 21 | duration: { |
| 22 | type: null, | 22 | type: null, |
| 23 | value: 300, | 23 | value: 300, |
| 24 | - observer: 'observeDuration', | ||
| 25 | }, | 24 | }, |
| 26 | name: { | 25 | name: { |
| 27 | type: String, | 26 | type: String, |
| ... | @@ -43,12 +42,30 @@ export function transition(showDefaultValue) { | ... | @@ -43,12 +42,30 @@ export function transition(showDefaultValue) { |
| 43 | if (value === old) { | 42 | if (value === old) { |
| 44 | return; | 43 | return; |
| 45 | } | 44 | } |
| 46 | - value ? this.enter() : this.leave(); | 45 | + value ? this.enureEnter() : this.enureLeave(); |
| 47 | }, | 46 | }, |
| 48 | - enter() { | 47 | + enureEnter() { |
| 48 | + if (this.enterPromise) | ||
| 49 | + return; | ||
| 50 | + this.enterPromise = new Promise((resolve) => this.enter(resolve)); | ||
| 51 | + }, | ||
| 52 | + enureLeave() { | ||
| 53 | + const { enterPromise } = this; | ||
| 54 | + if (!enterPromise) | ||
| 55 | + return; | ||
| 56 | + enterPromise | ||
| 57 | + .then(() => new Promise((resolve) => this.leave(resolve))) | ||
| 58 | + .then(() => { | ||
| 59 | + this.enterPromise = null; | ||
| 60 | + }); | ||
| 61 | + }, | ||
| 62 | + enter(resolve) { | ||
| 49 | const { duration, name } = this.data; | 63 | const { duration, name } = this.data; |
| 50 | const classNames = getClassNames(name); | 64 | const classNames = getClassNames(name); |
| 51 | const currentDuration = isObj(duration) ? duration.enter : duration; | 65 | const currentDuration = isObj(duration) ? duration.enter : duration; |
| 66 | + if (this.status === 'enter') { | ||
| 67 | + return; | ||
| 68 | + } | ||
| 52 | this.status = 'enter'; | 69 | this.status = 'enter'; |
| 53 | this.$emit('before-enter'); | 70 | this.$emit('before-enter'); |
| 54 | requestAnimationFrame(() => { | 71 | requestAnimationFrame(() => { |
| ... | @@ -68,10 +85,11 @@ export function transition(showDefaultValue) { | ... | @@ -68,10 +85,11 @@ export function transition(showDefaultValue) { |
| 68 | } | 85 | } |
| 69 | this.transitionEnded = false; | 86 | this.transitionEnded = false; |
| 70 | this.setData({ classes: classNames['enter-to'] }); | 87 | this.setData({ classes: classNames['enter-to'] }); |
| 88 | + resolve(); | ||
| 71 | }); | 89 | }); |
| 72 | }); | 90 | }); |
| 73 | }, | 91 | }, |
| 74 | - leave() { | 92 | + leave(resolve) { |
| 75 | if (!this.data.display) { | 93 | if (!this.data.display) { |
| 76 | return; | 94 | return; |
| 77 | } | 95 | } |
| ... | @@ -94,7 +112,10 @@ export function transition(showDefaultValue) { | ... | @@ -94,7 +112,10 @@ export function transition(showDefaultValue) { |
| 94 | return; | 112 | return; |
| 95 | } | 113 | } |
| 96 | this.transitionEnded = false; | 114 | this.transitionEnded = false; |
| 97 | - setTimeout(() => this.onTransitionEnd(), currentDuration); | 115 | + setTimeout(() => { |
| 116 | + this.onTransitionEnd(); | ||
| 117 | + resolve(); | ||
| 118 | + }, currentDuration); | ||
| 98 | this.setData({ classes: classNames['leave-to'] }); | 119 | this.setData({ classes: classNames['leave-to'] }); |
| 99 | }); | 120 | }); |
| 100 | }); | 121 | }); | ... | ... |
| 1 | -@import '../common/index.wxss';.van-nav-bar{background-color:var(--nav-bar-background-color,#fff);height:var(--nav-bar-height,46px);line-height:var(--nav-bar-height,46px);position:relative;text-align:center;-webkit-user-select:none;user-select:none}.van-nav-bar__content{height:100%;position:relative}.van-nav-bar__text{color:var(--nav-bar-text-color,#1989fa);display:inline-block;margin:0 calc(var(--padding-md, 16px)*-1);padding:0 var(--padding-md,16px);vertical-align:middle}.van-nav-bar__text--hover{background-color:#f2f3f5}.van-nav-bar__arrow{color:var(--nav-bar-icon-color,#1989fa)!important;font-size:var(--nav-bar-arrow-size,16px)!important;vertical-align:middle}.van-nav-bar__arrow+.van-nav-bar__text{margin-left:-20px;padding-left:25px}.van-nav-bar--fixed{left:0;position:fixed;top:0;width:100%}.van-nav-bar__title{color:var(--nav-bar-title-text-color,#323233);font-size:var(--nav-bar-title-font-size,16px);font-weight:var(--font-weight-bold,500);margin:0 auto;max-width:60%}.van-nav-bar__left,.van-nav-bar__right{align-items:center;bottom:0;display:flex;font-size:var(--font-size-md,14px);position:absolute;top:0}.van-nav-bar__left{left:var(--padding-md,16px)}.van-nav-bar__right{right:var(--padding-md,16px)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-nav-bar{background-color:var(--nav-bar-background-color,#fff);box-sizing:initial;height:var(--nav-bar-height,46px);line-height:var(--nav-bar-height,46px);position:relative;text-align:center;-webkit-user-select:none;user-select:none}.van-nav-bar__content{height:100%;position:relative}.van-nav-bar__text{color:var(--nav-bar-text-color,#1989fa);display:inline-block;margin:0 calc(var(--padding-md, 16px)*-1);padding:0 var(--padding-md,16px);vertical-align:middle}.van-nav-bar__text--hover{background-color:#f2f3f5}.van-nav-bar__arrow{color:var(--nav-bar-icon-color,#1989fa)!important;font-size:var(--nav-bar-arrow-size,16px)!important;vertical-align:middle}.van-nav-bar__arrow+.van-nav-bar__text{margin-left:-20px;padding-left:25px}.van-nav-bar--fixed{left:0;position:fixed;top:0;width:100%}.van-nav-bar__title{color:var(--nav-bar-title-text-color,#323233);font-size:var(--nav-bar-title-font-size,16px);font-weight:var(--font-weight-bold,500);margin:0 auto;max-width:60%}.van-nav-bar__left,.van-nav-bar__right{align-items:center;bottom:0;display:flex;font-size:var(--font-size-md,14px);position:absolute;top:0}.van-nav-bar__left{left:var(--padding-md,16px)}.van-nav-bar__right{right:var(--padding-md,16px)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -61,7 +61,7 @@ VantComponent({ | ... | @@ -61,7 +61,7 @@ VantComponent({ |
| 61 | getRect(this, '.van-notice-bar__wrap'), | 61 | getRect(this, '.van-notice-bar__wrap'), |
| 62 | ]).then((rects) => { | 62 | ]).then((rects) => { |
| 63 | const [contentRect, wrapRect] = rects; | 63 | const [contentRect, wrapRect] = rects; |
| 64 | - const { speed, scrollable, delay } = this.data; | 64 | + const { scrollable } = this.data; |
| 65 | if (contentRect == null || | 65 | if (contentRect == null || |
| 66 | wrapRect == null || | 66 | wrapRect == null || |
| 67 | !contentRect.width || | 67 | !contentRect.width || |
| ... | @@ -70,20 +70,26 @@ VantComponent({ | ... | @@ -70,20 +70,26 @@ VantComponent({ |
| 70 | return; | 70 | return; |
| 71 | } | 71 | } |
| 72 | if (scrollable || wrapRect.width < contentRect.width) { | 72 | if (scrollable || wrapRect.width < contentRect.width) { |
| 73 | - const duration = ((wrapRect.width + contentRect.width) / speed) * 1000; | 73 | + this.initAnimation(wrapRect.width, contentRect.width); |
| 74 | - this.wrapWidth = wrapRect.width; | ||
| 75 | - this.contentWidth = contentRect.width; | ||
| 76 | - this.duration = duration; | ||
| 77 | - this.animation = wx.createAnimation({ | ||
| 78 | - duration, | ||
| 79 | - timingFunction: 'linear', | ||
| 80 | - delay, | ||
| 81 | - }); | ||
| 82 | this.scroll(true); | 74 | this.scroll(true); |
| 83 | } | 75 | } |
| 84 | }); | 76 | }); |
| 85 | }); | 77 | }); |
| 86 | }, | 78 | }, |
| 79 | + initAnimation(warpWidth, contentWidth) { | ||
| 80 | + const { speed, delay } = this.data; | ||
| 81 | + this.wrapWidth = warpWidth; | ||
| 82 | + this.contentWidth = contentWidth; | ||
| 83 | + // begin 0 | ||
| 84 | + this.contentDuration = (contentWidth / speed) * 1000; | ||
| 85 | + // begin -wrapWidth | ||
| 86 | + this.duration = ((warpWidth + contentWidth) / speed) * 1000; | ||
| 87 | + this.animation = wx.createAnimation({ | ||
| 88 | + duration: this.contentDuration, | ||
| 89 | + timingFunction: 'linear', | ||
| 90 | + delay, | ||
| 91 | + }); | ||
| 92 | + }, | ||
| 87 | scroll(isInit = false) { | 93 | scroll(isInit = false) { |
| 88 | this.timer && clearTimeout(this.timer); | 94 | this.timer && clearTimeout(this.timer); |
| 89 | this.timer = null; | 95 | this.timer = null; |
| ... | @@ -93,17 +99,18 @@ VantComponent({ | ... | @@ -93,17 +99,18 @@ VantComponent({ |
| 93 | .step() | 99 | .step() |
| 94 | .export(), | 100 | .export(), |
| 95 | }); | 101 | }); |
| 102 | + const duration = isInit ? this.contentDuration : this.duration; | ||
| 96 | requestAnimationFrame(() => { | 103 | requestAnimationFrame(() => { |
| 97 | this.setData({ | 104 | this.setData({ |
| 98 | animationData: this.animation | 105 | animationData: this.animation |
| 99 | .translateX(-this.contentWidth) | 106 | .translateX(-this.contentWidth) |
| 100 | - .step() | 107 | + .step({ duration }) |
| 101 | .export(), | 108 | .export(), |
| 102 | }); | 109 | }); |
| 103 | }); | 110 | }); |
| 104 | this.timer = setTimeout(() => { | 111 | this.timer = setTimeout(() => { |
| 105 | this.scroll(); | 112 | this.scroll(); |
| 106 | - }, this.duration); | 113 | + }, duration + this.data.delay); |
| 107 | }, | 114 | }, |
| 108 | onClickIcon(event) { | 115 | onClickIcon(event) { |
| 109 | if (this.data.mode === 'closeable') { | 116 | if (this.data.mode === 'closeable') { | ... | ... |
| ... | @@ -16,5 +16,7 @@ interface NotifyOptions { | ... | @@ -16,5 +16,7 @@ interface NotifyOptions { |
| 16 | declare function Notify(options: NotifyOptions | string): any; | 16 | declare function Notify(options: NotifyOptions | string): any; |
| 17 | declare namespace Notify { | 17 | declare namespace Notify { |
| 18 | var clear: (options?: NotifyOptions | undefined) => void; | 18 | var clear: (options?: NotifyOptions | undefined) => void; |
| 19 | + var setDefaultOptions: (options: NotifyOptions) => void; | ||
| 20 | + var resetDefaultOptions: () => void; | ||
| 19 | } | 21 | } |
| 20 | export default Notify; | 22 | export default Notify; | ... | ... |
| ... | @@ -13,6 +13,7 @@ const defaultOptions = { | ... | @@ -13,6 +13,7 @@ const defaultOptions = { |
| 13 | onOpened: () => { }, | 13 | onOpened: () => { }, |
| 14 | onClose: () => { }, | 14 | onClose: () => { }, |
| 15 | }; | 15 | }; |
| 16 | +let currentOptions = Object.assign({}, defaultOptions); | ||
| 16 | function parseOptions(message) { | 17 | function parseOptions(message) { |
| 17 | if (message == null) { | 18 | if (message == null) { |
| 18 | return {}; | 19 | return {}; |
| ... | @@ -24,7 +25,7 @@ function getContext() { | ... | @@ -24,7 +25,7 @@ function getContext() { |
| 24 | return pages[pages.length - 1]; | 25 | return pages[pages.length - 1]; |
| 25 | } | 26 | } |
| 26 | export default function Notify(options) { | 27 | export default function Notify(options) { |
| 27 | - options = Object.assign(Object.assign({}, defaultOptions), parseOptions(options)); | 28 | + options = Object.assign(Object.assign({}, currentOptions), parseOptions(options)); |
| 28 | const context = options.context || getContext(); | 29 | const context = options.context || getContext(); |
| 29 | const notify = context.selectComponent(options.selector); | 30 | const notify = context.selectComponent(options.selector); |
| 30 | delete options.context; | 31 | delete options.context; |
| ... | @@ -44,3 +45,9 @@ Notify.clear = function (options) { | ... | @@ -44,3 +45,9 @@ Notify.clear = function (options) { |
| 44 | notify.hide(); | 45 | notify.hide(); |
| 45 | } | 46 | } |
| 46 | }; | 47 | }; |
| 48 | +Notify.setDefaultOptions = (options) => { | ||
| 49 | + Object.assign(currentOptions, options); | ||
| 50 | +}; | ||
| 51 | +Notify.resetDefaultOptions = () => { | ||
| 52 | + currentOptions = Object.assign({}, defaultOptions); | ||
| 53 | +}; | ... | ... |
| 1 | -<van-transition | 1 | +<import src="./overlay.wxml" /> |
| 2 | - wx:if="{{ lockScroll }}" | 2 | + |
| 3 | - show="{{ show }}" | 3 | +<root-portal wx:if="{{ rootPortal }}"> |
| 4 | - custom-class="van-overlay" | 4 | + <include src="./overlay.wxml" /> |
| 5 | - custom-style="z-index: {{ zIndex }}; {{ customStyle }}" | 5 | +</root-portal> |
| 6 | - duration="{{ duration }}" | 6 | + |
| 7 | - bind:tap="onClick" | 7 | +<include wx:else src="./overlay.wxml" /> |
| 8 | - catch:touchmove="noop" | ||
| 9 | -> | ||
| 10 | - <slot></slot> | ||
| 11 | -</van-transition> | ||
| 12 | -<van-transition | ||
| 13 | - wx:else | ||
| 14 | - show="{{ show }}" | ||
| 15 | - custom-class="van-overlay" | ||
| 16 | - custom-style="z-index: {{ zIndex }}; {{ customStyle }}" | ||
| 17 | - duration="{{ duration }}" | ||
| 18 | - bind:tap="onClick" | ||
| 19 | -> | ||
| 20 | - <slot></slot> | ||
| 21 | -</van-transition> | ... | ... |
| 1 | +<van-transition | ||
| 2 | + show="{{ show }}" | ||
| 3 | + custom-class="van-overlay custom-class" | ||
| 4 | + custom-style="z-index: {{ zIndex }}; {{ customStyle }}" | ||
| 5 | + duration="{{ duration }}" | ||
| 6 | + bind:tap="onClick" | ||
| 7 | + catch:touchmove="{{ lockScroll ? 'noop' : ''}}" | ||
| 8 | +> | ||
| 9 | + <slot></slot> | ||
| 10 | +</van-transition> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -53,10 +53,18 @@ VantComponent({ | ... | @@ -53,10 +53,18 @@ VantComponent({ |
| 53 | type: Boolean, | 53 | type: Boolean, |
| 54 | value: false, | 54 | value: false, |
| 55 | }, | 55 | }, |
| 56 | + safeAreaTabBar: { | ||
| 57 | + type: Boolean, | ||
| 58 | + value: false, | ||
| 59 | + }, | ||
| 56 | lockScroll: { | 60 | lockScroll: { |
| 57 | type: Boolean, | 61 | type: Boolean, |
| 58 | value: true, | 62 | value: true, |
| 59 | }, | 63 | }, |
| 64 | + rootPortal: { | ||
| 65 | + type: Boolean, | ||
| 66 | + value: false, | ||
| 67 | + }, | ||
| 60 | }, | 68 | }, |
| 61 | created() { | 69 | created() { |
| 62 | this.observeClass(); | 70 | this.observeClass(); | ... | ... |
| 1 | <wxs src="../wxs/utils.wxs" module="utils" /> | 1 | <wxs src="../wxs/utils.wxs" module="utils" /> |
| 2 | <wxs src="./index.wxs" module="computed" /> | 2 | <wxs src="./index.wxs" module="computed" /> |
| 3 | 3 | ||
| 4 | +<import src="./popup.wxml" /> | ||
| 5 | + | ||
| 4 | <van-overlay | 6 | <van-overlay |
| 5 | wx:if="{{ overlay }}" | 7 | wx:if="{{ overlay }}" |
| 6 | show="{{ show }}" | 8 | show="{{ show }}" |
| ... | @@ -9,18 +11,11 @@ | ... | @@ -9,18 +11,11 @@ |
| 9 | duration="{{ duration }}" | 11 | duration="{{ duration }}" |
| 10 | bind:click="onClickOverlay" | 12 | bind:click="onClickOverlay" |
| 11 | lock-scroll="{{ lockScroll }}" | 13 | lock-scroll="{{ lockScroll }}" |
| 14 | + root-portal="{{ rootPortal }}" | ||
| 12 | /> | 15 | /> |
| 13 | -<view | 16 | + |
| 14 | - wx:if="{{ inited }}" | 17 | +<root-portal wx:if="{{ rootPortal }}"> |
| 15 | - class="custom-class {{ classes }} {{ utils.bem('popup', [position, { round, safe: safeAreaInsetBottom, safeTop: safeAreaInsetTop }]) }}" | 18 | + <include src="./popup.wxml" /> |
| 16 | - style="{{ computed.popupStyle({ zIndex, currentDuration, display, customStyle }) }}" | 19 | +</root-portal> |
| 17 | - bind:transitionend="onTransitionEnd" | 20 | + |
| 18 | -> | 21 | + <include wx:else src="./popup.wxml" /> |
| 19 | - <slot /> | ||
| 20 | - <van-icon | ||
| 21 | - wx:if="{{ closeable }}" | ||
| 22 | - name="{{ closeIcon }}" | ||
| 23 | - class="close-icon-class van-popup__close-icon van-popup__close-icon--{{ closeIconPosition }}" | ||
| 24 | - bind:tap="onClickCloseIcon" | ||
| 25 | - /> | ||
| 26 | -</view> | ... | ... |
| 1 | -@import '../common/index.wxss';.van-popup{-webkit-overflow-scrolling:touch;animation:ease both;background-color:var(--popup-background-color,#fff);box-sizing:border-box;max-height:100%;overflow-y:auto;position:fixed;transition-timing-function:ease}.van-popup--center{left:50%;top:50%;transform:translate3d(-50%,-50%,0)}.van-popup--center.van-popup--round{border-radius:var(--popup-round-border-radius,16px)}.van-popup--top{left:0;top:0;width:100%}.van-popup--top.van-popup--round{border-radius:0 0 var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) var(--popup-round-border-radius,var(--popup-round-border-radius,16px))}.van-popup--right{right:0;top:50%;transform:translate3d(0,-50%,0)}.van-popup--right.van-popup--round{border-radius:var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) 0 0 var(--popup-round-border-radius,var(--popup-round-border-radius,16px))}.van-popup--bottom{bottom:0;left:0;width:100%}.van-popup--bottom.van-popup--round{border-radius:var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) 0 0}.van-popup--left{left:0;top:50%;transform:translate3d(0,-50%,0)}.van-popup--left.van-popup--round{border-radius:0 var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) 0}.van-popup--bottom.van-popup--safe{padding-bottom:env(safe-area-inset-bottom)}.van-popup--safeTop{padding-top:env(safe-area-inset-top)}.van-popup__close-icon{color:var(--popup-close-icon-color,#969799);font-size:var(--popup-close-icon-size,18px);position:absolute;z-index:var(--popup-close-icon-z-index,1)}.van-popup__close-icon--top-left{left:var(--popup-close-icon-margin,16px);top:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--top-right{right:var(--popup-close-icon-margin,16px);top:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--bottom-left{bottom:var(--popup-close-icon-margin,16px);left:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--bottom-right{bottom:var(--popup-close-icon-margin,16px);right:var(--popup-close-icon-margin,16px)}.van-popup__close-icon:active{opacity:.6}.van-scale-enter-active,.van-scale-leave-active{transition-property:opacity,transform}.van-scale-enter,.van-scale-leave-to{opacity:0;transform:translate3d(-50%,-50%,0) scale(.7)}.van-fade-enter-active,.van-fade-leave-active{transition-property:opacity}.van-fade-enter,.van-fade-leave-to{opacity:0}.van-center-enter-active,.van-center-leave-active{transition-property:opacity}.van-center-enter,.van-center-leave-to{opacity:0}.van-bottom-enter-active,.van-bottom-leave-active,.van-left-enter-active,.van-left-leave-active,.van-right-enter-active,.van-right-leave-active,.van-top-enter-active,.van-top-leave-active{transition-property:transform}.van-bottom-enter,.van-bottom-leave-to{transform:translate3d(0,100%,0)}.van-top-enter,.van-top-leave-to{transform:translate3d(0,-100%,0)}.van-left-enter,.van-left-leave-to{transform:translate3d(-100%,-50%,0)}.van-right-enter,.van-right-leave-to{transform:translate3d(100%,-50%,0)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-popup{-webkit-overflow-scrolling:touch;animation:ease both;background-color:var(--popup-background-color,#fff);box-sizing:border-box;max-height:100%;overflow-y:auto;position:fixed;transition-timing-function:ease}.van-popup--center{left:50%;top:50%;transform:translate3d(-50%,-50%,0)}.van-popup--center.van-popup--round{border-radius:var(--popup-round-border-radius,16px)}.van-popup--top{left:0;top:0;width:100%}.van-popup--top.van-popup--round{border-radius:0 0 var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) var(--popup-round-border-radius,var(--popup-round-border-radius,16px))}.van-popup--right{right:0;top:50%;transform:translate3d(0,-50%,0)}.van-popup--right.van-popup--round{border-radius:var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) 0 0 var(--popup-round-border-radius,var(--popup-round-border-radius,16px))}.van-popup--bottom{bottom:0;left:0;width:100%}.van-popup--bottom.van-popup--round{border-radius:var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) 0 0}.van-popup--left{left:0;top:50%;transform:translate3d(0,-50%,0)}.van-popup--left.van-popup--round{border-radius:0 var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) var(--popup-round-border-radius,var(--popup-round-border-radius,16px)) 0}.van-popup--bottom.van-popup--safe{padding-bottom:env(safe-area-inset-bottom)}.van-popup--bottom.van-popup--safeTabBar,.van-popup--top.van-popup--safeTabBar{bottom:var(--tabbar-height,50px)}.van-popup--safeTop{padding-top:env(safe-area-inset-top)}.van-popup__close-icon{color:var(--popup-close-icon-color,#969799);font-size:var(--popup-close-icon-size,18px);position:absolute;z-index:var(--popup-close-icon-z-index,1)}.van-popup__close-icon--top-left{left:var(--popup-close-icon-margin,16px);top:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--top-right{right:var(--popup-close-icon-margin,16px);top:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--bottom-left{bottom:var(--popup-close-icon-margin,16px);left:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--bottom-right{bottom:var(--popup-close-icon-margin,16px);right:var(--popup-close-icon-margin,16px)}.van-popup__close-icon:active{opacity:.6}.van-scale-enter-active,.van-scale-leave-active{transition-property:opacity,transform}.van-scale-enter,.van-scale-leave-to{opacity:0;transform:translate3d(-50%,-50%,0) scale(.7)}.van-fade-enter-active,.van-fade-leave-active{transition-property:opacity}.van-fade-enter,.van-fade-leave-to{opacity:0}.van-center-enter-active,.van-center-leave-active{transition-property:opacity}.van-center-enter,.van-center-leave-to{opacity:0}.van-bottom-enter-active,.van-bottom-leave-active,.van-left-enter-active,.van-left-leave-active,.van-right-enter-active,.van-right-leave-active,.van-top-enter-active,.van-top-leave-active{transition-property:transform}.van-bottom-enter,.van-bottom-leave-to{transform:translate3d(0,100%,0)}.van-top-enter,.van-top-leave-to{transform:translate3d(0,-100%,0)}.van-left-enter,.van-left-leave-to{transform:translate3d(-100%,-50%,0)}.van-right-enter,.van-right-leave-to{transform:translate3d(100%,-50%,0)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
src/components/vant-weapp/popup/popup.wxml
0 → 100644
| 1 | +<wxs src="../wxs/utils.wxs" module="utils" /> | ||
| 2 | +<wxs src="./index.wxs" module="computed" /> | ||
| 3 | +<view | ||
| 4 | + wx:if="{{ inited }}" | ||
| 5 | + class="custom-class {{ classes }} {{ utils.bem('popup', [position, { round, safe: safeAreaInsetBottom, safeTop: safeAreaInsetTop, safeTabBar: safeAreaTabBar }]) }}" | ||
| 6 | + style="{{ computed.popupStyle({ zIndex, currentDuration, display, customStyle }) }}" | ||
| 7 | + bind:transitionend="onTransitionEnd" | ||
| 8 | +> | ||
| 9 | + <slot /> | ||
| 10 | + <van-icon | ||
| 11 | + wx:if="{{ closeable }}" | ||
| 12 | + name="{{ closeIcon }}" | ||
| 13 | + class="close-icon-class van-popup__close-icon van-popup__close-icon--{{ closeIconPosition }}" | ||
| 14 | + bind:tap="onClickCloseIcon" | ||
| 15 | + /> | ||
| 16 | +</view> |
| 1 | -@import '../common/index.wxss';.van-rate{display:inline-flex;-webkit-user-select:none;user-select:none}.van-rate__item{padding:0 var(--rate-horizontal-padding,2px);position:relative}.van-rate__item:not(:last-child){padding-right:var(--rate-icon-gutter,4px)}.van-rate__icon{color:var(--rate-icon-void-color,#c8c9cc);display:block;font-size:var(--rate-icon-size,20px);height:1em}.van-rate__icon--half{left:var(--rate-horizontal-padding,2px);overflow:hidden;position:absolute;top:0;width:.5em}.van-rate__icon--full,.van-rate__icon--half{color:var(--rate-icon-full-color,#ee0a24)}.van-rate__icon--disabled{color:var(--rate-icon-disabled-color,#c8c9cc)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-rate{display:inline-flex;-webkit-user-select:none;user-select:none}.van-rate__item{padding:0 var(--rate-horizontal-padding,2px);position:relative}.van-rate__item:not(:last-child){padding-right:var(--rate-icon-gutter,4px)}.van-rate__icon{color:var(--rate-icon-void-color,#c8c9cc);display:block;font-size:var(--rate-icon-size,20px);height:100%}.van-rate__icon--half{left:var(--rate-horizontal-padding,2px);overflow:hidden;position:absolute;top:0;width:.5em}.van-rate__icon--full,.van-rate__icon--half{color:var(--rate-icon-full-color,#ee0a24)}.van-rate__icon--disabled{color:var(--rate-icon-disabled-color,#c8c9cc)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -4,6 +4,10 @@ VantComponent({ | ... | @@ -4,6 +4,10 @@ VantComponent({ |
| 4 | field: true, | 4 | field: true, |
| 5 | classes: ['field-class', 'input-class', 'cancel-class'], | 5 | classes: ['field-class', 'input-class', 'cancel-class'], |
| 6 | props: { | 6 | props: { |
| 7 | + value: { | ||
| 8 | + type: String, | ||
| 9 | + value: '', | ||
| 10 | + }, | ||
| 7 | label: String, | 11 | label: String, |
| 8 | focus: Boolean, | 12 | focus: Boolean, |
| 9 | error: Boolean, | 13 | error: Boolean, |
| ... | @@ -49,6 +53,10 @@ VantComponent({ | ... | @@ -49,6 +53,10 @@ VantComponent({ |
| 49 | type: String, | 53 | type: String, |
| 50 | value: 'clear', | 54 | value: 'clear', |
| 51 | }, | 55 | }, |
| 56 | + cursorSpacing: { | ||
| 57 | + type: Number, | ||
| 58 | + value: 0, | ||
| 59 | + }, | ||
| 52 | }, | 60 | }, |
| 53 | methods: { | 61 | methods: { |
| 54 | onChange(event) { | 62 | onChange(event) { |
| ... | @@ -60,7 +68,7 @@ VantComponent({ | ... | @@ -60,7 +68,7 @@ VantComponent({ |
| 60 | onCancel() { | 68 | onCancel() { |
| 61 | /** | 69 | /** |
| 62 | * 修复修改输入框值时,输入框失焦和赋值同时触发,赋值失效 | 70 | * 修复修改输入框值时,输入框失焦和赋值同时触发,赋值失效 |
| 63 | - * https://github.com/youzan/@vant/weapp/issues/1768 | 71 | + * https://github.com/youzan/vant-weapp/issues/1768 |
| 64 | */ | 72 | */ |
| 65 | setTimeout(() => { | 73 | setTimeout(() => { |
| 66 | if (canIUseModel()) { | 74 | if (canIUseModel()) { | ... | ... |
| ... | @@ -28,6 +28,7 @@ | ... | @@ -28,6 +28,7 @@ |
| 28 | input-class="input-class" | 28 | input-class="input-class" |
| 29 | placeholder="{{ placeholder }}" | 29 | placeholder="{{ placeholder }}" |
| 30 | placeholder-style="{{ placeholderStyle }}" | 30 | placeholder-style="{{ placeholderStyle }}" |
| 31 | + cursor-spacing="{{ cursorSpacing }}" | ||
| 31 | custom-style="padding: 5px 10px 5px 0; background-color: transparent;" | 32 | custom-style="padding: 5px 10px 5px 0; background-color: transparent;" |
| 32 | bind:blur="onBlur" | 33 | bind:blur="onBlur" |
| 33 | bind:focus="onFocus" | 34 | bind:focus="onFocus" |
| ... | @@ -48,6 +49,6 @@ | ... | @@ -48,6 +49,6 @@ |
| 48 | hover-stay-time="70" | 49 | hover-stay-time="70" |
| 49 | > | 50 | > |
| 50 | <slot wx:if="{{ useActionSlot }}" name="action" /> | 51 | <slot wx:if="{{ useActionSlot }}" name="action" /> |
| 51 | - <view wx:else bind:tap="onCancel" class="cancel-class">{{ actionText }}</view> | 52 | + <view wx:else bind:tap="onCancel" class="van-search__action-button cancel-class">{{ actionText }}</view> |
| 52 | </view> | 53 | </view> |
| 53 | </view> | 54 | </view> | ... | ... |
| 1 | -@import '../common/index.wxss';.van-search{align-items:center;box-sizing:border-box;display:flex;padding:var(--search-padding,10px 12px)}.van-search__content{background-color:var(--search-background-color,#f7f8fa);border-radius:2px;display:flex;flex:1;padding-left:var(--padding-sm,12px)}.van-search__content--round{border-radius:999px}.van-search__label{color:var(--search-label-color,#323233);font-size:var(--search-label-font-size,14px);line-height:var(--search-input-height,34px);padding:var(--search-label-padding,0 5px)}.van-search__field{flex:1}.van-search__field__left-icon{color:var(--search-left-icon-color,#969799)}.van-search--withaction{padding-right:0}.van-search__action{color:var(--search-action-text-color,#323233);font-size:var(--search-action-font-size,14px);line-height:var(--search-input-height,34px);padding:var(--search-action-padding,0 8px)}.van-search__action--hover{background-color:#f2f3f5} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-search{align-items:center;box-sizing:border-box;display:flex;padding:var(--search-padding,10px 12px)}.van-search__content{background-color:var(--search-background-color,#f7f8fa);border-radius:2px;display:flex;flex:1;padding-left:var(--padding-sm,12px)}.van-search__content--round{border-radius:999px}.van-search__label{color:var(--search-label-color,#323233);font-size:var(--search-label-font-size,14px);line-height:var(--search-input-height,34px);padding:var(--search-label-padding,0 5px)}.van-search__field{flex:1}.van-search__field__left-icon{color:var(--search-left-icon-color,#969799)}.van-search--withaction{padding-right:0}.van-search__action{color:var(--search-action-text-color,#323233);font-size:var(--search-action-font-size,14px);line-height:var(--search-input-height,34px)}.van-search__action--hover{background-color:#f2f3f5}.van-search__action-button{padding:var(--search-action-padding,0 8px)} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -36,6 +36,10 @@ VantComponent({ | ... | @@ -36,6 +36,10 @@ VantComponent({ |
| 36 | type: null, | 36 | type: null, |
| 37 | value: 300, | 37 | value: 300, |
| 38 | }, | 38 | }, |
| 39 | + rootPortal: { | ||
| 40 | + type: Boolean, | ||
| 41 | + value: false, | ||
| 42 | + }, | ||
| 39 | }, | 43 | }, |
| 40 | methods: { | 44 | methods: { |
| 41 | onClickOverlay() { | 45 | onClickOverlay() { | ... | ... |
| ... | @@ -11,6 +11,7 @@ | ... | @@ -11,6 +11,7 @@ |
| 11 | overlay-style="{{ overlayStyle }}" | 11 | overlay-style="{{ overlayStyle }}" |
| 12 | close-on-click-overlay="{{ closeOnClickOverlay }}" | 12 | close-on-click-overlay="{{ closeOnClickOverlay }}" |
| 13 | safe-area-inset-bottom="{{ safeAreaInsetBottom }}" | 13 | safe-area-inset-bottom="{{ safeAreaInsetBottom }}" |
| 14 | + root-portal="{{ rootPortal }}" | ||
| 14 | bind:close="onClose" | 15 | bind:close="onClose" |
| 15 | bind:click-overlay="onClickOverlay" | 16 | bind:click-overlay="onClickOverlay" |
| 16 | > | 17 | > | ... | ... |
| 1 | import { VantComponent } from '../common/component'; | 1 | import { VantComponent } from '../common/component'; |
| 2 | import { touch } from '../mixins/touch'; | 2 | import { touch } from '../mixins/touch'; |
| 3 | import { canIUseModel } from '../common/version'; | 3 | import { canIUseModel } from '../common/version'; |
| 4 | -import { getRect, addUnit } from '../common/utils'; | 4 | +import { getRect, addUnit, nextTick, addNumber, clamp } from '../common/utils'; |
| 5 | +const DRAG_STATUS = { | ||
| 6 | + START: 'start', | ||
| 7 | + MOVING: 'moving', | ||
| 8 | + END: 'end', | ||
| 9 | +}; | ||
| 5 | VantComponent({ | 10 | VantComponent({ |
| 6 | mixins: [touch], | 11 | mixins: [touch], |
| 7 | props: { | 12 | props: { |
| ... | @@ -54,16 +59,16 @@ VantComponent({ | ... | @@ -54,16 +59,16 @@ VantComponent({ |
| 54 | else { | 59 | else { |
| 55 | this.startValue = this.format(this.newValue); | 60 | this.startValue = this.format(this.newValue); |
| 56 | } | 61 | } |
| 57 | - this.dragStatus = 'start'; | 62 | + this.dragStatus = DRAG_STATUS.START; |
| 58 | }, | 63 | }, |
| 59 | onTouchMove(event) { | 64 | onTouchMove(event) { |
| 60 | if (this.data.disabled) | 65 | if (this.data.disabled) |
| 61 | return; | 66 | return; |
| 62 | - if (this.dragStatus === 'start') { | 67 | + if (this.dragStatus === DRAG_STATUS.START) { |
| 63 | this.$emit('drag-start'); | 68 | this.$emit('drag-start'); |
| 64 | } | 69 | } |
| 65 | this.touchMove(event); | 70 | this.touchMove(event); |
| 66 | - this.dragStatus = 'draging'; | 71 | + this.dragStatus = DRAG_STATUS.MOVING; |
| 67 | getRect(this, '.van-slider').then((rect) => { | 72 | getRect(this, '.van-slider').then((rect) => { |
| 68 | const { vertical } = this.data; | 73 | const { vertical } = this.data; |
| 69 | const delta = vertical ? this.deltaY : this.deltaX; | 74 | const delta = vertical ? this.deltaY : this.deltaX; |
| ... | @@ -82,9 +87,12 @@ VantComponent({ | ... | @@ -82,9 +87,12 @@ VantComponent({ |
| 82 | onTouchEnd() { | 87 | onTouchEnd() { |
| 83 | if (this.data.disabled) | 88 | if (this.data.disabled) |
| 84 | return; | 89 | return; |
| 85 | - if (this.dragStatus === 'draging') { | 90 | + if (this.dragStatus === DRAG_STATUS.MOVING) { |
| 91 | + this.dragStatus = DRAG_STATUS.END; | ||
| 92 | + nextTick(() => { | ||
| 86 | this.updateValue(this.newValue, true); | 93 | this.updateValue(this.newValue, true); |
| 87 | this.$emit('drag-end'); | 94 | this.$emit('drag-end'); |
| 95 | + }); | ||
| 88 | } | 96 | } |
| 89 | }, | 97 | }, |
| 90 | onClick(event) { | 98 | onClick(event) { |
| ... | @@ -163,15 +171,19 @@ VantComponent({ | ... | @@ -163,15 +171,19 @@ VantComponent({ |
| 163 | const { max, min } = this.data; | 171 | const { max, min } = this.data; |
| 164 | return max - min; | 172 | return max - min; |
| 165 | }, | 173 | }, |
| 174 | + getOffsetWidth(current, min) { | ||
| 175 | + const scope = this.getScope(); | ||
| 176 | + // 避免最小值小于最小step时出现负数情况 | ||
| 177 | + return `${Math.max(((current - min) * 100) / scope, 0)}%`; | ||
| 178 | + }, | ||
| 166 | // 计算选中条的长度百分比 | 179 | // 计算选中条的长度百分比 |
| 167 | calcMainAxis() { | 180 | calcMainAxis() { |
| 168 | const { value } = this; | 181 | const { value } = this; |
| 169 | const { min } = this.data; | 182 | const { min } = this.data; |
| 170 | - const scope = this.getScope(); | ||
| 171 | if (this.isRange(value)) { | 183 | if (this.isRange(value)) { |
| 172 | - return `${((value[1] - value[0]) * 100) / scope}%`; | 184 | + return this.getOffsetWidth(value[1], value[0]); |
| 173 | } | 185 | } |
| 174 | - return `${((value - Number(min)) * 100) / scope}%`; | 186 | + return this.getOffsetWidth(value, Number(min)); |
| 175 | }, | 187 | }, |
| 176 | // 计算选中条的开始位置的偏移量 | 188 | // 计算选中条的开始位置的偏移量 |
| 177 | calcOffset() { | 189 | calcOffset() { |
| ... | @@ -184,8 +196,12 @@ VantComponent({ | ... | @@ -184,8 +196,12 @@ VantComponent({ |
| 184 | return '0%'; | 196 | return '0%'; |
| 185 | }, | 197 | }, |
| 186 | format(value) { | 198 | format(value) { |
| 187 | - const { max, min, step } = this.data; | 199 | + const min = +this.data.min; |
| 188 | - return Math.round(Math.max(min, Math.min(value, max)) / step) * step; | 200 | + const max = +this.data.max; |
| 201 | + const step = +this.data.step; | ||
| 202 | + value = clamp(value, min, max); | ||
| 203 | + const diff = Math.round((value - min) / step) * step; | ||
| 204 | + return addNumber(min, diff); | ||
| 189 | }, | 205 | }, |
| 190 | }, | 206 | }, |
| 191 | }); | 207 | }); | ... | ... |
| ... | @@ -16,7 +16,6 @@ VantComponent({ | ... | @@ -16,7 +16,6 @@ VantComponent({ |
| 16 | props: { | 16 | props: { |
| 17 | value: { | 17 | value: { |
| 18 | type: null, | 18 | type: null, |
| 19 | - observer: 'observeValue', | ||
| 20 | }, | 19 | }, |
| 21 | integer: { | 20 | integer: { |
| 22 | type: Boolean, | 21 | type: Boolean, |
| ... | @@ -66,38 +65,42 @@ VantComponent({ | ... | @@ -66,38 +65,42 @@ VantComponent({ |
| 66 | data: { | 65 | data: { |
| 67 | currentValue: '', | 66 | currentValue: '', |
| 68 | }, | 67 | }, |
| 68 | + watch: { | ||
| 69 | + value() { | ||
| 70 | + this.observeValue(); | ||
| 71 | + }, | ||
| 72 | + }, | ||
| 69 | created() { | 73 | created() { |
| 70 | this.setData({ | 74 | this.setData({ |
| 71 | - currentValue: this.format(this.data.value), | 75 | + currentValue: this.format(this.data.value).newValue, |
| 72 | }); | 76 | }); |
| 73 | }, | 77 | }, |
| 74 | methods: { | 78 | methods: { |
| 75 | observeValue() { | 79 | observeValue() { |
| 76 | - const { value, currentValue } = this.data; | 80 | + const { value } = this.data; |
| 77 | - if (!equal(value, currentValue)) { | 81 | + this.setData({ currentValue: this.format(value).newValue }); |
| 78 | - this.setData({ currentValue: this.format(value) }); | ||
| 79 | - } | ||
| 80 | }, | 82 | }, |
| 81 | check() { | 83 | check() { |
| 82 | - const val = this.format(this.data.currentValue); | 84 | + const { newValue } = this.format(this.data.currentValue); |
| 83 | - if (!equal(val, this.data.currentValue)) { | 85 | + if (!equal(newValue, this.data.currentValue)) { |
| 84 | - this.setData({ currentValue: val }); | 86 | + this.setData({ currentValue: newValue }); |
| 85 | } | 87 | } |
| 86 | }, | 88 | }, |
| 87 | isDisabled(type) { | 89 | isDisabled(type) { |
| 88 | - const { disabled, disablePlus, disableMinus, currentValue, max, min, } = this.data; | 90 | + const { disabled, disablePlus, disableMinus, currentValue, max, min } = this.data; |
| 89 | if (type === 'plus') { | 91 | if (type === 'plus') { |
| 90 | - return disabled || disablePlus || currentValue >= max; | 92 | + return disabled || disablePlus || +currentValue >= +max; |
| 91 | } | 93 | } |
| 92 | - return disabled || disableMinus || currentValue <= min; | 94 | + return disabled || disableMinus || +currentValue <= +min; |
| 93 | }, | 95 | }, |
| 94 | onFocus(event) { | 96 | onFocus(event) { |
| 95 | this.$emit('focus', event.detail); | 97 | this.$emit('focus', event.detail); |
| 96 | }, | 98 | }, |
| 97 | onBlur(event) { | 99 | onBlur(event) { |
| 98 | - const value = this.format(event.detail.value); | 100 | + const data = this.format(event.detail.value); |
| 99 | - this.emitChange(value); | 101 | + this.setData({ currentValue: data.newValue }); |
| 100 | - this.$emit('blur', Object.assign(Object.assign({}, event.detail), { value })); | 102 | + this.emitChange(data); |
| 103 | + this.$emit('blur', Object.assign(Object.assign({}, event.detail), { value: +data.newValue })); | ||
| 101 | }, | 104 | }, |
| 102 | // filter illegal characters | 105 | // filter illegal characters |
| 103 | filter(value) { | 106 | filter(value) { |
| ... | @@ -107,17 +110,16 @@ VantComponent({ | ... | @@ -107,17 +110,16 @@ VantComponent({ |
| 107 | } | 110 | } |
| 108 | return value; | 111 | return value; |
| 109 | }, | 112 | }, |
| 110 | - // limit value range | ||
| 111 | format(value) { | 113 | format(value) { |
| 112 | - value = this.filter(value); | 114 | + // filter illegal characters and format integer |
| 115 | + const safeValue = this.filter(value); | ||
| 113 | // format range | 116 | // format range |
| 114 | - value = value === '' ? 0 : +value; | 117 | + const rangeValue = Math.max(Math.min(this.data.max, +safeValue), this.data.min); |
| 115 | - value = Math.max(Math.min(this.data.max, value), this.data.min); | ||
| 116 | // format decimal | 118 | // format decimal |
| 117 | - if (isDef(this.data.decimalLength)) { | 119 | + const newValue = isDef(this.data.decimalLength) |
| 118 | - value = value.toFixed(this.data.decimalLength); | 120 | + ? rangeValue.toFixed(this.data.decimalLength) |
| 119 | - } | 121 | + : String(rangeValue); |
| 120 | - return value; | 122 | + return { value, newValue }; |
| 121 | }, | 123 | }, |
| 122 | onInput(event) { | 124 | onInput(event) { |
| 123 | const { value = '' } = event.detail || {}; | 125 | const { value = '' } = event.detail || {}; |
| ... | @@ -125,19 +127,16 @@ VantComponent({ | ... | @@ -125,19 +127,16 @@ VantComponent({ |
| 125 | if (value === '') { | 127 | if (value === '') { |
| 126 | return; | 128 | return; |
| 127 | } | 129 | } |
| 128 | - let formatted = this.filter(value); | 130 | + const formatted = this.format(value); |
| 129 | - // limit max decimal length | ||
| 130 | - if (isDef(this.data.decimalLength) && formatted.indexOf('.') !== -1) { | ||
| 131 | - const pair = formatted.split('.'); | ||
| 132 | - formatted = `${pair[0]}.${pair[1].slice(0, this.data.decimalLength)}`; | ||
| 133 | - } | ||
| 134 | this.emitChange(formatted); | 131 | this.emitChange(formatted); |
| 135 | }, | 132 | }, |
| 136 | - emitChange(value) { | 133 | + emitChange(data) { |
| 134 | + const { value, newValue } = data; | ||
| 137 | if (!this.data.asyncChange) { | 135 | if (!this.data.asyncChange) { |
| 138 | - this.setData({ currentValue: value }); | 136 | + // fix when input 11. parsed to 11, unable to enter decimal |
| 137 | + this.setData({ currentValue: +value === +newValue ? value : newValue }); | ||
| 139 | } | 138 | } |
| 140 | - this.$emit('change', value); | 139 | + this.$emit('change', +newValue); |
| 141 | }, | 140 | }, |
| 142 | onChange() { | 141 | onChange() { |
| 143 | const { type } = this; | 142 | const { type } = this; |
| ... | @@ -146,7 +145,7 @@ VantComponent({ | ... | @@ -146,7 +145,7 @@ VantComponent({ |
| 146 | return; | 145 | return; |
| 147 | } | 146 | } |
| 148 | const diff = type === 'minus' ? -this.data.step : +this.data.step; | 147 | const diff = type === 'minus' ? -this.data.step : +this.data.step; |
| 149 | - const value = this.format(add(+this.data.currentValue, diff)); | 148 | + const value = this.format(String(add(+this.data.currentValue, diff))); |
| 150 | this.emitChange(value); | 149 | this.emitChange(value); |
| 151 | this.$emit(type); | 150 | this.$emit(type); |
| 152 | }, | 151 | }, | ... | ... |
| ... | @@ -16,7 +16,6 @@ | ... | @@ -16,7 +16,6 @@ |
| 16 | <slot name="minus" /> | 16 | <slot name="minus" /> |
| 17 | </view> | 17 | </view> |
| 18 | <input | 18 | <input |
| 19 | - always-embed="{{ false }}" | ||
| 20 | type="{{ integer ? 'number' : 'digit' }}" | 19 | type="{{ integer ? 'number' : 'digit' }}" |
| 21 | class="input-class {{ utils.bem('stepper__input', { disabled: disabled || disableInput }) }}" | 20 | class="input-class {{ utils.bem('stepper__input', { disabled: disabled || disableInput }) }}" |
| 22 | style="{{ computed.inputStyle({ buttonSize, inputWidth }) }}" | 21 | style="{{ computed.inputStyle({ buttonSize, inputWidth }) }}" | ... | ... |
| ... | @@ -20,7 +20,7 @@ | ... | @@ -20,7 +20,7 @@ |
| 20 | wx:if="{{ item.inactiveIcon || inactiveIcon }}" | 20 | wx:if="{{ item.inactiveIcon || inactiveIcon }}" |
| 21 | color="{{ status(index, active) === 'inactive' ? inactiveColor: activeColor }}" | 21 | color="{{ status(index, active) === 'inactive' ? inactiveColor: activeColor }}" |
| 22 | name="{{ item.inactiveIcon || inactiveIcon }}" | 22 | name="{{ item.inactiveIcon || inactiveIcon }}" |
| 23 | - custom-class="van-step__icon" | 23 | + class="van-step__icon" |
| 24 | /> | 24 | /> |
| 25 | <view | 25 | <view |
| 26 | wx:else | 26 | wx:else |
| ... | @@ -29,7 +29,7 @@ | ... | @@ -29,7 +29,7 @@ |
| 29 | /> | 29 | /> |
| 30 | </block> | 30 | </block> |
| 31 | 31 | ||
| 32 | - <van-icon wx:else name="{{ item.activeIcon || activeIcon }}" color="{{ activeColor }}" custom-class="van-step__icon" /> | 32 | + <van-icon wx:else name="{{ item.activeIcon || activeIcon }}" color="{{ activeColor }}" class="van-step__icon" /> |
| 33 | </view> | 33 | </view> |
| 34 | <view | 34 | <view |
| 35 | wx:if="{{ index !== steps.length - 1 }}" | 35 | wx:if="{{ index !== steps.length - 1 }}" | ... | ... |
| 1 | -@import '../common/index.wxss';.van-steps{background-color:var(--steps-background-color,#fff);overflow:hidden}.van-steps--horizontal{padding:10px}.van-steps--horizontal .van-step__wrapper{display:flex;overflow:hidden;position:relative}.van-steps--vertical{padding-left:10px}.van-steps--vertical .van-step__wrapper{padding:0 0 0 20px}.van-step{color:var(--step-text-color,#969799);flex:1;font-size:var(--step-font-size,14px);position:relative}.van-step--finish{color:var(--step-finish-text-color,#323233)}.van-step__circle{background-color:var(--step-circle-color,#969799);border-radius:50%;height:var(--step-circle-size,5px);width:var(--step-circle-size,5px)}.van-step--horizontal{padding-bottom:14px}.van-step--horizontal:first-child .van-step__title{transform:none}.van-step--horizontal:first-child .van-step__circle-container{padding:0 8px 0 0;transform:translate3d(0,50%,0)}.van-step--horizontal:last-child{position:absolute;right:0;width:auto}.van-step--horizontal:last-child .van-step__title{text-align:right;transform:none}.van-step--horizontal:last-child .van-step__circle-container{padding:0 0 0 8px;right:0;transform:translate3d(0,50%,0)}.van-step--horizontal .van-step__circle-container{background-color:#fff;bottom:6px;padding:0 var(--padding-xs,8px);position:absolute;transform:translate3d(-50%,50%,0);z-index:1}.van-step--horizontal .van-step__title{display:inline-block;font-size:var(--step-horizontal-title-font-size,12px);transform:translate3d(-50%,0,0)}.van-step--horizontal .van-step__line{background-color:var(--step-line-color,#ebedf0);bottom:6px;height:1px;left:0;position:absolute;right:0;transform:translate3d(0,50%,0)}.van-step--horizontal.van-step--process{color:var(--step-process-text-color,#323233)}.van-step--horizontal.van-step--process .van-step__icon{display:block;font-size:var(--step-icon-size,12px);line-height:1}.van-step--vertical{line-height:18px;padding:10px 10px 10px 0}.van-step--vertical:after{border-bottom-width:1px}.van-step--vertical:last-child:after{border-bottom-width:none}.van-step--vertical:first-child:before{background-color:#fff;content:"";height:20px;left:-15px;position:absolute;top:0;width:1px;z-index:1}.van-step--vertical .van-step__circle,.van-step--vertical .van-step__icon,.van-step--vertical .van-step__line{left:-14px;position:absolute;top:19px;transform:translate3d(-50%,-50%,0);z-index:2}.van-step--vertical .van-step__icon{font-size:var(--step-icon-size,12px);line-height:1}.van-step--vertical .van-step__line{background-color:var(--step-line-color,#ebedf0);height:100%;transform:translate3d(-50%,0,0);width:1px;z-index:1} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-steps{background-color:var(--steps-background-color,#fff);overflow:hidden}.van-steps--horizontal{padding:10px}.van-steps--horizontal .van-step__wrapper{display:flex;overflow:hidden;position:relative}.van-steps--vertical{padding-left:10px}.van-steps--vertical .van-step__wrapper{padding:0 0 0 20px}.van-step{color:var(--step-text-color,#969799);flex:1;font-size:var(--step-font-size,14px);position:relative}.van-step--finish{color:var(--step-finish-text-color,#323233)}.van-step__circle{background-color:var(--step-circle-color,#969799);border-radius:50%;height:var(--step-circle-size,5px);width:var(--step-circle-size,5px)}.van-step--horizontal{padding-bottom:14px}.van-step--horizontal:first-child .van-step__title{transform:none}.van-step--horizontal:first-child .van-step__circle-container{padding:0 8px 0 0;transform:translate3d(0,50%,0)}.van-step--horizontal:last-child{bottom:0;position:absolute;right:0;top:0;width:auto}.van-step--horizontal:last-child .van-step__title{text-align:right;transform:none}.van-step--horizontal:last-child .van-step__circle-container{padding:0 0 0 8px;right:0;transform:translate3d(0,50%,0)}.van-step--horizontal .van-step__circle-container{background-color:#fff;bottom:6px;padding:0 var(--padding-xs,8px);position:absolute;transform:translate3d(-50%,50%,0);z-index:1}.van-step--horizontal .van-step__title{display:inline-block;font-size:var(--step-horizontal-title-font-size,12px);transform:translate3d(-50%,0,0)}.van-step--horizontal .van-step__line{background-color:var(--step-line-color,#ebedf0);bottom:6px;height:1px;left:0;position:absolute;right:0;transform:translate3d(0,50%,0)}.van-step--horizontal.van-step--process{color:var(--step-process-text-color,#323233)}.van-step--horizontal.van-step--process .van-step__icon{display:block;font-size:var(--step-icon-size,12px);line-height:1}.van-step--vertical{line-height:18px;padding:10px 10px 10px 0}.van-step--vertical:after{border-bottom-width:1px}.van-step--vertical:last-child:after{border-bottom-width:none}.van-step--vertical:first-child:before{background-color:#fff;content:"";height:20px;left:-15px;position:absolute;top:0;width:1px;z-index:1}.van-step--vertical .van-step__circle,.van-step--vertical .van-step__icon,.van-step--vertical .van-step__line{left:-14px;position:absolute;top:19px;transform:translate3d(-50%,-50%,0);z-index:2}.van-step--vertical .van-step__icon{background-color:var(--steps-background-color,#fff);font-size:var(--step-icon-size,12px);line-height:1}.van-step--vertical .van-step__line{background-color:var(--step-line-color,#ebedf0);height:100%;transform:translate3d(-50%,0,0);width:1px;z-index:1} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -57,10 +57,8 @@ VantComponent({ | ... | @@ -57,10 +57,8 @@ VantComponent({ |
| 57 | } | 57 | } |
| 58 | this.scrollTop = scrollTop || this.scrollTop; | 58 | this.scrollTop = scrollTop || this.scrollTop; |
| 59 | if (typeof container === 'function') { | 59 | if (typeof container === 'function') { |
| 60 | - Promise.all([ | 60 | + Promise.all([getRect(this, ROOT_ELEMENT), this.getContainerRect()]) |
| 61 | - getRect(this, ROOT_ELEMENT), | 61 | + .then(([root, container]) => { |
| 62 | - this.getContainerRect(), | ||
| 63 | - ]).then(([root, container]) => { | ||
| 64 | if (offsetTop + root.height > container.height + container.top) { | 62 | if (offsetTop + root.height > container.height + container.top) { |
| 65 | this.setDataAfterDiff({ | 63 | this.setDataAfterDiff({ |
| 66 | fixed: false, | 64 | fixed: false, |
| ... | @@ -77,11 +75,12 @@ VantComponent({ | ... | @@ -77,11 +75,12 @@ VantComponent({ |
| 77 | else { | 75 | else { |
| 78 | this.setDataAfterDiff({ fixed: false, transform: 0 }); | 76 | this.setDataAfterDiff({ fixed: false, transform: 0 }); |
| 79 | } | 77 | } |
| 80 | - }); | 78 | + }) |
| 79 | + .catch(() => { }); | ||
| 81 | return; | 80 | return; |
| 82 | } | 81 | } |
| 83 | getRect(this, ROOT_ELEMENT).then((root) => { | 82 | getRect(this, ROOT_ELEMENT).then((root) => { |
| 84 | - if (!isDef(root)) { | 83 | + if (!isDef(root) || (!root.width && !root.height)) { |
| 85 | return; | 84 | return; |
| 86 | } | 85 | } |
| 87 | if (offsetTop >= root.top) { | 86 | if (offsetTop >= root.top) { |
| ... | @@ -112,6 +111,9 @@ VantComponent({ | ... | @@ -112,6 +111,9 @@ VantComponent({ |
| 112 | }, | 111 | }, |
| 113 | getContainerRect() { | 112 | getContainerRect() { |
| 114 | const nodesRef = this.data.container(); | 113 | const nodesRef = this.data.container(); |
| 114 | + if (!nodesRef) { | ||
| 115 | + return Promise.reject(new Error('not found container')); | ||
| 116 | + } | ||
| 115 | return new Promise((resolve) => nodesRef.boundingClientRect(resolve).exec()); | 117 | return new Promise((resolve) => nodesRef.boundingClientRect(resolve).exec()); |
| 116 | }, | 118 | }, |
| 117 | }, | 119 | }, | ... | ... |
| ... | @@ -6,6 +6,14 @@ VantComponent({ | ... | @@ -6,6 +6,14 @@ VantComponent({ |
| 6 | name: null, | 6 | name: null, |
| 7 | icon: String, | 7 | icon: String, |
| 8 | dot: Boolean, | 8 | dot: Boolean, |
| 9 | + url: { | ||
| 10 | + type: String, | ||
| 11 | + value: '', | ||
| 12 | + }, | ||
| 13 | + linkType: { | ||
| 14 | + type: String, | ||
| 15 | + value: 'redirectTo', | ||
| 16 | + }, | ||
| 9 | iconPrefix: { | 17 | iconPrefix: { |
| 10 | type: String, | 18 | type: String, |
| 11 | value: 'van-icon', | 19 | value: 'van-icon', |
| ... | @@ -27,6 +35,10 @@ VantComponent({ | ... | @@ -27,6 +35,10 @@ VantComponent({ |
| 27 | parent.$emit('change', active); | 35 | parent.$emit('change', active); |
| 28 | } | 36 | } |
| 29 | } | 37 | } |
| 38 | + const { url, linkType } = this.data; | ||
| 39 | + if (url && wx[linkType]) { | ||
| 40 | + return wx[linkType]({ url }); | ||
| 41 | + } | ||
| 30 | this.$emit('click'); | 42 | this.$emit('click'); |
| 31 | }, | 43 | }, |
| 32 | updateFromParent() { | 44 | updateFromParent() { | ... | ... |
| ... | @@ -5,7 +5,13 @@ import { isDef } from '../common/validator'; | ... | @@ -5,7 +5,13 @@ import { isDef } from '../common/validator'; |
| 5 | import { useChildren } from '../common/relation'; | 5 | import { useChildren } from '../common/relation'; |
| 6 | VantComponent({ | 6 | VantComponent({ |
| 7 | mixins: [touch], | 7 | mixins: [touch], |
| 8 | - classes: ['nav-class', 'tab-class', 'tab-active-class', 'line-class'], | 8 | + classes: [ |
| 9 | + 'nav-class', | ||
| 10 | + 'tab-class', | ||
| 11 | + 'tab-active-class', | ||
| 12 | + 'line-class', | ||
| 13 | + 'wrap-class', | ||
| 14 | + ], | ||
| 9 | relation: useChildren('tab', function () { | 15 | relation: useChildren('tab', function () { |
| 10 | this.updateTabs(); | 16 | this.updateTabs(); |
| 11 | }), | 17 | }), |
| ... | @@ -73,6 +79,10 @@ VantComponent({ | ... | @@ -73,6 +79,10 @@ VantComponent({ |
| 73 | type: Boolean, | 79 | type: Boolean, |
| 74 | value: true, | 80 | value: true, |
| 75 | }, | 81 | }, |
| 82 | + useBeforeChange: { | ||
| 83 | + type: Boolean, | ||
| 84 | + value: false, | ||
| 85 | + }, | ||
| 76 | }, | 86 | }, |
| 77 | data: { | 87 | data: { |
| 78 | tabs: [], | 88 | tabs: [], |
| ... | @@ -83,6 +93,7 @@ VantComponent({ | ... | @@ -83,6 +93,7 @@ VantComponent({ |
| 83 | skipTransition: true, | 93 | skipTransition: true, |
| 84 | scrollWithAnimation: false, | 94 | scrollWithAnimation: false, |
| 85 | lineOffsetLeft: 0, | 95 | lineOffsetLeft: 0, |
| 96 | + inited: false, | ||
| 86 | }, | 97 | }, |
| 87 | mounted() { | 98 | mounted() { |
| 88 | requestAnimationFrame(() => { | 99 | requestAnimationFrame(() => { |
| ... | @@ -105,28 +116,25 @@ VantComponent({ | ... | @@ -105,28 +116,25 @@ VantComponent({ |
| 105 | }, | 116 | }, |
| 106 | trigger(eventName, child) { | 117 | trigger(eventName, child) { |
| 107 | const { currentIndex } = this.data; | 118 | const { currentIndex } = this.data; |
| 108 | - const currentChild = child || this.children[currentIndex]; | 119 | + const data = this.getChildData(currentIndex, child); |
| 109 | - if (!isDef(currentChild)) { | 120 | + if (!isDef(data)) { |
| 110 | return; | 121 | return; |
| 111 | } | 122 | } |
| 112 | - this.$emit(eventName, { | 123 | + this.$emit(eventName, data); |
| 113 | - index: currentChild.index, | ||
| 114 | - name: currentChild.getComputedName(), | ||
| 115 | - title: currentChild.data.title, | ||
| 116 | - }); | ||
| 117 | }, | 124 | }, |
| 118 | onTap(event) { | 125 | onTap(event) { |
| 119 | const { index } = event.currentTarget.dataset; | 126 | const { index } = event.currentTarget.dataset; |
| 120 | const child = this.children[index]; | 127 | const child = this.children[index]; |
| 121 | if (child.data.disabled) { | 128 | if (child.data.disabled) { |
| 122 | this.trigger('disabled', child); | 129 | this.trigger('disabled', child); |
| 130 | + return; | ||
| 123 | } | 131 | } |
| 124 | - else { | 132 | + this.onBeforeChange(index).then(() => { |
| 125 | this.setCurrentIndex(index); | 133 | this.setCurrentIndex(index); |
| 126 | nextTick(() => { | 134 | nextTick(() => { |
| 127 | this.trigger('click'); | 135 | this.trigger('click'); |
| 128 | }); | 136 | }); |
| 129 | - } | 137 | + }); |
| 130 | }, | 138 | }, |
| 131 | // correct the index of active tab | 139 | // correct the index of active tab |
| 132 | setCurrentIndexByName(name) { | 140 | setCurrentIndexByName(name) { |
| ... | @@ -152,6 +160,9 @@ VantComponent({ | ... | @@ -152,6 +160,9 @@ VantComponent({ |
| 152 | }); | 160 | }); |
| 153 | }); | 161 | }); |
| 154 | if (currentIndex === data.currentIndex) { | 162 | if (currentIndex === data.currentIndex) { |
| 163 | + if (!data.inited) { | ||
| 164 | + this.resize(); | ||
| 165 | + } | ||
| 155 | return; | 166 | return; |
| 156 | } | 167 | } |
| 157 | const shouldEmitChange = data.currentIndex !== null; | 168 | const shouldEmitChange = data.currentIndex !== null; |
| ... | @@ -191,12 +202,13 @@ VantComponent({ | ... | @@ -191,12 +202,13 @@ VantComponent({ |
| 191 | .reduce((prev, curr) => prev + curr.width, 0); | 202 | .reduce((prev, curr) => prev + curr.width, 0); |
| 192 | lineOffsetLeft += | 203 | lineOffsetLeft += |
| 193 | (rect.width - lineRect.width) / 2 + (ellipsis ? 0 : 8); | 204 | (rect.width - lineRect.width) / 2 + (ellipsis ? 0 : 8); |
| 194 | - this.setData({ lineOffsetLeft }); | 205 | + this.setData({ lineOffsetLeft, inited: true }); |
| 195 | this.swiping = true; | 206 | this.swiping = true; |
| 196 | if (skipTransition) { | 207 | if (skipTransition) { |
| 197 | - nextTick(() => { | 208 | + // waiting transition end |
| 209 | + setTimeout(() => { | ||
| 198 | this.setData({ skipTransition: false }); | 210 | this.setData({ skipTransition: false }); |
| 199 | - }); | 211 | + }, this.data.duration); |
| 200 | } | 212 | } |
| 201 | }); | 213 | }); |
| 202 | }, | 214 | }, |
| ... | @@ -247,7 +259,7 @@ VantComponent({ | ... | @@ -247,7 +259,7 @@ VantComponent({ |
| 247 | if (direction === 'horizontal' && offsetX >= minSwipeDistance) { | 259 | if (direction === 'horizontal' && offsetX >= minSwipeDistance) { |
| 248 | const index = this.getAvaiableTab(deltaX); | 260 | const index = this.getAvaiableTab(deltaX); |
| 249 | if (index !== -1) { | 261 | if (index !== -1) { |
| 250 | - this.setCurrentIndex(index); | 262 | + this.onBeforeChange(index).then(() => this.setCurrentIndex(index)); |
| 251 | } | 263 | } |
| 252 | } | 264 | } |
| 253 | this.swiping = false; | 265 | this.swiping = false; |
| ... | @@ -266,5 +278,25 @@ VantComponent({ | ... | @@ -266,5 +278,25 @@ VantComponent({ |
| 266 | } | 278 | } |
| 267 | return -1; | 279 | return -1; |
| 268 | }, | 280 | }, |
| 281 | + onBeforeChange(index) { | ||
| 282 | + const { useBeforeChange } = this.data; | ||
| 283 | + if (!useBeforeChange) { | ||
| 284 | + return Promise.resolve(); | ||
| 285 | + } | ||
| 286 | + return new Promise((resolve, reject) => { | ||
| 287 | + this.$emit('before-change', Object.assign(Object.assign({}, this.getChildData(index)), { callback: (status) => (status ? resolve() : reject()) })); | ||
| 288 | + }); | ||
| 289 | + }, | ||
| 290 | + getChildData(index, child) { | ||
| 291 | + const currentChild = child || this.children[index]; | ||
| 292 | + if (!isDef(currentChild)) { | ||
| 293 | + return; | ||
| 294 | + } | ||
| 295 | + return { | ||
| 296 | + index: currentChild.index, | ||
| 297 | + name: currentChild.getComputedName(), | ||
| 298 | + title: currentChild.data.title, | ||
| 299 | + }; | ||
| 300 | + }, | ||
| 269 | }, | 301 | }, |
| 270 | }); | 302 | }); | ... | ... |
| 1 | <wxs src="../wxs/utils.wxs" module="utils" /> | 1 | <wxs src="../wxs/utils.wxs" module="utils" /> |
| 2 | <wxs src="./index.wxs" module="computed" /> | 2 | <wxs src="./index.wxs" module="computed" /> |
| 3 | 3 | ||
| 4 | -<view class="custom-class {{ utils.bem('tabs', [type]) }}"> | 4 | +<view class="custom-class {{ utils.bem('tabs') }}"> |
| 5 | <van-sticky | 5 | <van-sticky |
| 6 | disabled="{{ !sticky }}" | 6 | disabled="{{ !sticky }}" |
| 7 | z-index="{{ zIndex }}" | 7 | z-index="{{ zIndex }}" |
| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | container="{{ container }}" | 9 | container="{{ container }}" |
| 10 | bind:scroll="onTouchScroll" | 10 | bind:scroll="onTouchScroll" |
| 11 | > | 11 | > |
| 12 | - <view class="{{ utils.bem('tabs__wrap', { scrollable }) }} {{ type === 'line' && border ? 'van-hairline--top-bottom' : '' }}"> | 12 | + <view class="{{ utils.bem('tabs--') + type }} {{ utils.bem('tabs__wrap', { scrollable }) }} {{ type === 'line' && border ? 'van-hairline--top-bottom' : '' }} wrap-class"> |
| 13 | <slot name="nav-left" /> | 13 | <slot name="nav-left" /> |
| 14 | 14 | ||
| 15 | <scroll-view | 15 | <scroll-view |
| ... | @@ -20,7 +20,7 @@ | ... | @@ -20,7 +20,7 @@ |
| 20 | style="{{ color ? 'border-color: ' + color : '' }}" | 20 | style="{{ color ? 'border-color: ' + color : '' }}" |
| 21 | > | 21 | > |
| 22 | <view class="{{ utils.bem('tabs__nav', [type, { complete: !ellipsis }]) }} nav-class" style="{{ computed.navStyle(color, type) }}"> | 22 | <view class="{{ utils.bem('tabs__nav', [type, { complete: !ellipsis }]) }} nav-class" style="{{ computed.navStyle(color, type) }}"> |
| 23 | - <view wx:if="{{ type === 'line' }}" class="van-tabs__line" style="{{ computed.lineStyle({ color, lineOffsetLeft, lineHeight, skipTransition, duration, lineWidth }) }}" /> | 23 | + <view wx:if="{{ type === 'line' }}" class="van-tabs__line" style="{{ computed.lineStyle({ color, lineOffsetLeft, lineHeight, skipTransition, duration, lineWidth, inited }) }}" /> |
| 24 | <view | 24 | <view |
| 25 | wx:for="{{ tabs }}" | 25 | wx:for="{{ tabs }}" |
| 26 | wx:key="index" | 26 | wx:key="index" | ... | ... |
| ... | @@ -60,6 +60,7 @@ function trackStyle(data) { | ... | @@ -60,6 +60,7 @@ function trackStyle(data) { |
| 60 | function lineStyle(data) { | 60 | function lineStyle(data) { |
| 61 | return style({ | 61 | return style({ |
| 62 | width: utils.addUnit(data.lineWidth), | 62 | width: utils.addUnit(data.lineWidth), |
| 63 | + opacity: data.inited ? 1 : 0, | ||
| 63 | transform: 'translateX(' + data.lineOffsetLeft + 'px)', | 64 | transform: 'translateX(' + data.lineOffsetLeft + 'px)', |
| 64 | '-webkit-transform': 'translateX(' + data.lineOffsetLeft + 'px)', | 65 | '-webkit-transform': 'translateX(' + data.lineOffsetLeft + 'px)', |
| 65 | 'background-color': data.color, | 66 | 'background-color': data.color, | ... | ... |
| 1 | -@import '../common/index.wxss';.van-tabs{-webkit-tap-highlight-color:transparent;position:relative}.van-tabs__wrap{display:flex;overflow:hidden}.van-tabs__wrap--scrollable .van-tab{flex:0 0 22%}.van-tabs__wrap--scrollable .van-tab--complete{flex:1 0 auto!important;padding:0 12px}.van-tabs__wrap--scrollable .van-tabs__nav--complete{padding-left:8px;padding-right:8px}.van-tabs__scroll{background-color:var(--tabs-nav-background-color,#fff)}.van-tabs__scroll--line{box-sizing:initial;height:calc(100% + 15px)}.van-tabs__scroll--card{border:1px solid var(--tabs-default-color,#ee0a24);border-radius:2px;box-sizing:border-box;margin:0 var(--padding-md,16px);width:calc(100% - var(--padding-md, 16px)*2)}.van-tabs__scroll::-webkit-scrollbar{display:none}.van-tabs__nav{display:flex;position:relative;-webkit-user-select:none;user-select:none}.van-tabs__nav--card{box-sizing:border-box;height:var(--tabs-card-height,30px)}.van-tabs__nav--card .van-tab{border-right:1px solid var(--tabs-default-color,#ee0a24);color:var(--tabs-default-color,#ee0a24);line-height:calc(var(--tabs-card-height, 30px) - 2px)}.van-tabs__nav--card .van-tab:last-child{border-right:none}.van-tabs__nav--card .van-tab.van-tab--active{background-color:var(--tabs-default-color,#ee0a24);color:#fff}.van-tabs__nav--card .van-tab--disabled{color:var(--tab-disabled-text-color,#c8c9cc)}.van-tabs__line{background-color:var(--tabs-bottom-bar-color,#ee0a24);border-radius:var(--tabs-bottom-bar-height,3px);bottom:0;height:var(--tabs-bottom-bar-height,3px);left:0;position:absolute;z-index:1}.van-tabs__track{height:100%;position:relative;width:100%}.van-tabs__track--animated{display:flex;transition-property:left}.van-tabs__content{overflow:hidden}.van-tabs--line .van-tabs__wrap{height:var(--tabs-line-height,44px)}.van-tabs--card .van-tabs__wrap{height:var(--tabs-card-height,30px)}.van-tab{box-sizing:border-box;color:var(--tab-text-color,#646566);cursor:pointer;flex:1;font-size:var(--tab-font-size,14px);line-height:var(--tabs-line-height,44px);min-width:0;padding:0 5px;position:relative;text-align:center}.van-tab--active{color:var(--tab-active-text-color,#323233);font-weight:var(--font-weight-bold,500)}.van-tab--disabled{color:var(--tab-disabled-text-color,#c8c9cc)}.van-tab__title__info{display:inline-block;position:relative!important;top:-1px!important;transform:translateX(0)!important} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +@import '../common/index.wxss';.van-tabs{-webkit-tap-highlight-color:transparent;position:relative}.van-tabs__wrap{display:flex;overflow:hidden}.van-tabs__wrap--scrollable .van-tab{flex:0 0 22%}.van-tabs__wrap--scrollable .van-tab--complete{flex:1 0 auto!important;padding:0 12px}.van-tabs__wrap--scrollable .van-tabs__nav--complete{padding-left:8px;padding-right:8px}.van-tabs__scroll{background-color:var(--tabs-nav-background-color,#fff);overflow:auto}.van-tabs__scroll--line{box-sizing:initial;height:calc(100% + 15px)}.van-tabs__scroll--card{border:1px solid var(--tabs-default-color,#ee0a24);border-radius:2px;box-sizing:border-box;margin:0 var(--padding-md,16px);width:calc(100% - var(--padding-md, 16px)*2)}.van-tabs__scroll::-webkit-scrollbar{display:none}.van-tabs__nav{display:flex;position:relative;-webkit-user-select:none;user-select:none}.van-tabs__nav--card{box-sizing:border-box;height:var(--tabs-card-height,30px)}.van-tabs__nav--card .van-tab{border-right:1px solid var(--tabs-default-color,#ee0a24);color:var(--tabs-default-color,#ee0a24);line-height:calc(var(--tabs-card-height, 30px) - 2px)}.van-tabs__nav--card .van-tab:last-child{border-right:none}.van-tabs__nav--card .van-tab.van-tab--active{background-color:var(--tabs-default-color,#ee0a24);color:#fff}.van-tabs__nav--card .van-tab--disabled{color:var(--tab-disabled-text-color,#c8c9cc)}.van-tabs__line{background-color:var(--tabs-bottom-bar-color,#ee0a24);border-radius:var(--tabs-bottom-bar-height,3px);bottom:0;height:var(--tabs-bottom-bar-height,3px);left:0;opacity:0;position:absolute;z-index:1}.van-tabs__track{height:100%;position:relative;width:100%}.van-tabs__track--animated{display:flex;transition-property:left}.van-tabs__content{overflow:hidden}.van-tabs--line{height:var(--tabs-line-height,44px)}.van-tabs--card{height:var(--tabs-card-height,30px)}.van-tab{box-sizing:border-box;color:var(--tab-text-color,#646566);cursor:pointer;flex:1;font-size:var(--tab-font-size,14px);line-height:var(--tabs-line-height,44px);min-width:0;padding:0 5px;position:relative;text-align:center}.van-tab--active{color:var(--tab-active-text-color,#323233);font-weight:var(--font-weight-bold,500)}.van-tab--disabled{color:var(--tab-disabled-text-color,#c8c9cc)}.van-tab__title__info{position:relative!important;top:-1px!important;transform:translateX(0)!important} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | /// <reference types="miniprogram-api-typings" /> | 1 | /// <reference types="miniprogram-api-typings" /> |
| 2 | -declare type ToastMessage = string | number; | 2 | +/// <reference types="miniprogram-api-typings" /> |
| 3 | +type ToastMessage = string | number; | ||
| 4 | +type ToastContext = WechatMiniprogram.Component.TrivialInstance | WechatMiniprogram.Page.TrivialInstance; | ||
| 3 | interface ToastOptions { | 5 | interface ToastOptions { |
| 4 | show?: boolean; | 6 | show?: boolean; |
| 5 | type?: string; | 7 | type?: string; |
| 6 | mask?: boolean; | 8 | mask?: boolean; |
| 7 | zIndex?: number; | 9 | zIndex?: number; |
| 8 | - context?: WechatMiniprogram.Component.TrivialInstance | WechatMiniprogram.Page.TrivialInstance; | 10 | + context?: (() => ToastContext) | ToastContext; |
| 9 | position?: string; | 11 | position?: string; |
| 10 | duration?: number; | 12 | duration?: number; |
| 11 | selector?: string; | 13 | selector?: string; | ... | ... |
| ... | @@ -22,7 +22,9 @@ function getContext() { | ... | @@ -22,7 +22,9 @@ function getContext() { |
| 22 | } | 22 | } |
| 23 | function Toast(toastOptions) { | 23 | function Toast(toastOptions) { |
| 24 | const options = Object.assign(Object.assign({}, currentOptions), parseOptions(toastOptions)); | 24 | const options = Object.assign(Object.assign({}, currentOptions), parseOptions(toastOptions)); |
| 25 | - const context = options.context || getContext(); | 25 | + const context = (typeof options.context === 'function' |
| 26 | + ? options.context() | ||
| 27 | + : options.context) || getContext(); | ||
| 26 | const toast = context.selectComponent(options.selector); | 28 | const toast = context.selectComponent(options.selector); |
| 27 | if (!toast) { | 29 | if (!toast) { |
| 28 | console.warn('未找到 van-toast 节点,请确认 selector 及 context 是否正确'); | 30 | console.warn('未找到 van-toast 节点,请确认 selector 及 context 是否正确'); | ... | ... |
| 1 | import { VantComponent } from '../common/component'; | 1 | import { VantComponent } from '../common/component'; |
| 2 | -import { isImageFile, chooseFile, isVideoFile } from './utils'; | ||
| 3 | -import { chooseImageProps, chooseVideoProps } from './shared'; | ||
| 4 | import { isBoolean, isPromise } from '../common/validator'; | 2 | import { isBoolean, isPromise } from '../common/validator'; |
| 3 | +import { imageProps, mediaProps, messageFileProps, videoProps } from './shared'; | ||
| 4 | +import { chooseFile, isImageFile, isVideoFile } from './utils'; | ||
| 5 | VantComponent({ | 5 | VantComponent({ |
| 6 | - props: Object.assign(Object.assign({ disabled: Boolean, multiple: Boolean, uploadText: String, useBeforeRead: Boolean, afterRead: null, beforeRead: null, previewSize: { | 6 | + props: Object.assign(Object.assign(Object.assign(Object.assign({ disabled: Boolean, multiple: Boolean, uploadText: String, useBeforeRead: Boolean, afterRead: null, beforeRead: null, previewSize: { |
| 7 | type: null, | 7 | type: null, |
| 8 | value: 80, | 8 | value: 80, |
| 9 | }, name: { | 9 | }, name: { |
| ... | @@ -34,13 +34,16 @@ VantComponent({ | ... | @@ -34,13 +34,16 @@ VantComponent({ |
| 34 | }, previewFullImage: { | 34 | }, previewFullImage: { |
| 35 | type: Boolean, | 35 | type: Boolean, |
| 36 | value: true, | 36 | value: true, |
| 37 | + }, videoFit: { | ||
| 38 | + type: String, | ||
| 39 | + value: 'contain', | ||
| 37 | }, imageFit: { | 40 | }, imageFit: { |
| 38 | type: String, | 41 | type: String, |
| 39 | value: 'scaleToFill', | 42 | value: 'scaleToFill', |
| 40 | }, uploadIcon: { | 43 | }, uploadIcon: { |
| 41 | type: String, | 44 | type: String, |
| 42 | value: 'photograph', | 45 | value: 'photograph', |
| 43 | - } }, chooseImageProps), chooseVideoProps), | 46 | + } }, imageProps), videoProps), mediaProps), messageFileProps), |
| 44 | data: { | 47 | data: { |
| 45 | lists: [], | 48 | lists: [], |
| 46 | isInCount: true, | 49 | isInCount: true, |
| ... | @@ -114,11 +117,12 @@ VantComponent({ | ... | @@ -114,11 +117,12 @@ VantComponent({ |
| 114 | if (!this.data.previewFullImage) | 117 | if (!this.data.previewFullImage) |
| 115 | return; | 118 | return; |
| 116 | const { index } = event.currentTarget.dataset; | 119 | const { index } = event.currentTarget.dataset; |
| 117 | - const { lists } = this.data; | 120 | + const { lists, showmenu } = this.data; |
| 118 | const item = lists[index]; | 121 | const item = lists[index]; |
| 119 | wx.previewImage({ | 122 | wx.previewImage({ |
| 120 | urls: lists.filter((item) => isImageFile(item)).map((item) => item.url), | 123 | urls: lists.filter((item) => isImageFile(item)).map((item) => item.url), |
| 121 | current: item.url, | 124 | current: item.url, |
| 125 | + showmenu, | ||
| 122 | fail() { | 126 | fail() { |
| 123 | wx.showToast({ title: '预览图片失败', icon: 'none' }); | 127 | wx.showToast({ title: '预览图片失败', icon: 'none' }); |
| 124 | }, | 128 | }, |
| ... | @@ -129,17 +133,28 @@ VantComponent({ | ... | @@ -129,17 +133,28 @@ VantComponent({ |
| 129 | return; | 133 | return; |
| 130 | const { index } = event.currentTarget.dataset; | 134 | const { index } = event.currentTarget.dataset; |
| 131 | const { lists } = this.data; | 135 | const { lists } = this.data; |
| 136 | + const sources = []; | ||
| 137 | + const current = lists.reduce((sum, cur, curIndex) => { | ||
| 138 | + if (!isVideoFile(cur)) { | ||
| 139 | + return sum; | ||
| 140 | + } | ||
| 141 | + sources.push(Object.assign(Object.assign({}, cur), { type: 'video' })); | ||
| 142 | + if (curIndex < index) { | ||
| 143 | + sum++; | ||
| 144 | + } | ||
| 145 | + return sum; | ||
| 146 | + }, 0); | ||
| 132 | wx.previewMedia({ | 147 | wx.previewMedia({ |
| 133 | - sources: lists | 148 | + sources, |
| 134 | - .filter((item) => isVideoFile(item)) | 149 | + current, |
| 135 | - .map((item) => (Object.assign(Object.assign({}, item), { type: 'video' }))), | ||
| 136 | - current: index, | ||
| 137 | fail() { | 150 | fail() { |
| 138 | wx.showToast({ title: '预览视频失败', icon: 'none' }); | 151 | wx.showToast({ title: '预览视频失败', icon: 'none' }); |
| 139 | }, | 152 | }, |
| 140 | }); | 153 | }); |
| 141 | }, | 154 | }, |
| 142 | onPreviewFile(event) { | 155 | onPreviewFile(event) { |
| 156 | + if (!this.data.previewFile) | ||
| 157 | + return; | ||
| 143 | const { index } = event.currentTarget.dataset; | 158 | const { index } = event.currentTarget.dataset; |
| 144 | wx.openDocument({ | 159 | wx.openDocument({ |
| 145 | filePath: this.data.lists[index].url, | 160 | filePath: this.data.lists[index].url, | ... | ... |
| ... | @@ -28,6 +28,8 @@ | ... | @@ -28,6 +28,8 @@ |
| 28 | title="{{ item.name || ('视频' + index) }}" | 28 | title="{{ item.name || ('视频' + index) }}" |
| 29 | poster="{{ item.thumb }}" | 29 | poster="{{ item.thumb }}" |
| 30 | autoplay="{{ item.autoplay }}" | 30 | autoplay="{{ item.autoplay }}" |
| 31 | + object-fit="{{videoFit}}" | ||
| 32 | + referrer-policy="{{ referrerPolicy }}" | ||
| 31 | class="van-uploader__preview-image" | 33 | class="van-uploader__preview-image" |
| 32 | style="{{ computed.sizeStyle({ previewSize }) }}" | 34 | style="{{ computed.sizeStyle({ previewSize }) }}" |
| 33 | data-index="{{ index }}" | 35 | data-index="{{ index }}" | ... | ... |
| 1 | -export declare const chooseImageProps: { | 1 | +export declare const imageProps: { |
| 2 | sizeType: { | 2 | sizeType: { |
| 3 | type: ArrayConstructor; | 3 | type: ArrayConstructor; |
| 4 | value: string[]; | 4 | value: string[]; |
| ... | @@ -7,8 +7,12 @@ export declare const chooseImageProps: { | ... | @@ -7,8 +7,12 @@ export declare const chooseImageProps: { |
| 7 | type: ArrayConstructor; | 7 | type: ArrayConstructor; |
| 8 | value: string[]; | 8 | value: string[]; |
| 9 | }; | 9 | }; |
| 10 | + showmenu: { | ||
| 11 | + type: BooleanConstructor; | ||
| 12 | + value: boolean; | ||
| 13 | + }; | ||
| 10 | }; | 14 | }; |
| 11 | -export declare const chooseVideoProps: { | 15 | +export declare const videoProps: { |
| 12 | capture: { | 16 | capture: { |
| 13 | type: ArrayConstructor; | 17 | type: ArrayConstructor; |
| 14 | value: string[]; | 18 | value: string[]; |
| ... | @@ -25,4 +29,33 @@ export declare const chooseVideoProps: { | ... | @@ -25,4 +29,33 @@ export declare const chooseVideoProps: { |
| 25 | type: StringConstructor; | 29 | type: StringConstructor; |
| 26 | value: string; | 30 | value: string; |
| 27 | }; | 31 | }; |
| 32 | + referrerPolicy: { | ||
| 33 | + type: StringConstructor; | ||
| 34 | + value: string; | ||
| 35 | + }; | ||
| 36 | +}; | ||
| 37 | +export declare const mediaProps: { | ||
| 38 | + capture: { | ||
| 39 | + type: ArrayConstructor; | ||
| 40 | + value: string[]; | ||
| 41 | + }; | ||
| 42 | + mediaType: { | ||
| 43 | + type: ArrayConstructor; | ||
| 44 | + value: string[]; | ||
| 45 | + }; | ||
| 46 | + maxDuration: { | ||
| 47 | + type: NumberConstructor; | ||
| 48 | + value: number; | ||
| 49 | + }; | ||
| 50 | + camera: { | ||
| 51 | + type: StringConstructor; | ||
| 52 | + value: string; | ||
| 53 | + }; | ||
| 54 | +}; | ||
| 55 | +export declare const messageFileProps: { | ||
| 56 | + extension: null; | ||
| 57 | + previewFile: { | ||
| 58 | + type: BooleanConstructor; | ||
| 59 | + value: boolean; | ||
| 60 | + }; | ||
| 28 | }; | 61 | }; | ... | ... |
| 1 | -// props for choose image | 1 | +// props for image |
| 2 | -export const chooseImageProps = { | 2 | +export const imageProps = { |
| 3 | sizeType: { | 3 | sizeType: { |
| 4 | type: Array, | 4 | type: Array, |
| 5 | value: ['original', 'compressed'], | 5 | value: ['original', 'compressed'], |
| ... | @@ -8,9 +8,13 @@ export const chooseImageProps = { | ... | @@ -8,9 +8,13 @@ export const chooseImageProps = { |
| 8 | type: Array, | 8 | type: Array, |
| 9 | value: ['album', 'camera'], | 9 | value: ['album', 'camera'], |
| 10 | }, | 10 | }, |
| 11 | + showmenu: { | ||
| 12 | + type: Boolean, | ||
| 13 | + value: true, | ||
| 14 | + }, | ||
| 11 | }; | 15 | }; |
| 12 | -// props for choose video | 16 | +// props for video |
| 13 | -export const chooseVideoProps = { | 17 | +export const videoProps = { |
| 14 | capture: { | 18 | capture: { |
| 15 | type: Array, | 19 | type: Array, |
| 16 | value: ['album', 'camera'], | 20 | value: ['album', 'camera'], |
| ... | @@ -27,4 +31,35 @@ export const chooseVideoProps = { | ... | @@ -27,4 +31,35 @@ export const chooseVideoProps = { |
| 27 | type: String, | 31 | type: String, |
| 28 | value: 'back', | 32 | value: 'back', |
| 29 | }, | 33 | }, |
| 34 | + referrerPolicy: { | ||
| 35 | + type: String, | ||
| 36 | + value: 'no-referrer', | ||
| 37 | + }, | ||
| 38 | +}; | ||
| 39 | +// props for media | ||
| 40 | +export const mediaProps = { | ||
| 41 | + capture: { | ||
| 42 | + type: Array, | ||
| 43 | + value: ['album', 'camera'], | ||
| 44 | + }, | ||
| 45 | + mediaType: { | ||
| 46 | + type: Array, | ||
| 47 | + value: ['image', 'video', 'mix'], | ||
| 48 | + }, | ||
| 49 | + maxDuration: { | ||
| 50 | + type: Number, | ||
| 51 | + value: 60, | ||
| 52 | + }, | ||
| 53 | + camera: { | ||
| 54 | + type: String, | ||
| 55 | + value: 'back', | ||
| 56 | + }, | ||
| 57 | +}; | ||
| 58 | +// props for file | ||
| 59 | +export const messageFileProps = { | ||
| 60 | + extension: null, | ||
| 61 | + previewFile: { | ||
| 62 | + type: Boolean, | ||
| 63 | + value: true, | ||
| 64 | + }, | ||
| 30 | }; | 65 | }; | ... | ... |
| ... | @@ -10,7 +10,7 @@ export interface File { | ... | @@ -10,7 +10,7 @@ export interface File { |
| 10 | } | 10 | } |
| 11 | export declare function isImageFile(item: File): boolean; | 11 | export declare function isImageFile(item: File): boolean; |
| 12 | export declare function isVideoFile(item: File): boolean; | 12 | export declare function isVideoFile(item: File): boolean; |
| 13 | -export declare function chooseFile({ accept, multiple, capture, compressed, maxDuration, sizeType, camera, maxCount, }: { | 13 | +export declare function chooseFile({ accept, multiple, capture, compressed, maxDuration, sizeType, camera, maxCount, mediaType, extension, }: { |
| 14 | accept: any; | 14 | accept: any; |
| 15 | multiple: any; | 15 | multiple: any; |
| 16 | capture: any; | 16 | capture: any; |
| ... | @@ -19,4 +19,6 @@ export declare function chooseFile({ accept, multiple, capture, compressed, maxD | ... | @@ -19,4 +19,6 @@ export declare function chooseFile({ accept, multiple, capture, compressed, maxD |
| 19 | sizeType: any; | 19 | sizeType: any; |
| 20 | camera: any; | 20 | camera: any; |
| 21 | maxCount: any; | 21 | maxCount: any; |
| 22 | + mediaType: any; | ||
| 23 | + extension: any; | ||
| 22 | }): Promise<File | File[]>; | 24 | }): Promise<File | File[]>; | ... | ... |
| 1 | -import { pickExclude } from '../common/utils'; | 1 | +import { pickExclude, isPC, isWxWork } from '../common/utils'; |
| 2 | import { isImageUrl, isVideoUrl } from '../common/validator'; | 2 | import { isImageUrl, isVideoUrl } from '../common/validator'; |
| 3 | export function isImageFile(item) { | 3 | export function isImageFile(item) { |
| 4 | if (item.isImage != null) { | 4 | if (item.isImage != null) { |
| ... | @@ -25,7 +25,7 @@ export function isVideoFile(item) { | ... | @@ -25,7 +25,7 @@ export function isVideoFile(item) { |
| 25 | return false; | 25 | return false; |
| 26 | } | 26 | } |
| 27 | function formatImage(res) { | 27 | function formatImage(res) { |
| 28 | - return res.tempFiles.map((item) => (Object.assign(Object.assign({}, pickExclude(item, ['path'])), { type: 'image', url: item.path, thumb: item.path }))); | 28 | + return res.tempFiles.map((item) => (Object.assign(Object.assign({}, pickExclude(item, ['path'])), { type: 'image', url: item.tempFilePath || item.path, thumb: item.tempFilePath || item.path }))); |
| 29 | } | 29 | } |
| 30 | function formatVideo(res) { | 30 | function formatVideo(res) { |
| 31 | return [ | 31 | return [ |
| ... | @@ -33,15 +33,16 @@ function formatVideo(res) { | ... | @@ -33,15 +33,16 @@ function formatVideo(res) { |
| 33 | ]; | 33 | ]; |
| 34 | } | 34 | } |
| 35 | function formatMedia(res) { | 35 | function formatMedia(res) { |
| 36 | - return res.tempFiles.map((item) => (Object.assign(Object.assign({}, pickExclude(item, ['fileType', 'thumbTempFilePath', 'tempFilePath'])), { type: res.type, url: item.tempFilePath, thumb: res.type === 'video' ? item.thumbTempFilePath : item.tempFilePath }))); | 36 | + return res.tempFiles.map((item) => (Object.assign(Object.assign({}, pickExclude(item, ['fileType', 'thumbTempFilePath', 'tempFilePath'])), { type: item.fileType, url: item.tempFilePath, thumb: item.fileType === 'video' ? item.thumbTempFilePath : item.tempFilePath }))); |
| 37 | } | 37 | } |
| 38 | function formatFile(res) { | 38 | function formatFile(res) { |
| 39 | return res.tempFiles.map((item) => (Object.assign(Object.assign({}, pickExclude(item, ['path'])), { url: item.path }))); | 39 | return res.tempFiles.map((item) => (Object.assign(Object.assign({}, pickExclude(item, ['path'])), { url: item.path }))); |
| 40 | } | 40 | } |
| 41 | -export function chooseFile({ accept, multiple, capture, compressed, maxDuration, sizeType, camera, maxCount, }) { | 41 | +export function chooseFile({ accept, multiple, capture, compressed, maxDuration, sizeType, camera, maxCount, mediaType, extension, }) { |
| 42 | return new Promise((resolve, reject) => { | 42 | return new Promise((resolve, reject) => { |
| 43 | switch (accept) { | 43 | switch (accept) { |
| 44 | case 'image': | 44 | case 'image': |
| 45 | + if (isPC || isWxWork) { | ||
| 45 | wx.chooseImage({ | 46 | wx.chooseImage({ |
| 46 | count: multiple ? Math.min(maxCount, 9) : 1, | 47 | count: multiple ? Math.min(maxCount, 9) : 1, |
| 47 | sourceType: capture, | 48 | sourceType: capture, |
| ... | @@ -49,10 +50,24 @@ export function chooseFile({ accept, multiple, capture, compressed, maxDuration, | ... | @@ -49,10 +50,24 @@ export function chooseFile({ accept, multiple, capture, compressed, maxDuration, |
| 49 | success: (res) => resolve(formatImage(res)), | 50 | success: (res) => resolve(formatImage(res)), |
| 50 | fail: reject, | 51 | fail: reject, |
| 51 | }); | 52 | }); |
| 53 | + } | ||
| 54 | + else { | ||
| 55 | + wx.chooseMedia({ | ||
| 56 | + count: multiple ? Math.min(maxCount, 9) : 1, | ||
| 57 | + mediaType: ['image'], | ||
| 58 | + sourceType: capture, | ||
| 59 | + maxDuration, | ||
| 60 | + sizeType, | ||
| 61 | + camera, | ||
| 62 | + success: (res) => resolve(formatImage(res)), | ||
| 63 | + fail: reject, | ||
| 64 | + }); | ||
| 65 | + } | ||
| 52 | break; | 66 | break; |
| 53 | case 'media': | 67 | case 'media': |
| 54 | wx.chooseMedia({ | 68 | wx.chooseMedia({ |
| 55 | count: multiple ? Math.min(maxCount, 9) : 1, | 69 | count: multiple ? Math.min(maxCount, 9) : 1, |
| 70 | + mediaType, | ||
| 56 | sourceType: capture, | 71 | sourceType: capture, |
| 57 | maxDuration, | 72 | maxDuration, |
| 58 | sizeType, | 73 | sizeType, |
| ... | @@ -72,12 +87,7 @@ export function chooseFile({ accept, multiple, capture, compressed, maxDuration, | ... | @@ -72,12 +87,7 @@ export function chooseFile({ accept, multiple, capture, compressed, maxDuration, |
| 72 | }); | 87 | }); |
| 73 | break; | 88 | break; |
| 74 | default: | 89 | default: |
| 75 | - wx.chooseMessageFile({ | 90 | + wx.chooseMessageFile(Object.assign(Object.assign({ count: multiple ? maxCount : 1, type: accept }, (extension ? { extension } : {})), { success: (res) => resolve(formatFile(res)), fail: reject })); |
| 76 | - count: multiple ? maxCount : 1, | ||
| 77 | - type: accept, | ||
| 78 | - success: (res) => resolve(formatFile(res)), | ||
| 79 | - fail: reject, | ||
| 80 | - }); | ||
| 81 | break; | 91 | break; |
| 82 | } | 92 | } |
| 83 | }); | 93 | }); | ... | ... |
-
Please register or login to post a comment