UNPKG

wx-mini-weview

Version:

weixin UI

401 lines (362 loc) 11.3 kB
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); } } });