wx-mini-weview
Version:
weixin UI
401 lines (362 loc) • 11.3 kB
JavaScript
const { WvInheritable } = require('../../behaviors/WvInheritable');
Component({
options: {
styleIsolation: 'apply-shared',
multipleSlots: true
},
relations: {
'../steps-node/steps-node': {
type: 'child',
linked(target) {
// 设置节点索引
const index = this.getChildrenNodes('stepsNodes')?.length || 0;
target.setData({ index });
// 使用WvInheritable的方法注册子节点
this.linkChildNode('stepsNodes', target);
// 更新步骤节点
this.updateStepsNodes();
},
linkChanged() {
this.updateStepsNodes();
},
unlinked(target) {
// 使用WvInheritable的方法注销子节点
this.unlinkChildNode('stepsNodes', target);
this.updateStepsNodes();
}
}
},
behaviors: [
WvInheritable({
properties: {},
childrenProperties: {
stepsNodes: {
// 各状态对应的图标
waitingIcon: {
type: String,
value: '' // 默认显示数字
},
processIcon: {
type: String,
value: 'STEPS_INDEX' // 默认显示数字
},
finishIcon: {
type: String,
value: 'bi-check' // 默认显示对勾
},
errorIcon: {
type: String,
value: 'bi-x' // 默认显示叉
},
// 各状态主题
waitingTheme: {
type: String,
value: 'wv-theme-light wv-content-dark'
},
processTheme: {
type: String,
value: 'wv-theme-primary wv-content-light'
},
finishTheme: {
type: String,
value: 'wv-theme-success wv-content-light'
},
errorTheme: {
type: String,
value: 'wv-theme-error wv-content-light'
},
hiddenStatusDesc: {
type: Boolean,
value: false
},
waitingIconTextColor: {
type: String,
value: ''
},
processIconTextColor: {
type: String,
value: ''
},
finishIconTextColor: {
type: String,
value: ''
},
errorIconTextColor: {
type: String,
value: ''
},
// Icon background colors
markWidth: {
type: String,
value: '140rpx'
},
markHeight: {
type: String,
value: '140rpx'
},
waitingIconColor: {
type: String,
value: ''
},
processIconColor: {
type: String,
value: ''
},
finishIconColor: {
type: String,
value: ''
},
errorIconColor: {
type: String,
value: ''
},
// Title colors
waitingTitleColor: {
type: String,
value: 'unset'
},
processTitleColor: {
type: String,
value: ''
},
finishTitleColor: {
type: String,
value: ''
},
errorTitleColor: {
type: String,
value: ''
},
// 设置最小宽度
minWidth: {
type: String,
value: '120rpx'
},
// 设置最大高度
maxHeight: {
type: String,
value: '300rpx'
},
// Marker scale for different states
markWidth: {
type: String,
value: '40rpx'
},
markHeight: {
type: String,
value: '40rpx'
},
waitingMarkScale: {
type: Number,
value: 0.5
},
processMarkScale: {
type: Number,
value: 0.7
},
finishMarkScale: {
type: Number,
value: 1
},
errorMarkScale: {
type: Number,
value: 1
}
}
}
})
],
properties: {
connectorThickness: {
type: String,
value: '10rpx'
},
// 等待状态的节点值数组
waitingValues: {
type: Array,
value: []
},
// 进行中状态的节点值数组
processValues: {
type: Array,
value: []
},
// 完成状态的节点值数组
finishValues: {
type: Array,
value: []
},
// 错误状态的节点值数组
errorValues: {
type: Array,
value: []
},
linkWaitingTheme: {
type: String,
value: 'wv-theme-light wv-content-dark'
},
linkProcessTheme: {
type: String,
value: 'wv-theme-primary wv-content-light'
},
linkFinishTheme: {
type: String,
value: 'wv-theme-success wv-content-light'
},
linkErrorTheme: {
type: String,
value: 'wv-theme-error wv-content-light'
},
// 是否简洁模式,简化连接线
simple: {
type: Boolean,
value: false
},
// 节点之间的间距
nodeGap: {
type: String,
value: '40rpx'
},
// 水平布局是否平均分布
full: {
type: Boolean,
value: true
},
// 水平布局宽度
width: {
type: String,
value: '100%'
}
},
data: {
stepsNodes: [],
stepsCount: 0,
connectors: [],
_debounceCalculateConnectorsTimer: null,
_debounceUpdateStepsNodesTimer: null
},
lifetimes: {
attached() {
this.updateStepsNodes();
},
ready() {
this.calculateConnectors();
},
detached() {
if (this.data._debounceCalculateConnectorsTimer) {
clearTimeout(this.data._debounceCalculateConnectorsTimer);
}
if (this.data._debounceUpdateStepsNodesTimer) {
clearTimeout(this.data._debounceUpdateStepsNodesTimer);
}
}
},
observers: {
'waitingValues, processValues, finishValues, errorValues': function() {
if (this.data.stepsNodes.length > 0) {
wx.nextTick(() => {
this.updateStepsNodes();
});
}
}
},
methods: {
updateStepsNodes() {
if (this.data._debounceUpdateStepsNodesTimer) {
clearTimeout(this.data._debounceUpdateStepsNodesTimer);
}
this.data._debounceUpdateStepsNodesTimer = setTimeout(() => {
const nodes = this.getChildrenNodes('stepsNodes') || [];
if (!nodes || nodes.length === 0) return;
const { waitingValues, processValues, finishValues, errorValues } = this.data;
// 计算状态并通知节点更新
nodes.forEach((node, index) => {
const nodeValue = node.data.value;
if (nodeValue === undefined) {
console.error('Steps node missing required value property');
return;
}
// 根据value匹配状态
let status = 'waiting'; // 默认状态
if (errorValues && errorValues.includes(nodeValue)) {
status = 'error';
} else if (finishValues && finishValues.includes(nodeValue)) {
status = 'finish';
} else if (processValues && processValues.includes(nodeValue)) {
status = 'process';
} else if (waitingValues && waitingValues.includes(nodeValue)) {
status = 'waiting';
}
node.setInheritedProps({
status: status
});
node.updateNodePosition(index, nodes.length);
});
this.setData({
stepsNodes: nodes,
stepsCount: nodes.length
}, () => {
if (nodes.length > 0) {
wx.nextTick(() => {
this.calculateConnectors();
});
}
});
}, 300);
},
calculateConnectors() {
if (this.data._debounceCalculateConnectorsTimer) {
clearTimeout(this.data._debounceCalculateConnectorsTimer);
}
this.data._debounceCalculateConnectorsTimer = setTimeout(() => {
const { current } = this.data;
const nodes = this.getChildrenNodes('stepsNodes') || [];
if (!nodes || nodes.length <= 1) return;
const markerPromises = nodes.map(node =>
node.getMarkerCoord().then(coords => ({
coords,
status: node.data.wvInheritableApply.status
}))
);
Promise.all(markerPromises)
.then(results => {
const connectors = [];
for (let i = 0; i < results.length - 1; i++) {
const current = results[i].coords;
const next = results[i+1].coords;
const status = results[i+1].status;
if (!current || !next) continue;
let statusTheme;
switch (status) {
case 'process':
statusTheme = this.data.linkProcessTheme;
break;
case 'finish':
statusTheme = this.data.linkFinishTheme;
break;
case 'error':
statusTheme = this.data.linkErrorTheme;
break;
case 'waiting':
default:
statusTheme = this.data.linkWaitingTheme;
break;
}
const connector = {
left: current.x,
top: current.y,
length: next.x - current.x,
status: status,
statusTheme: statusTheme
};
connectors.push(connector);
}
this.setData({ connectors });
})
.catch(err => {
console.error('获取marker坐标失败', err);
});
}, 300);
}
}
});