原文链接

前言

还是微信小程序项目,虽然有一些优秀的第三方组件,但是秉持高度还原UI设计稿的原则,没有直接在项目中使用。遇到一些类似的逻辑时,可以参考一下这些开源项目的实现方式。难的往往只是某一个点,有时候我们需要的只是一张地图(PS:来自硬派脱口秀节目《知识就是力量》)。

开始

为什么研究actionsheet组件?

因为项目中设计较多的交互动画,想要自己同一封装,可多处使用。一方面可以减少代码量,另一方面可以将动画与逻辑分离,更易于管理。

正文

  1. 首先,需要在github上下载vant-weapp的源码;
  2. 把项目clone或下载到本地,参照官方说明,编译出可运行的小程序代码;
  3. 使用微信编辑器打开项目,并把编译出的小程序源码拖进你喜欢的编辑器。

actionsheet示例页面:

actionsheet页面代码:

wxml:

<demo-block title="基础用法" padding><van-button bind:click="toggleActionsheet1">弹出 Actionsheet</van-button><!-- 监听了close事件 show控制显示和隐藏 --><van-actionsheetshow="{{ show1 }}"actions="{{ actions }}"bind:close="toggleActionsheet1"bind:select="toggleActionsheet1"/>
</demo-block><demo-block title="带取消按钮的 Actionsheet" padding><van-button bind:click="toggleActionsheet2">弹出带取消按钮的 Actionsheet</van-button><van-actionsheetshow="{{ show2 }}"actions="{{ actions }}"cancel-text="取消"bind:close="toggleActionsheet2"bind:cancel="toggleActionsheet2"bind:select="toggleActionsheet2"/>
</demo-block><demo-block title="带标题的 Actionsheet" padding><van-button bind:click="toggleActionsheet3">弹出带标题的 Actionsheet</van-button><van-actionsheetshow="{{ show3 }}"title="标题"bind:close="toggleActionsheet3"><view class="content">内容</view></van-actionsheet>
</demo-block>

js:

import Page from '../../common/page';Page({data: {show1: false,show2: false,show3: false},onLoad() {this.setData({actions: [{ name: '选项' },{ name: '选项', subname: '禁用' },{ name: '选项', loading: true },{ name: '禁用选项', disabled: true }]});},// 设置隐藏  在最外层page里改变了show的值,触发transition.js中show的observer函数,导致所有的动画执行toggle(type) {this.setData({[type]: !this.data[type]});},// 调用方法toggleActionsheet1() {this.toggle('show1');},toggleActionsheet2() {this.toggle('show2');},toggleActionsheet3() {this.toggle('show3');}
});

在示例页面可以看出,是使用了van-actionsheet组件,那我们再去看看van-actionsheet组件的实现。

van-actionsheet组件代码:

<!-- 引入了van-popup组件 -->
<van-popupshow="{{ show }}"overlay="{{ overlay }}"close-on-click-overlay="{{ closeOnClickOverlay }}"custom-class="van-actionsheet {{ title ? 'van-actionsheet--withtitle' : '' }}"position="bottom"bind:close="onClose"
><!-- 这部分是作为van-popup组件的slot内容插入的 --><view wx:if="{{ title }}" class="van-hairline--top-bottom van-actionsheet__header"><view>{{ title }}</view><van-icon custom-class="van-actionsheet__close" name="close" bind:click="onClose" /></view><view wx:else class="van-hairline--bottom"><viewwx:for="{{ actions }}"wx:key="index"class="van-actionsheet__item van-hairline--top {{ item.disabled || item.loading ? 'van-actionsheet__item--disabled' : '' }} {{ item.className || '' }}"data-index="{{ index }}"bind:tap="onSelect"><block wx:if="{{ !item.loading }}"><view class="van-actionsheet__name">{{ item.name }}</view><view class="van-actionsheet__subname" wx:if="{{ item.subname }}">{{ item.subname }}</view></block><van-loading wx:else custom-class="van-actionsheet__loading" size="20px" /></view></view><viewwx:if="{{ cancelText }}"class="van-actionsheet__cancel van-hairline--top"bind:tap="onCancel">{{ cancelText }}</view><view wx:else class="van-actionsheet__content"><!-- slot:可以自定义actionsheet内容 --><slot /></view>
</van-popup>

在van-actionsheet组件源码中可以看出,组件内引入了van-popup组件,那我们再去看看van-popup组件的实现。

van-popup组件源码:

<!-- 引入了van-overlay组件 -->
<van-overlaymaskshow="{{ overlay && show }}"custom-style="{{ overlayStyle }}"bind:click="onClickOverlay"
/><!-- 真正的弹窗内容 -->
<viewwx:if="{{ inited }}"class="custom-class van-popup {{ position ? 'van-popup--' + position : '' }}"style="animation-name: van-{{ position }}-{{ type }}; animation-duration: {{ duration }}ms; {{ display ? '' : 'display: none;' }}"bind:animationend="onAnimationEnd"
><!-- slot: 可以自定义弹窗的内容 --><slot />
</view>

组件van-popup内又引入了van-overlay组件,那再去看看van-overlay组件的实现。

van-overlay组件源码:

<!-- 好家伙,又是一个组件 -->
<van-transitionshow="{{ show }}"custom-class="van-overlay"custom-style="z-index: {{ zIndex }}; {{ mask ? 'background-color: rgba(0, 0, 0, .7);' : '' }}; {{ customStyle }}"bind:tap="onClick"
/>

组件中还是组件。。。再去看看van-transition组件的实现吧。

van-transition组件源码:

wxml:

<!-- name值默认为fade, type值是取transition中的type值(enter/leave) --><!-- 终于到头了~ -->
<viewwx:if="{{ inited }}"class="van-transition custom-class"style="animation-name: van-{{ name }}-{{ type }}; animation-duration: {{ duration }}ms; {{ display ? '' : 'display: none;' }} {{ customStyle }}"bind:animationend="onAnimationEnd"
>
<!-- 显示和隐藏通过控制display属性实现,绑定了动画结束的处理函数 --><slot />
</view>

wxss: 该部分代码定义的是动画,代码过长,此处就不深入探究CSS动画的实现啦。

js:

// 引入behaviors
import transitionBehaviors from '../behaviors/transition';Component({options: {addGlobalClass: true},externalClasses: ['custom-class'],// 类似于mixins和traits的组件间代码复用机制// 每个behavior一组属性、数据、生命周期函数和方法,组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。每个组件可以引用多个 behavior。behavior也可以引用其他behavior 。behaviors: [transitionBehaviors(true)],properties: {name: {type: String,value: 'fade'}}
});

transition.js:

