20 changed files with 1202 additions and 632 deletions
@ -1,197 +1,233 @@
|
||||
import { BLUE, WHITE } from '../common/color'; |
||||
import { VantComponent } from '../common/component'; |
||||
import { getSystemInfoSync } from '../common/utils'; |
||||
import { isObj } from '../common/validator'; |
||||
import { canIUseCanvas2d } from '../common/version'; |
||||
import { adaptor } from './canvas'; |
||||
import { |
||||
BLUE, |
||||
WHITE |
||||
} from '../common/color'; |
||||
import { |
||||
VantComponent |
||||
} from '../common/component'; |
||||
import { |
||||
getSystemInfoSync |
||||
} from '../common/utils'; |
||||
import { |
||||
isObj |
||||
} from '../common/validator'; |
||||
import { |
||||
canIUseCanvas2d |
||||
} from '../common/version'; |
||||
import { |
||||
adaptor |
||||
} from './canvas'; |
||||
|
||||
function format(rate) { |
||||
return Math.min(Math.max(rate, 0), 100); |
||||
return Math.min(Math.max(rate, 0), 100); |
||||
} |
||||
const PERIMETER = 2 * Math.PI; |
||||
const BEGIN_ANGLE = -Math.PI / 2; |
||||
const STEP = 1; |
||||
VantComponent({ |
||||
props: { |
||||
text: String, |
||||
lineCap: { |
||||
type: String, |
||||
value: 'round', |
||||
}, |
||||
value: { |
||||
type: Number, |
||||
value: 0, |
||||
observer: 'reRender', |
||||
}, |
||||
speed: { |
||||
type: Number, |
||||
value: 50, |
||||
}, |
||||
size: { |
||||
type: Number, |
||||
value: 100, |
||||
observer() { |
||||
this.drawCircle(this.currentValue); |
||||
}, |
||||
}, |
||||
fill: String, |
||||
layerColor: { |
||||
type: String, |
||||
value: WHITE, |
||||
}, |
||||
color: { |
||||
type: null, |
||||
value: BLUE, |
||||
observer() { |
||||
this.setHoverColor().then(() => { |
||||
this.drawCircle(this.currentValue); |
||||
}); |
||||
}, |
||||
}, |
||||
type: { |
||||
type: String, |
||||
value: '', |
||||
}, |
||||
strokeWidth: { |
||||
type: Number, |
||||
value: 4, |
||||
}, |
||||
clockwise: { |
||||
type: Boolean, |
||||
value: true, |
||||
}, |
||||
}, |
||||
data: { |
||||
hoverColor: BLUE, |
||||
}, |
||||
methods: { |
||||
getContext() { |
||||
const { type, size } = this.data; |
||||
if (type === '' || !canIUseCanvas2d()) { |
||||
const ctx = wx.createCanvasContext('van-circle', this); |
||||
return Promise.resolve(ctx); |
||||
} |
||||
const dpr = getSystemInfoSync().pixelRatio; |
||||
return new Promise((resolve) => { |
||||
wx.createSelectorQuery() |
||||
.in(this) |
||||
.select('#van-circle') |
||||
.node() |
||||
.exec((res) => { |
||||
const canvas = res[0].node; |
||||
const ctx = canvas.getContext(type); |
||||
if (!this.inited) { |
||||
this.inited = true; |
||||
canvas.width = size * dpr; |
||||
canvas.height = size * dpr; |
||||
ctx.scale(dpr, dpr); |
||||
} |
||||
resolve(adaptor(ctx)); |
||||
}); |
||||
}); |
||||
}, |
||||
setHoverColor() { |
||||
const { color, size } = this.data; |
||||
if (isObj(color)) { |
||||
return this.getContext().then((context) => { |
||||
if (!context) |
||||
return; |
||||
const LinearColor = context.createLinearGradient(size, 0, 0, 0); |
||||
Object.keys(color) |
||||
.sort((a, b) => parseFloat(a) - parseFloat(b)) |
||||
.map((key) => LinearColor.addColorStop(parseFloat(key) / 100, color[key])); |
||||
this.hoverColor = LinearColor; |
||||
}); |
||||
} |
||||
this.hoverColor = color; |
||||
return Promise.resolve(); |
||||
}, |
||||
presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) { |
||||
const { strokeWidth, lineCap, clockwise, size } = this.data; |
||||
const position = size / 2; |
||||
const radius = position - strokeWidth / 2; |
||||
context.setStrokeStyle(strokeStyle); |
||||
context.setLineWidth(strokeWidth); |
||||
context.setLineCap(lineCap); |
||||
context.beginPath(); |
||||
context.arc(position, position, radius, beginAngle, endAngle, !clockwise); |
||||
context.stroke(); |
||||
if (fill) { |
||||
context.setFillStyle(fill); |
||||
context.fill(); |
||||
} |
||||
}, |
||||
renderLayerCircle(context) { |
||||
const { layerColor, fill } = this.data; |
||||
this.presetCanvas(context, layerColor, 0, PERIMETER, fill); |
||||
}, |
||||
renderHoverCircle(context, formatValue) { |
||||
const { clockwise } = this.data; |
||||
// 结束角度
|
||||
const progress = PERIMETER * (formatValue / 100); |
||||
const endAngle = clockwise |
||||
? BEGIN_ANGLE + progress |
||||
: 3 * Math.PI - (BEGIN_ANGLE + progress); |
||||
this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle); |
||||
}, |
||||
drawCircle(currentValue) { |
||||
const { size } = this.data; |
||||
this.getContext().then((context) => { |
||||
if (!context) |
||||
return; |
||||
context.clearRect(0, 0, size, size); |
||||
this.renderLayerCircle(context); |
||||
const formatValue = format(currentValue); |
||||
if (formatValue !== 0) { |
||||
this.renderHoverCircle(context, formatValue); |
||||
} |
||||
context.draw(); |
||||
}); |
||||
}, |
||||
reRender() { |
||||
// tofector 动画暂时没有想到好的解决方案
|
||||
const { value, speed } = this.data; |
||||
if (speed <= 0 || speed > 1000) { |
||||
this.drawCircle(value); |
||||
return; |
||||
} |
||||
this.clearMockInterval(); |
||||
this.currentValue = this.currentValue || 0; |
||||
const run = () => { |
||||
this.interval = setTimeout(() => { |
||||
if (this.currentValue !== value) { |
||||
if (Math.abs(this.currentValue - value) < STEP) { |
||||
this.currentValue = value; |
||||
} |
||||
else if (this.currentValue < value) { |
||||
this.currentValue += STEP; |
||||
} |
||||
else { |
||||
this.currentValue -= STEP; |
||||
} |
||||
this.drawCircle(this.currentValue); |
||||
run(); |
||||
} |
||||
else { |
||||
this.clearMockInterval(); |
||||
} |
||||
}, 1000 / speed); |
||||
}; |
||||
run(); |
||||
}, |
||||
clearMockInterval() { |
||||
if (this.interval) { |
||||
clearTimeout(this.interval); |
||||
this.interval = null; |
||||
} |
||||
}, |
||||
}, |
||||
mounted() { |
||||
this.currentValue = this.data.value; |
||||
this.setHoverColor().then(() => { |
||||
this.drawCircle(this.currentValue); |
||||
}); |
||||
}, |
||||
destroyed() { |
||||
this.clearMockInterval(); |
||||
}, |
||||
}); |
||||
props: { |
||||
text: String, |
||||
lineCap: { |
||||
type: String, |
||||
value: 'round', |
||||
}, |
||||
value: { |
||||
type: Number, |
||||
value: 0, |
||||
observer: 'reRender', |
||||
}, |
||||
speed: { |
||||
type: Number, |
||||
value: 50, |
||||
}, |
||||
size: { |
||||
type: Number, |
||||
value: 100, |
||||
observer() { |
||||
this.drawCircle(this.currentValue); |
||||
}, |
||||
}, |
||||
fill: String, |
||||
layerColor: { |
||||
type: String, |
||||
value: WHITE, |
||||
}, |
||||
color: { |
||||
type: null, |
||||
value: BLUE, |
||||
observer() { |
||||
this.setHoverColor().then(() => { |
||||
this.drawCircle(this.currentValue); |
||||
}); |
||||
}, |
||||
}, |
||||
type: { |
||||
type: String, |
||||
value: '', |
||||
}, |
||||
strokeWidth: { |
||||
type: Number, |
||||
value: 4, |
||||
}, |
||||
clockwise: { |
||||
type: Boolean, |
||||
value: true, |
||||
}, |
||||
canvasId: { |
||||
type: String, |
||||
value: '' |
||||
} |
||||
}, |
||||
data: { |
||||
hoverColor: BLUE, |
||||
}, |
||||
methods: { |
||||
getContext() { |
||||
const { |
||||
type, |
||||
size |
||||
} = this.data; |
||||
if (type === '' || !canIUseCanvas2d()) { |
||||
const ctx = wx.createCanvasContext('van-circle', this); |
||||
return Promise.resolve(ctx); |
||||
} |
||||
const dpr = getSystemInfoSync().pixelRatio; |
||||
return new Promise((resolve) => { |
||||
wx.createSelectorQuery() |
||||
.in(this) |
||||
.select('#van-circle') |
||||
.node() |
||||
.exec((res) => { |
||||
const canvas = res[0].node; |
||||
const ctx = canvas.getContext(type); |
||||
if (!this.inited) { |
||||
this.inited = true; |
||||
canvas.width = size * dpr; |
||||
canvas.height = size * dpr; |
||||
ctx.scale(dpr, dpr); |
||||
} |
||||
resolve(adaptor(ctx)); |
||||
}); |
||||
}); |
||||
}, |
||||
setHoverColor() { |
||||
const { |
||||
color, |
||||
size |
||||
} = this.data; |
||||
if (isObj(color)) { |
||||
return this.getContext().then((context) => { |
||||
if (!context) |
||||
return; |
||||
const LinearColor = context.createLinearGradient(size, 0, 0, 0); |
||||
Object.keys(color) |
||||
.sort((a, b) => parseFloat(a) - parseFloat(b)) |
||||
.map((key) => LinearColor.addColorStop(parseFloat(key) / 100, color[key])); |
||||
this.hoverColor = LinearColor; |
||||
}); |
||||
} |
||||
this.hoverColor = color; |
||||
return Promise.resolve(); |
||||
}, |
||||
presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) { |
||||
const { |
||||
strokeWidth, |
||||
lineCap, |
||||
clockwise, |
||||
size |
||||
} = this.data; |
||||
const position = size / 2; |
||||
const radius = position - strokeWidth / 2; |
||||
context.setStrokeStyle(strokeStyle); |
||||
context.setLineWidth(strokeWidth); |
||||
context.setLineCap(lineCap); |
||||
context.beginPath(); |
||||
context.arc(position, position, radius, beginAngle, endAngle, !clockwise); |
||||
context.stroke(); |
||||
if (fill) { |
||||
context.setFillStyle(fill); |
||||
context.fill(); |
||||
} |
||||
}, |
||||
renderLayerCircle(context) { |
||||
const { |
||||
layerColor, |
||||
fill |
||||
} = this.data; |
||||
this.presetCanvas(context, layerColor, 0, PERIMETER, fill); |
||||
}, |
||||
renderHoverCircle(context, formatValue) { |
||||
const { |
||||
clockwise |
||||
} = this.data; |
||||
// 结束角度
|
||||
const progress = PERIMETER * (formatValue / 100); |
||||
const endAngle = clockwise ? |
||||
BEGIN_ANGLE + progress : |
||||
3 * Math.PI - (BEGIN_ANGLE + progress); |
||||
this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle); |
||||
}, |
||||
drawCircle(currentValue) { |
||||
const { |
||||
size |
||||
} = this.data; |
||||
this.getContext().then((context) => { |
||||
if (!context) |
||||
return; |
||||
context.clearRect(0, 0, size, size); |
||||
this.renderLayerCircle(context); |
||||
const formatValue = format(currentValue); |
||||
if (formatValue !== 0) { |
||||
this.renderHoverCircle(context, formatValue); |
||||
} |
||||
context.draw(); |
||||
}); |
||||
}, |
||||
reRender() { |
||||
// tofector 动画暂时没有想到好的解决方案
|
||||
const { |
||||
value, |
||||
speed |
||||
} = this.data; |
||||
if (speed <= 0 || speed > 1000) { |
||||
this.drawCircle(value); |
||||
return; |
||||
} |
||||
this.clearMockInterval(); |
||||
this.currentValue = this.currentValue || 0; |
||||
const run = () => { |
||||
this.interval = setTimeout(() => { |
||||
if (this.currentValue !== value) { |
||||
if (Math.abs(this.currentValue - value) < STEP) { |
||||
this.currentValue = value; |
||||
} else if (this.currentValue < value) { |
||||
this.currentValue += STEP; |
||||
} else { |
||||
this.currentValue -= STEP; |
||||
} |
||||
this.drawCircle(this.currentValue); |
||||
run(); |
||||
} else { |
||||
this.clearMockInterval(); |
||||
} |
||||
}, 1000 / speed); |
||||
}; |
||||
run(); |
||||
}, |
||||
clearMockInterval() { |
||||
if (this.interval) { |
||||
clearTimeout(this.interval); |
||||
this.interval = null; |
||||
} |
||||
}, |
||||
}, |
||||
mounted() { |
||||
this.currentValue = this.data.value; |
||||
this.setHoverColor().then(() => { |
||||
this.drawCircle(this.currentValue); |
||||
}); |
||||
}, |
||||
destroyed() { |
||||
this.clearMockInterval(); |
||||
}, |
||||
}); |
@ -1 +1,16 @@
|
||||
@import '../common/index.wxss';.van-circle{display:inline-block;position:relative;text-align:center}.van-circle__text{color:var(--circle-text-color,#323233);left:0;position:absolute;top:50%;transform:translateY(-50%);width:100%} |
||||
@import '../common/index.wxss'; |
||||
|
||||
.van-circle { |
||||
display: inline-block; |
||||
position: relative; |
||||
text-align: center |
||||
} |
||||
|
||||
.van-circle__text { |
||||
color: var(--circle-text-color, #323233); |
||||
left: 0; |
||||
position: absolute; |
||||
top: 50%; |
||||
transform: translateY(-50%); |
||||
width: 100% |
||||
} |
@ -1,130 +1,157 @@
|
||||
import { useParent } from '../common/relation'; |
||||
import { VantComponent } from '../common/component'; |
||||
import { |
||||
useParent |
||||
} from '../common/relation'; |
||||
import { |
||||
VantComponent |
||||
} from '../common/component'; |
||||
VantComponent({ |
||||
classes: ['item-title-class'], |
||||
field: true, |
||||
relation: useParent('dropdown-menu', function () { |
||||
this.updateDataFromParent(); |
||||
}), |
||||
props: { |
||||
value: { |
||||
type: null, |
||||
observer: 'rerender', |
||||
}, |
||||
title: { |
||||
type: String, |
||||
observer: 'rerender', |
||||
}, |
||||
disabled: Boolean, |
||||
titleClass: { |
||||
type: String, |
||||
observer: 'rerender', |
||||
}, |
||||
options: { |
||||
type: Array, |
||||
value: [], |
||||
observer: 'rerender', |
||||
}, |
||||
popupStyle: String, |
||||
useBeforeToggle: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
rootPortal: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
}, |
||||
data: { |
||||
transition: true, |
||||
showPopup: false, |
||||
showWrapper: false, |
||||
displayTitle: '', |
||||
safeAreaTabBar: false, |
||||
}, |
||||
methods: { |
||||
rerender() { |
||||
wx.nextTick(() => { |
||||
var _a; |
||||
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.updateItemListData(); |
||||
}); |
||||
}, |
||||
updateDataFromParent() { |
||||
if (this.parent) { |
||||
const { overlay, duration, activeColor, closeOnClickOverlay, direction, safeAreaTabBar, } = this.parent.data; |
||||
this.setData({ |
||||
overlay, |
||||
duration, |
||||
activeColor, |
||||
closeOnClickOverlay, |
||||
direction, |
||||
safeAreaTabBar, |
||||
}); |
||||
} |
||||
}, |
||||
onOpen() { |
||||
this.$emit('open'); |
||||
}, |
||||
onOpened() { |
||||
this.$emit('opened'); |
||||
}, |
||||
onClose() { |
||||
this.$emit('close'); |
||||
}, |
||||
onClosed() { |
||||
this.$emit('closed'); |
||||
this.setData({ showWrapper: false }); |
||||
}, |
||||
onOptionTap(event) { |
||||
const { option } = event.currentTarget.dataset; |
||||
const { value } = option; |
||||
const shouldEmitChange = this.data.value !== value; |
||||
this.setData({ showPopup: false, value }); |
||||
this.$emit('close'); |
||||
this.rerender(); |
||||
if (shouldEmitChange) { |
||||
this.$emit('change', value); |
||||
} |
||||
}, |
||||
toggle(show, options = {}) { |
||||
const { showPopup } = this.data; |
||||
if (typeof show !== 'boolean') { |
||||
show = !showPopup; |
||||
} |
||||
if (show === showPopup) { |
||||
return; |
||||
} |
||||
this.onBeforeToggle(show).then((status) => { |
||||
var _a; |
||||
if (!status) { |
||||
return; |
||||
} |
||||
this.setData({ |
||||
transition: !options.immediate, |
||||
showPopup: show, |
||||
}); |
||||
if (show) { |
||||
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.getChildWrapperStyle().then((wrapperStyle) => { |
||||
this.setData({ wrapperStyle, showWrapper: true }); |
||||
this.rerender(); |
||||
}); |
||||
} |
||||
else { |
||||
this.rerender(); |
||||
} |
||||
}); |
||||
}, |
||||
onBeforeToggle(status) { |
||||
const { useBeforeToggle } = this.data; |
||||
if (!useBeforeToggle) { |
||||
return Promise.resolve(true); |
||||
} |
||||
return new Promise((resolve) => { |
||||
this.$emit('before-toggle', { |
||||
status, |
||||
callback: (value) => resolve(value), |
||||
}); |
||||
}); |
||||
}, |
||||
}, |
||||
}); |
||||
classes: ['item-title-class'], |
||||
field: true, |
||||
relation: useParent('dropdown-menu', function() { |
||||
this.updateDataFromParent(); |
||||
}), |
||||
props: { |
||||
value: { |
||||
type: null, |
||||
observer: 'rerender', |
||||
}, |
||||
title: { |
||||
type: String, |
||||
observer: 'rerender', |
||||
}, |
||||
disabled: Boolean, |
||||
titleClass: { |
||||
type: String, |
||||
observer: 'rerender', |
||||
}, |
||||
options: { |
||||
type: Array, |
||||
value: [], |
||||
observer: 'rerender', |
||||
}, |
||||
popupStyle: String, |
||||
useBeforeToggle: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
rootPortal: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
}, |
||||
data: { |
||||
transition: true, |
||||
showPopup: false, |
||||
showWrapper: false, |
||||
displayTitle: '', |
||||
safeAreaTabBar: false, |
||||
}, |
||||
methods: { |
||||
rerender() { |
||||
wx.nextTick(() => { |
||||
var _a; |
||||
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.updateItemListData(); |
||||
}); |
||||
}, |
||||
updateDataFromParent() { |
||||
if (this.parent) { |
||||
const { |
||||
overlay, |
||||
duration, |
||||
activeColor, |
||||
closeOnClickOverlay, |
||||
direction, |
||||
safeAreaTabBar, |
||||
} = this.parent.data; |
||||
this.setData({ |
||||
overlay, |
||||
duration, |
||||
activeColor, |
||||
closeOnClickOverlay, |
||||
direction, |
||||
safeAreaTabBar, |
||||
}); |
||||
} |
||||
}, |
||||
onOpen() { |
||||
this.$emit('open'); |
||||
}, |
||||
onOpened() { |
||||
this.$emit('opened'); |
||||
}, |
||||
onClose() { |
||||
this.$emit('close'); |
||||
}, |
||||
onClosed() { |
||||
this.$emit('closed'); |
||||
this.setData({ |
||||
showWrapper: false |
||||
}); |
||||
}, |
||||
onOptionTap(event) { |
||||
const { |
||||
option |
||||
} = event.currentTarget.dataset; |
||||
const { |
||||
value |
||||
} = option; |
||||
const shouldEmitChange = this.data.value !== value; |
||||
this.setData({ |
||||
showPopup: false, |
||||
value |
||||
}); |
||||
this.$emit('close'); |
||||
this.rerender(); |
||||
if (shouldEmitChange) { |
||||
this.$emit('change', value); |
||||
} |
||||
}, |
||||
toggle(show, options = {}) { |
||||
const { |
||||
showPopup |
||||
} = this.data; |
||||
if (typeof show !== 'boolean') { |
||||
show = !showPopup; |
||||
} |
||||
if (show === showPopup) { |
||||
return; |
||||
} |
||||
this.onBeforeToggle(show).then((status) => { |
||||
var _a; |
||||
if (!status) { |
||||
return; |
||||
} |
||||
this.setData({ |
||||
transition: !options.immediate, |
||||
showPopup: show, |
||||
}); |
||||
if (show) { |
||||
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.getChildWrapperStyle().then(( |
||||
wrapperStyle) => { |
||||
this.setData({ |
||||
wrapperStyle, |
||||
showWrapper: true |
||||
}); |
||||
this.rerender(); |
||||
}); |
||||
} else { |
||||
this.rerender(); |
||||
} |
||||
}); |
||||
}, |
||||
onBeforeToggle(status) { |
||||
const { |
||||
useBeforeToggle |
||||
} = this.data; |
||||
if (!useBeforeToggle) { |
||||
return Promise.resolve(true); |
||||
} |
||||
return new Promise((resolve) => { |
||||
this.$emit('before-toggle', { |
||||
status, |
||||
callback: (value) => resolve(value), |
||||
}); |
||||
}); |
||||
}, |
||||
}, |
||||
}); |
@ -1,117 +1,139 @@
|
||||
import { VantComponent } from '../common/component'; |
||||
import { useChildren } from '../common/relation'; |
||||
import { addUnit, getRect, getSystemInfoSync } from '../common/utils'; |
||||
import { |
||||
VantComponent |
||||
} from '../common/component'; |
||||
import { |
||||
useChildren |
||||
} from '../common/relation'; |
||||
import { |
||||
addUnit, |
||||
getRect, |
||||
getSystemInfoSync |
||||
} from '../common/utils'; |
||||
let ARRAY = []; |
||||
VantComponent({ |
||||
field: true, |
||||
classes: ['title-class'], |
||||
relation: useChildren('dropdown-item', function () { |
||||
this.updateItemListData(); |
||||
}), |
||||
props: { |
||||
activeColor: { |
||||
type: String, |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
overlay: { |
||||
type: Boolean, |
||||
value: true, |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
zIndex: { |
||||
type: Number, |
||||
value: 10, |
||||
}, |
||||
duration: { |
||||
type: Number, |
||||
value: 200, |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
direction: { |
||||
type: String, |
||||
value: 'down', |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
safeAreaTabBar: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
closeOnClickOverlay: { |
||||
type: Boolean, |
||||
value: true, |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
closeOnClickOutside: { |
||||
type: Boolean, |
||||
value: true, |
||||
}, |
||||
}, |
||||
data: { |
||||
itemListData: [], |
||||
}, |
||||
beforeCreate() { |
||||
const { windowHeight } = getSystemInfoSync(); |
||||
this.windowHeight = windowHeight; |
||||
ARRAY.push(this); |
||||
}, |
||||
destroyed() { |
||||
ARRAY = ARRAY.filter((item) => item !== this); |
||||
}, |
||||
methods: { |
||||
updateItemListData() { |
||||
this.setData({ |
||||
itemListData: this.children.map((child) => child.data), |
||||
}); |
||||
}, |
||||
updateChildrenData() { |
||||
this.children.forEach((child) => { |
||||
child.updateDataFromParent(); |
||||
}); |
||||
}, |
||||
toggleItem(active) { |
||||
this.children.forEach((item, index) => { |
||||
const { showPopup } = item.data; |
||||
if (index === active) { |
||||
item.toggle(); |
||||
} |
||||
else if (showPopup) { |
||||
item.toggle(false, { immediate: true }); |
||||
} |
||||
}); |
||||
}, |
||||
close() { |
||||
this.children.forEach((child) => { |
||||
child.toggle(false, { immediate: true }); |
||||
}); |
||||
}, |
||||
getChildWrapperStyle() { |
||||
const { zIndex, direction } = this.data; |
||||
return getRect(this, '.van-dropdown-menu').then((rect) => { |
||||
const { top = 0, bottom = 0 } = rect; |
||||
const offset = direction === 'down' ? bottom : this.windowHeight - top; |
||||
let wrapperStyle = `z-index: ${zIndex};`; |
||||
if (direction === 'down') { |
||||
wrapperStyle += `top: ${addUnit(offset)};`; |
||||
} |
||||
else { |
||||
wrapperStyle += `bottom: ${addUnit(offset)};`; |
||||
} |
||||
return wrapperStyle; |
||||
}); |
||||
}, |
||||
onTitleTap(event) { |
||||
const { index } = event.currentTarget.dataset; |
||||
const child = this.children[index]; |
||||
if (!child.data.disabled) { |
||||
ARRAY.forEach((menuItem) => { |
||||
if (menuItem && |
||||
menuItem.data.closeOnClickOutside && |
||||
menuItem !== this) { |
||||
menuItem.close(); |
||||
} |
||||
}); |
||||
this.toggleItem(index); |
||||
} |
||||
}, |
||||
}, |
||||
}); |
||||
field: true, |
||||
classes: ['title-class'], |
||||
relation: useChildren('dropdown-item', function() { |
||||
this.updateItemListData(); |
||||
}), |
||||
props: { |
||||
activeColor: { |
||||
type: String, |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
overlay: { |
||||
type: Boolean, |
||||
value: true, |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
zIndex: { |
||||
type: Number, |
||||
value: 10, |
||||
}, |
||||
duration: { |
||||
type: Number, |
||||
value: 200, |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
direction: { |
||||
type: String, |
||||
value: 'down', |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
safeAreaTabBar: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
closeOnClickOverlay: { |
||||
type: Boolean, |
||||
value: true, |
||||
observer: 'updateChildrenData', |
||||
}, |
||||
closeOnClickOutside: { |
||||
type: Boolean, |
||||
value: true, |
||||
}, |
||||
}, |
||||
data: { |
||||
itemListData: [], |
||||
currentValue: '' |
||||
}, |
||||
beforeCreate() { |
||||
const { |
||||
windowHeight |
||||
} = getSystemInfoSync(); |
||||
this.windowHeight = windowHeight; |
||||
ARRAY.push(this); |
||||
}, |
||||
destroyed() { |
||||
ARRAY = ARRAY.filter((item) => item !== this); |
||||
}, |
||||
methods: { |
||||
updateItemListData() { |
||||
this.setData({ |
||||
itemListData: this.children.map((child) => child.data), |
||||
}); |
||||
}, |
||||
updateChildrenData() { |
||||
this.children.forEach((child) => { |
||||
child.updateDataFromParent(); |
||||
}); |
||||
}, |
||||
toggleItem(active) { |
||||
this.children.forEach((item, index) => { |
||||
const { |
||||
showPopup |
||||
} = item.data; |
||||
if (index === active) { |
||||
item.toggle(); |
||||
} else if (showPopup) { |
||||
item.toggle(false, { |
||||
immediate: true |
||||
}); |
||||
} |
||||
}); |
||||
}, |
||||
close() { |
||||
this.children.forEach((child) => { |
||||
child.toggle(false, { |
||||
immediate: true |
||||
}); |
||||
}); |
||||
}, |
||||
getChildWrapperStyle() { |
||||
const { |
||||
zIndex, |
||||
direction |
||||
} = this.data; |
||||
return getRect(this, '.van-dropdown-menu').then((rect) => { |
||||
const { |
||||
top = 0, bottom = 0 |
||||
} = rect; |
||||
const offset = direction === 'down' ? bottom : this.windowHeight - top; |
||||
let wrapperStyle = `z-index: ${zIndex};`; |
||||
if (direction === 'down') { |
||||
wrapperStyle += `top: ${addUnit(offset)};`; |
||||
} else { |
||||
wrapperStyle += `bottom: ${addUnit(offset)};`; |
||||
} |
||||
return wrapperStyle; |
||||
}); |
||||
}, |
||||
onTitleTap(event) { |
||||
const { |
||||
index |
||||
} = event.currentTarget.dataset; |
||||
const child = this.children[index]; |
||||
if (!child.data.disabled) { |
||||
ARRAY.forEach((menuItem) => { |
||||
if (menuItem && |
||||
menuItem.data.closeOnClickOutside && |
||||
menuItem !== this) { |
||||
menuItem.close(); |
||||
} |
||||
}); |
||||
this.toggleItem(index); |
||||
} |
||||
}, |
||||
}, |
||||
}); |
@ -1,16 +1,21 @@
|
||||
/* eslint-disable */ |
||||
function displayTitle(item) { |
||||
if (item.title) { |
||||
return item.title; |
||||
} |
||||
if (item.title) { |
||||
return item.title; |
||||
} |
||||
|
||||
var match = item.options.filter(function(option) { |
||||
return option.value === item.value; |
||||
}); |
||||
var displayTitle = match.length ? match[0].text : ''; |
||||
return displayTitle; |
||||
var match = item.options.filter(function(option) { |
||||
return option.value === item.value; |
||||
}); |
||||
var displayTitle = match.length ? match[0].text : ''; |
||||
return displayTitle; |
||||
} |
||||
|
||||
function setTitleColor(item) { |
||||
return item.value != '' ? '#17c653' : '' |
||||
} |
||||
|
||||
module.exports = { |
||||
displayTitle: displayTitle |
||||
}; |
||||
displayTitle: displayTitle, |
||||
setTitleColor: setTitleColor |
||||
}; |
Loading…
Reference in new issue