Improve miniprogram phase1 event and request handling

This commit is contained in:
yumoqing 2026-05-19 01:21:51 +08:00
parent 13a770d56d
commit 8cbc573786
6 changed files with 54 additions and 17 deletions

1
app.js
View File

@ -30,6 +30,7 @@ App({
}, },
// entire_url: 拼接 baseUrl // entire_url: 拼接 baseUrl
entireUrl(path) { entireUrl(path) {
if (/^https?:\/\//.test(path)) return path
const base = this.globalData.baseUrl || '' const base = this.globalData.baseUrl || ''
return base.replace(/\/$/, '') + '/' + path.replace(/^\//, '') return base.replace(/\/$/, '') + '/' + path.replace(/^\//, '')
} }

View File

@ -5,31 +5,31 @@
<template name="brick"> <template name="brick">
<!-- 文本组件 --> <!-- 文本组件 -->
<block wx:if="{{item.widgettype === 'Text'}}"> <block wx:if="{{item.widgettype === 'Text'}}">
<text class="text-content">{{item.options.text}}</text> <text class="text-content" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">{{item.options.text}}</text>
</block> </block>
<block wx:if="{{item.widgettype === 'Title1'}}"> <block wx:if="{{item.widgettype === 'Title1'}}">
<text class="title-1">{{item.options.text}}</text> <text class="title-1" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">{{item.options.text}}</text>
</block> </block>
<block wx:if="{{item.widgettype === 'Title2'}}"> <block wx:if="{{item.widgettype === 'Title2'}}">
<text class="title-2">{{item.options.text}}</text> <text class="title-2" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">{{item.options.text}}</text>
</block> </block>
<block wx:if="{{item.widgettype === 'Title3'}}"> <block wx:if="{{item.widgettype === 'Title3'}}">
<text class="title-3">{{item.options.text}}</text> <text class="title-3" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">{{item.options.text}}</text>
</block> </block>
<block wx:if="{{item.widgettype === 'Title4'}}"> <block wx:if="{{item.widgettype === 'Title4'}}">
<text class="title-4">{{item.options.text}}</text> <text class="title-4" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">{{item.options.text}}</text>
</block> </block>
<block wx:if="{{item.widgettype === 'Title5'}}"> <block wx:if="{{item.widgettype === 'Title5'}}">
<text class="title-5">{{item.options.text}}</text> <text class="title-5" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">{{item.options.text}}</text>
</block> </block>
<block wx:if="{{item.widgettype === 'Title6'}}"> <block wx:if="{{item.widgettype === 'Title6'}}">
<text class="title-6">{{item.options.text}}</text> <text class="title-6" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">{{item.options.text}}</text>
</block> </block>
<!-- 布局组件 - HBox/VBox --> <!-- 布局组件 - HBox/VBox -->
<block wx:if="{{item.widgettype === 'HBox' || item.widgettype === 'FHBox'}}"> <block wx:if="{{item.widgettype === 'HBox' || item.widgettype === 'FHBox'}}">
<view class="flex-row {{item.widgettype === 'FHBox' ? 'flex-between' : ''}}"> <view class="flex-row {{item.widgettype === 'FHBox' ? 'flex-between' : ''}}" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">
<block wx:for="{{item.subwidgets}}" wx:key="widgettype" wx:for-item="child"> <block wx:for="{{item.subwidgets}}" wx:key="widgettype" wx:for-item="child">
<template is="brick" data="{{item: child}}" /> <template is="brick" data="{{item: child}}" />
</block> </block>
@ -37,7 +37,7 @@
</block> </block>
<block wx:if="{{item.widgettype === 'VBox' || item.widgettype === 'FVBox'}}"> <block wx:if="{{item.widgettype === 'VBox' || item.widgettype === 'FVBox'}}">
<view class="flex-col {{item.widgettype === 'FVBox' ? 'flex-between' : ''}}"> <view class="flex-col {{item.widgettype === 'FVBox' ? 'flex-between' : ''}}" bindtap="onBricksTap" data-bind="{{item._primaryBind}}">
<block wx:for="{{item.subwidgets}}" wx:key="widgettype" wx:for-item="child"> <block wx:for="{{item.subwidgets}}" wx:key="widgettype" wx:for-item="child">
<template is="brick" data="{{item: child}}" /> <template is="brick" data="{{item: child}}" />
</block> </block>
@ -46,20 +46,20 @@
<!-- Filler --> <!-- Filler -->
<block wx:if="{{item.widgettype === 'Filler' || item.widgettype === 'HFiller' || item.widgettype === 'VFiller'}}"> <block wx:if="{{item.widgettype === 'Filler' || item.widgettype === 'HFiller' || item.widgettype === 'VFiller'}}">
<view class="flex-fill"></view> <view class="flex-fill" bindtap="onBricksTap" data-bind="{{item._primaryBind}}"></view>
</block> </block>
<!-- 输入组件 --> <!-- 输入组件 -->
<block wx:if="{{item.widgettype === 'KeyinText'}}"> <block wx:if="{{item.widgettype === 'KeyinText'}}">
<input class="input-field" placeholder="{{item.options.placeholder}}" value="{{item.options.value || item.options.text}}" bindinput="onInput" data-widget="{{item}}" /> <input class="input-field" placeholder="{{item.options.placeholder}}" value="{{item.options.value || item.options.text}}" bindinput="onInput" data-bind="{{item._primaryBind}}" data-widget="{{item}}" />
</block> </block>
<block wx:if="{{item.widgettype === 'Input'}}"> <block wx:if="{{item.widgettype === 'Input'}}">
<block wx:if="{{item.options.type === 'password'}}"> <block wx:if="{{item.options.type === 'password'}}">
<input class="input-field" type="idcard" placeholder="{{item.options.placeholder}}" password="{{true}}" /> <input class="input-field" type="idcard" placeholder="{{item.options.placeholder}}" password="{{true}}" bindinput="onInput" data-bind="{{item._primaryBind}}" />
</block> </block>
<block wx:else> <block wx:else>
<input class="input-field" placeholder="{{item.options.placeholder}}" value="{{item.options.value}}" /> <input class="input-field" placeholder="{{item.options.placeholder}}" value="{{item.options.value}}" bindinput="onInput" data-bind="{{item._primaryBind}}" />
</block> </block>
</block> </block>

View File

@ -68,6 +68,15 @@ Page({
} }
}, },
onBricksTap(e) {
if (this.renderer) this.renderer.onEvent(e)
},
onInput(e) {
if (this.renderer) this.renderer.onInput(e)
this.onInputChange(e)
},
onInputChange(e) { onInputChange(e) {
console.log('[Bricks] Input:', e.detail.value) console.log('[Bricks] Input:', e.detail.value)
} }