export default function(showDefaultValue) {return Behavior({properties: {customStyle: String,// 根据show的值判断是动画type是enter还是leaveshow: {value: showDefaultValue,type: Boolean,// 属性值被更改时的响应函数observer(value) {if (value) {this.show();} else {this.setData({type: 'leave'});}}},duration: {type: Number,value: 300}},data: {type: '',inited: false,display: false},attached() {if (this.data.show) {this.show();}},methods: {show() {this.setData({inited: true,display: true,type: 'enter'});},// 动画结束,只修改了displayonAnimationEnd() {// 如果false, 就隐藏if (!this.data.show) {this.setData({display: false});}}}});
}

总结

很细的组件化开发,分工明确,耦合度低。对behavior进行了同一的管理,组件behaviors+observer的结合使用,完美~

之前参考vant-weapp slider组件的实现,自己做了一个双向滑动的slider,收获颇多。致敬这些优秀的开源项目,致敬那些优秀的程序员~路还长

嘘寒问暖 不如打笔巨款~

微信小程序:有赞小程序UI( vant-weapp ) actionsheet组件源码窥探相关推荐

  1. uni-app - 文本展开 / 收起折叠功能,支持自定义样式(当文本内容超出规定行数后,展开收起折叠的功能)兼容 H5 / App / 小程序且易用更容易修改的插件组件源码,超详细的示例代码及注释

    前言 网上的组件和教程代码都太乱了,根本无法按照自己的需求修改,而且基本上都有兼容性和功能性 BUG. 本文实现了 多行文本展开与折叠组件,灵活性非常高,只完成了核心功能,可随意自定义样式满足您的需求 ...

  2. 基于微信小程序共享停车位设计与实现SSM_car.rar(项目源码+数据库文件+微信小程序开发+后端java语言)

    主要功能实现了共享车位的创建,车位的管管理,创建车辆.车辆的管理.附近车位.显示车位的编号,车位的位置,车位的状态,车位.可以查看订单记录车位.停费时间,确认时间计费的时间.可以删除,订单也可以确认是 ...

  3. 美团饿了么外卖返利小程序公众号搭建外卖返利分销系统代cps源码

    美团饿了么外卖返利小程序公众号搭建外卖返利分销系统代cps源码 外卖CPS小程序源码分享 饿了么.美团优惠开发(外卖cps,三级裂变源码) 源码或搭建 http://y.mybei.cn/ 截图 功能 ...

  4. 抖音小程序基础之 目前提供哪些API(教程含源码)

    抖音小程序基础之 目前提供哪些API(教程含源码) 小程序开发框架提供丰富的 字节跳动宿主 原生 API,可以方便的调起 字节跳动宿主 提供的能力,如获取系统信息等.详细介绍请参考 API 文档. 通 ...

  5. 【整站程序】wordpress-RiPro-V2去授权WordPress主题虚拟收费主题源码下载

    [整站程序]RiPro-V2去授权WordPress主题RiPlus虚拟收费主题源码下载RiPro-V2是一个优秀的主题,首页拖拽布局,高级筛选,自带会员生态系统,超全支付接口,你喜欢的样子我都有!R ...

  6. 前端小游戏2048(一步步详解附带源代码,源码上传到csdn,可以免费下载)

    2048小游戏 2048是前端开发必经的一个小游戏,2048小游戏包含了HTML,CSS和JavaScript. 简介 <2048>,是一款益智小游戏,这款游戏是由年仅19岁的意大利程序员 ...

  7. java串口发送十六进制数,本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下1.介绍使用Java实现的串口通信程序,支持十六进制数据的发送与接收。 源码:...

    本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下 1.介绍 使用Java实现的串口通信程序,支持十六进制数据的发送与接收. 源码:SerialPortDemo 效果图如下: ...

  8. Delphi:程序自己删除自己,适用于任何windows版本(含源码)

    Delphi:程序自己删除自己,适用于任何windows版本(含源码) function Suicide: Boolean; var   sei: TSHELLEXECUTEINFO;   szMod ...

  9. 经典怀旧FCgame红白机小游戏在线网页合集版畅玩HTML网站源码

    经典怀旧FCgame红白机小游戏在线网页合集版畅玩HTML网站源码 ☑️ 编号:ym468 ☑️ 品牌:无 ☑️ 语言:ThinkPHP ☑️ 大小:4.7MB ☑️ 类型:经典怀旧FCgame ☑️ ...

  10. Html5在线小游戏 在线玩压扁小鸟(flyBird)游戏源码

    这个源码无需后台上传服务器,直接在线即可使用. 该游戏源码是基于HTML5和JavaScript开发的,运行在浏览器中,使得用户能够方便地进行游戏,而且不需要进行任何安装和下载操作.想要玩游戏的用户只 ...

最新文章

  1. firefox html5 canvas,html5 Canvas
  2. linux下查看监听端口对应的进程
  3. 完全分布式部署Hadoop
  4. 关于Integer类中parseInt()和valueOf()方法的区别以及int和String类性的转换.以及String类valueOf()方法...
  5. cmd命令快速启动、暂停和关闭sql server服务
  6. 千灯腾碧人潮涌,蓬勃“雨花”气如虹
  7. 【深度学习】PyTorch 数据集随机值的完美实践
  8. 【SpringBoot 2】(四)详析SpringBoot的常用注解
  9. 使用SQL Server数据库指标预测应用程序问题
  10. 微信小程序接入海康威视萤石云直播
  11. Python实时爬取斗鱼弹幕
  12. matlab求一元函数极值点和拐点,matlab求函数的极值点和拐点函数y=x^2*sin(x^2-爱问知识人...
  13. 5w1H数据分析简单例子
  14. DRM in Android详解
  15. 关于导入百度导航SDK报错以及解决方案
  16. 企业WiFi认证 保护企业的信息
  17. 参考C++高级进阶教程
  18. 为什么中国码农不断涌向杭州?
  19. sqlserver 数据库优化工具,安全性设置,并发设置,SQL耗时优化
  20. 结合Bootstrap实现头像上传前预览

热门文章

  1. 2021-11-13偏最小二乘法应用实例python程序代码
  2. TMK2SLNO TMK1SLNO 华为OSN1800 2路STM-16,8路STM-4或8路STM-1光接口板
  3. [AngularJS面面观] 20. 依赖注入 --- instance注入器以及provider注入器
  4. 容联七陌×惠州燃气丨用服务之光,点燃美好生活
  5. 库存进销存出入库销售mysql表结构_进销存数据库表结构设计.doc
  6. hspice 2019 安装流程
  7. ydui的datetime日期选择组件
  8. ReactNative之 Activity class {xxx/xxx.MainActivity} does not exist
  9. 把项目部署在腾讯云服务器上详细内容教程
  10. 火山视频解析,火山视频去水印