微信小程序button按钮指定open-type事件点击提交之前做数据检查

    今天这个需求,需要一键登录,但是点击按钮调起一键登录之前,我们需要检查用户是否勾选注意事项。

    一键登录选择手机号这个功能,微信小程序帮我们做好了,我们只需要在button元素设置open-type=getPhoneNumber,然后绑定获取手机号响应事件即可。也就是bindgetphonenumber=onGetPhoneNumber。

    问题就是,这个getPhoneNumber事件是微信小程序里面内置的,我们无法修改这个getPhoneNumber函数,在调用这个函数之前做个数据检查。

    我想了一个办法,就是在button按钮里面包一个text,组成这样的结构<button><text></text></button>,然后让text充满button,在text元素上绑定tap事件,设置检查功能,如果检查失败,阻止冒泡,点击事件就不会传递到button,这样getPhoneNumber事件就不会被调起,可是自己做了测试,我们通过bindtap传入的函数,虽然参数有event,但是它没有stopPropagation()方法,也就是它和我们web浏览器的html元素事件不同。我还想了里面的text通过catchtap捕获不冒泡来绑定事件,检查通过,继续触发tap事件-this.triggerEvent("tap",{},{bubbles:true}),可是这个方式似乎也不行,可能一旦捕获了,就捕获了,后续再手动触发也不会把事件冒泡到父级button上。

    我还想了一个办法,就是这里设置两个button(button1显示button2隐藏),一个按钮button1绑定(bindtap)数据检查事件,一个按钮button2做(open-type)一键登录选择手机号功能,button1检查通过,通过查找元素的方式找到button2,然后调起它的点击事件。可是,查找元素这里就遇到了麻烦,根本找不到,通过wx.createSelectorQuery("")查找不到,不知道什么原因,网上好多资料给的都是官方api示例,没有实际例子,另外通过this.selectComponent()的方式在组件范围内查找也找不到,这条路很艰难。还有一个即使找到了,触发点击事件感觉也不靠谱,微信小程序里面似乎没有提到通过查找元素然后触发事件。

   就在快要放弃的时候,我根据第二个办法的思路,马上调整了策略,同样是两个button,他们做个互斥显示,而这个互斥的条件就是检查是否通过。

  于是,就有了今天的一个故事。

wxml

<scroll-view class="scrollarea">
  <view class="container">
    <view class="login-item logo">
      <image src="../../../icons/icon_logo.png"></image>
      <text>飞手壹号</text>
    </view>
    <view class="login-item login-btn-box">
      <block wx:if="{{userSelected}}">
        <button id="login-btn" open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber" >用户一键登录</button>
      </block>
      <block wx:else>
        <button bindtap="checkSelect" >用户一键登录</button>
      </block>
    </view>
    <view class="login-item agreement">
      <radio checked="{{userSelected}}" bind:tap="onRadioChange"></radio>
      <text>已阅读并同意《服务协议》和《隐私协议》</text>
    </view>
  </view>
</scroll-view>

js

const app = getApp()
Page({
  data: {
    userSelected: false
  },
  onLoad() {

  },
  onRadioChange() {
    var userSelected = this.data.userSelected;
    this.setData({
      userSelected: !userSelected
    })
  },
  checkSelect() {
    if(!this.data.userSelected) {
      wx.showModal({
        title: '温馨提示',
        content: '请勾选已阅读并同意《服务协议》和《隐私协议》',
        complete: (res) => {
          if (res.cancel) {}
          if (res.confirm) {}
        }
      })
    }
  },
  onGetPhoneNumber(e) {
    if(e.detail.code!='') {
      wx.request({
        url: 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' + app.globalData.access_token,
        method: 'POST',
        data : {code: e.detail.code},
        success(res) {
          if(res.data.errcode==0) {
            let phoneNumber = res.data.phone_info.phoneNumber
            // 登录准备
              
          }
        }
      })
    }
  },
  quickLogin() {
    wx.navigateTo({
      url: '../role/index',
    })
  }
})

代码其实很简单,没什么技巧,就是使用了wx:if  wx:else做了一个条件判断。