View File

@ -9,7 +9,7 @@ class BricksHttp {
*/ */
get(url, params = {}) { get(url, params = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const fullUrl = app.entireUrl(url) const fullUrl = this._withBricksContext(app.entireUrl(url))
wx.request({ wx.request({
url: fullUrl, url: fullUrl,
data: params, data: params,
@ -32,7 +32,7 @@ class BricksHttp {
*/ */
post(url, data = {}) { post(url, data = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const fullUrl = app.entireUrl(url) const fullUrl = this._withBricksContext(app.entireUrl(url))
wx.request({ wx.request({
url: fullUrl, url: fullUrl,
data: JSON.stringify(data), data: JSON.stringify(data),
@ -49,6 +49,16 @@ class BricksHttp {
}) })
}) })
} }
_withBricksContext(url) {
if (!/\.(ui|dspy)(\?|$)/.test(url)) return url
const info = wx.getSystemInfoSync ? wx.getSystemInfoSync() : {}
const clean = url.replace(/([?&])(_webbricks_|_width|_height|_is_mobile|_lang)=[^&]*&?/g, '$1').replace(/[?&]$/, '')
const join = clean.indexOf('?') >= 0 ? '&' : '?'
return clean + join + '_webbricks_=1&_width=' + encodeURIComponent(info.windowWidth || 0) +
'&_height=' + encodeURIComponent(info.windowHeight || 0) +
'&_is_mobile=1&_lang=' + encodeURIComponent(info.language || 'zh-CN')
}
} }
module.exports = { BricksHttp } module.exports = { BricksHttp }

View File

@ -42,7 +42,16 @@ class BricksParser {
params: b.params, params: b.params,
url: b.url || (b.options && b.options.url), url: b.url || (b.options && b.options.url),
script: b.script script: b.script
})) : [] })) : [],
_primaryBind: obj.binds && obj.binds.length > 0 ? {
event: obj.binds[0].event || 'tap',
actiontype: obj.binds[0].actiontype,
target: obj.binds[0].target,
methodname: obj.binds[0].methodname || obj.binds[0].method,
params: obj.binds[0].params,
url: obj.binds[0].url || (obj.binds[0].options && obj.binds[0].options.url),
script: obj.binds[0].script
} : null
} }
// 递归处理子组件 // 递归处理子组件

View File

@ -24,7 +24,8 @@ class BricksRenderer {
* 处理事件绑定 * 处理事件绑定
*/ */
onEvent(e) { onEvent(e) {
const { actiontype, target, methodname, url, script } = e.currentTarget.dataset const bind = e.currentTarget.dataset.bind || e.detail || {}
const { actiontype, target, methodname, url, script } = bind.actiontype ? bind : e.currentTarget.dataset
console.log('[Bricks] Event:', actiontype, target) console.log('[Bricks] Event:', actiontype, target)
switch (actiontype) { switch (actiontype) {
@ -63,6 +64,13 @@ class BricksRenderer {
_handleEvent(e) { _handleEvent(e) {
console.log('[Bricks] Event data:', e.detail) console.log('[Bricks] Event data:', e.detail)
} }
onInput(e) {
const bind = e.currentTarget.dataset.bind || {}
if (bind.actiontype) {
this.onEvent({ currentTarget: { dataset: { bind } }, detail: e.detail })
}
}
} }
module.exports = { BricksRenderer } module.exports = { BricksRenderer }