实际效果演示:

    初学微信小程序,遇到了太多的问题,这个小问题可以卡半天,太麻烦了。

<think>好的,我现在需要解决用户的问题:在uniapp开发中,当使用微信小程序button按钮并设置open-type='share'时,如何添加前置判断条件。用户希望在某些条件下才允许触发分享功能。 首先,我要回忆一下微信小程序的分享机制。通常,使用open-type='share'的按钮会触发页面的onShareAppMessage生命周期函数,用户点击按钮后会自动调用这个函数。但是,用户现在想要在点击按钮时先执行一些判断,再决定是否继续分享。 根据微信小程序的文档,直接使用open-type='share'的按钮点击后会直接触发分享,无法通过阻止事件冒泡或返回false来取消。因此,常规的事件处理函数可能无法满足前置判断的需求。这时候可能需要替代方案。 接下来,我需要考虑如何在不使用open-type='share'的情况下实现分享功能。用户提到uniapp,所以可能需要使用uni-app的事件处理机制。可能的思路是:不使用open-type,而是通过自定义点击事件,在事件处理函数中执行判断,如果条件满足,再手动触发分享。 在微信小程序中,手动触发分享可以通过调用Page.onShareAppMessage方法,或者使用wx.showShareMenu和wx.hideShareMenu来控制分享按钮的显示,但用户希望的是在点击时判断,而不是一直显示或隐藏。因此,可能需要结合自定义按钮和uni-app的API。 另外,uni-app的条件编译可能也需要考虑,因为用户的需求是针对微信小程序的,可能需要使用#ifdef MP-WEIXIN来包裹相关代码,确保其他平台不受影响。 可能的步骤是: 1. 将按钮open-type='share'改为普通的@click事件(在uni-app中是@tap)。 2. 在@tap的事件处理函数中执行前置判断。 3. 如果判断通过,手动调用分享的方法。这里可能需要调用uni.showShareMenu或者直接触发分享界面。但需要确认在微信小程序中如何手动触发分享,因为通常分享需要用户主动点击按钮才能调起面板。 这里可能需要进一步查阅微信小程序的文档,发现如果用户没有使用open-type='share'的按钮,而是通过其他方式触发分享,可能需要先调用wx.updateShareMenu,或者设置shareTicket等。但可能无法直接调起分享面板,因为微信的安全策略要求分享必须由用户点击触发。 因此,可能需要另一种方法:动态设置按钮open-type属性。例如,在满足条件时,设置open-type为'share',否则移除该属性。这样,当用户点击按钮时,只有在条件满足时才会触发分享功能。 在uni-app中,可以通过数据绑定动态设置属性。例如,在button组件上使用:open-type="shareCondition ? 'share' : ''",然后根据shareCondition的值来决定是否启用分享功能。同时,可以绑定@click事件,在点击时先执行判断,如果条件不满足,则不进行任何操作,或者给出提示;如果条件满足,可能需要在数据中设置shareCondition为true,并触发按钮的分享功能。 不过,微信小程序button组件可能需要在点击open-type已经正确设置,因此可能需要先设置open-type为'share',然后在@click事件中判断,如果条件不满足,则阻止分享。但根据之前的了解,无法直接阻止open-type='share'的默认行为,因此这种方法可能不可行。 另一种思路是,在onShareAppMessage函数内部进行判断。例如,当用户点击分享按钮后,会触发该函数,此时在函数内部检查条件,如果条件不满足,返回一个空的title和path,或者显示提示信息。但微信可能要求必须设置有效的title,否则分享失败,所以可能需要结合其他方法,比如在onShareAppMessage中判断条件,如果不符合,则显示提示,并返回无效的分享配置,或者调用wx.showToast提示用户无法分享。 不过,用户的需求是在点击按钮时就进行判断,而不是在触发分享之后。因此,可能需要结合自定义按钮和动态设置open-type属性。例如,当用户满足条件时,按钮open-type='share',否则不使用该属性,这样点击按钮时不会触发分享,而是执行其他事件。 具体实现步骤可能如下: 1. 在data中定义一个变量,如canShare,初始化为false。 2. 在需要判断的时候(比如页面加载时,或某些操作后),更新canShare的值。 3. 在按钮上动态绑定open-type属性::open-type="canShare ? 'share' : ''" 4. 同时,绑定一个@click事件,当canShare为false时,执行提示或其他操作。 5. 当canShare为true时,点击按钮会触发分享,执行onShareAppMessage中的逻辑。 但这样可能存在一个问题:当canShare为false时,按钮open-type被移除,点击按钮会触发@click事件,而如果canShare为true,按钮open-type存在,点击会触发分享,但此时@click事件可能不会执行,因为微信小程序open-type='share'的按钮点击会直接触发分享,而不会执行绑定的事件处理函数。因此,可能需要测试在uniapp中,当button同时有open-type和@click时,事件的处理顺序。 如果微信小程序中,open-type='share'的按钮点击会优先触发分享,而不会执行@click事件,那么这种方法可能无法在条件满足时执行前置判断。因此,需要另一种方法。 可能的解决方案是:不使用open-type='share',而是用普通按钮,然后在@click事件中执行判断,如果条件满足,则通过API调起分享。但微信小程序的安全策略可能不允许通过API直接调起分享面板,必须由用户点击带有open-type='share'的按钮才能触发。因此,这种方法可能不可行。 这时可能需要折中的办法:在用户点击自定义按钮后,如果条件满足,动态将按钮open-type设置为'share',并模拟一次点击。但这种方式可能涉及DOM操作,且在微信小程序中可能不被允许,或者无法立即生效。 另一个思路是,使用hidden属性或条件渲染,根据条件显示不同的按钮。例如,当满足条件时,显示一个带有open-type='share'的按钮;否则,显示一个普通按钮点击时提示用户不满足条件。 这种方法可能更可行。在uniapp中,可以使用v-if或条件编译来实现。例如: <button v-if="canShare" open-type="share" @click="handleShare">分享</button> <button v-else @click="showAlert">分享</button> 然后在handleShare函数中,可能不需要任何事情,因为分享会自动触发onShareAppMessage。但是,如果需要在分享前执行某些操作,比如记录日志,可以在onShareAppMessage中处理。 不过,用户可能需要在前置判断中一些异步操作,比如检查用户权限或状态,然后再决定是否允许分享。这时候,可能需要结合自定义的点击事件和动态设置按钮open-type属性。 例如,当用户点击按钮时,先执行判断,如果是异步的,可能需要先显示加载中,等判断结果返回后,再动态设置canShare为true,并触发按钮点击。但这种方法可能复杂且不可靠。 综上所述,比较可行的方案是使用条件渲染两个不同的按钮:一个带有open-type='share',另一个不带。根据条件显示不同的按钮。这样,当用户满足条件时,点击带有open-type按钮会触发分享;否则,点击另一个按钮会执行提示操作。 在uniapp中,具体代码可能如下: <template> <view> <!-- 微信小程序条件编译 --> <!--#ifdef MP-WEIXIN--> <button v-if="canShare" open-type="share" @click="handleShareClick">分享</button> <button v-else @click="handleNoShare">分享</button> <!--#endif--> </view> </template> <script> export default { data() { return { canShare: false }; }, onLoad() { // 执行前置条件判断,例如检查用户登录状态等 this.checkShareCondition(); }, methods: { checkShareCondition() { // 假设异步检查条件 setTimeout(() => { this.canShare = true; // 或 false }, 1000); }, handleShareClick() { // 这里可以执行一些前置操作,但分享逻辑由onShareAppMessage处理 console.log('分享按钮点击,条件满足'); }, handleNoShare() { uni.showToast({ title: '当前无法分享', icon: 'none' }); } }, onShareAppMessage() { return { title: '分享标题', path: '/pages/index/index' }; } }; </script> 这样,当canShare为true时,显示带有open-type='share'的按钮点击后触发分享;否则显示普通按钮点击提示无法分享。同时,在onShareAppMessage中可以进一步处理分享内容。 但需要注意,在微信小程序中,点击open-type='share'的按钮会直接触发分享,而不会执行@click绑定的事件处理函数。因此,handleShareClick可能不会被调用。这时,如果需要在分享前执行某些同步操作,可能需要将这些操作放在onShareAppMessage中,或者在按钮显示之前就已经完成条件判断。 因此,更准确的法是,前置判断在点击按钮之前就已经完成,通过条件渲染不同的按钮。而onShareAppMessage中可能不需要额外判断,因为只有在canShare为true时才会显示该按钮。 如果需要在用户点击分享按钮时再次验证条件(比如防止条件在渲染后发生变化),可以在onShareAppMessage中进行判断: onShareAppMessage() { if (!this.canShare) { // 返回空或不合法配置,但微信可能不允许 return {}; } return { title: '分享标题', path: '/pages/index/index' }; } 但微信可能要求必须返回有效的title和path,否则分享失败。因此,更好的法是在onShareAppMessage中也进行条件判断,如果条件不满足,可以提示用户,但可能无法阻止分享面板的弹出,因为此时已经触发了分享流程。 因此,最可靠的方法还是通过条件渲染按钮,确保只有在条件满足时才显示带有open-type='share'的按钮,从而避免用户在不满足条件时触发分享。 总结实现步骤: 1. 在data中定义canShare变量,控制是否允许分享。 2. 在页面加载或适当时机执行前置条件判断,更新canShare。 3. 使用条件渲染,根据canShare显示不同的按钮。 4. 对于不满足条件的情况,按钮点击时给出提示。 5. 在onShareAppMessage中设置分享内容。 这样就能实现前置判断,并根据条件允许或禁止分享功能的触发。</think>在UniApp中实现微信小程序`button`组件的`open-type='share'`功能前置判断,可通过以下步骤实现: ### 实现步骤 1. **使用条件渲染控制按钮显示** 通过`v-if`指令动态切换分享按钮的显示状态,结合前置判断逻辑决定是否展示具备分享功能的按钮 ```html <!-- 微信小程序条件编译 --> <!--#ifdef MP-WEIXIN--> <button v-if="canShare" open-type="share" @click="handleShareButton"> 分享 </button> <button v-else @click="showShareDenied"> 分享 </button> <!--#endif--> ``` 2. **数据驱动状态管理** 在`data`中设置`canShare`状态标识,通过业务逻辑动态更新该值 ```javascript data() { return { canShare: false // 初始状态禁止分享 } } ``` 3. **前置条件验证方法** 在页面生命周期或用户操作时执行验证逻辑 ```javascript methods: { // 验证分享条件(示例:用户登录状态检查) checkShareCondition() { this.canShare = uni.getStorageSync('userToken') ? true : false } } ``` 4. **分享事件处理** 通过`onShareAppMessage`生命周期函数处理分享内容 ```javascript onShareAppMessage() { return { title: '自定义分享标题', path: '/pages/index/index?id=123' } } ``` 5. **禁止分享时的交互处理** 添加用户提示增强体验 ```javascript methods: { showShareDenied() { uni.showToast({ title: '请登录后分享', icon: 'none' }) } } ``` ### 实现原理 1. **条件渲染机制**:通过`v-if`指令实现DOM节点的动态创建/销毁,符合微信小程序按钮点击触发分享必须保持`open-type`属性」的规范要求[^1] 2. **状态同步控制**:`canShare`状态变更会触发视图层重新渲染,确保按钮功能与业务逻辑实时同步 3. **安全校验策略**:在`onShareAppMessage`生命周期中可进行二次验证,防止状态篡改 ```javascript onShareAppMessage() { if (!this.canShare) { return { title: '', path: '' } // 无效分享配置 } // 正常分享配置 } ``` ### 注意事项 1. **事件冒泡限制**:微信小程序原生`share`按钮不会触发`@click`事件,因此前置验证必须通过条件渲染实现[^2] 2. **异步验证处理**:若需网络请求验证,建议使用加载状态提示 ```javascript async checkAsyncCondition() { uni.showLoading({ title: '验证中' }) const res = await api.checkSharePermission() this.canShare = res.valid uni.hideLoading() } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffy5459

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值