- 微信小程序UI组件库合集
UI组件库合集,大家有遇到好的组件库,欢迎留言评论然后加入到文档里。 第一款: 官方WeUI组件库,地址 https://developers.weixin.qq.com/miniprogram/dev/extended/weui/ 预览码: [图片] 第二款: ColorUI:地址 https://github.com/weilanwl/ColorUI 预览码: [图片] 第三款: vantUI(又名:ZanUI):地址 https://youzan.github.io/vant-weapp/#/intro 预览码: [图片] 第四款: MinUI: 地址 https://meili.github.io/min/docs/minui/index.html 预览码: [图片] 第五款: iview-weapp:地址 https://weapp.iviewui.com/docs/guide/start 预览码: [图片] 第六款: WXRUI:暂无地址 预览码: [图片] 第七款: WuxUI:地址https://www.wuxui.com/#/introduce 预览码: [图片] 第八款: WussUI:地址 https://phonycode.github.io/wuss-weapp/quickstart.html 预览码: [图片] 第九款: TouchUI:地址 https://github.com/uileader/touchwx 预览码: [图片] 第十款: Hello UniApp: 地址 https://m3w.cn/uniapp 预览码: [图片] 第十一款: TaroUI:地址 https://taro-ui.jd.com/#/docs/introduction 预览码: [图片] 第十二款: Thor UI: 地址 https://thorui.cn/doc/ 预览码: [图片] 第十三款: GUI:https://github.com/Gensp/GUI 预览码: [图片] 第十四款: QyUI:暂无地址 预览码: [图片] 第十五款: WxaUI:暂无地址 预览码: [图片] 第十六款: kaiUI: github地址 https://github.com/Chaunjie/kai-ui 组件库文档:https://chaunjie.github.io/kui/dist/#/start 预览码: [图片] 第十七款: YsUI:暂无地址 预览码: [图片] 第十八款: BeeUI:git地址 http://ued.local.17173.com/gitlab/wxc/beeui.git 预览码: [图片] 第十九款: AntUI: 暂无地址 预览码: [图片] 第二十款: BleuUI:暂无地址 预览码: [图片] 第二十一款: uniydUI:暂无地址 预览码: [图片] 第二十二款: RovingUI:暂无地址 预览码: [图片] 第二十三款: DojayUI:暂无地址 预览码: [图片] 第二十四款: SkyUI:暂无地址 预览码: [图片] 第二十五款: YuUI:暂无地址 预览码: [图片] 第二十六款: wePyUI:暂无地址 预览码: [图片] 第二十七款: WXDUI:暂无地址 预览码: [图片] 第二十八款: XviewUI:暂无地址 预览码: [图片] 第二十九款: MinaUI:暂无地址 预览码: [图片] 第三十款: InyUI:暂无地址 预览码: [图片] 第三十一款: easyUI:地址 https://github.com/qq865738120/easyUI 预览码: [图片] 第三十二款 Kbone-UI: 地址 https://wechat-miniprogram.github.io/kboneui/ui/#/ 暂无预览码 第三十三款 VtuUi: 地址 https://github.com/jisida/VtuWeapp 预览码: [图片] 第三十四款 Lin-UI 地址:http://doc.mini.talelin.com/ 预览码: [图片] 第三十五款 GraceUI 地址: http://grace.hcoder.net/ 这个是收费的哦~ 预览码: [图片] 第三十六款 anna-remax-ui npm:https://www.npmjs.com/package/anna-remax-ui/v/1.0.12 anna-remax-ui 地址: https://annasearl.github.io/anna-remax-ui/components/general/button 预览码 [图片] 第三十七款 Olympus UI 地址:暂无 网易严选出品。 预览码 [图片] 第三十八款 AiYunXiaoUI 地址暂无 预览码 [图片] 第三十九款 visionUI npm:https://www.npmjs.com/package/vision-ui 预览码: [图片] 第四十款 AnimaUI(灵动UI) 地址:https://github.com/AnimaUI/wechat-miniprogram 预览码: [图片] 第四十一款 uView 地址:http://uviewui.com/components/quickstart.html 预览码: [图片] 第四十二款 firstUI 地址:https://www.firstui.cn/ 预览码: [图片]
2023-01-10 - 关于 openID存储方案和unionid存储方案 ?
现在开放平台下有多个应用,小程序,APP,公众号,目前只存储了 unionid(在user表中) ,对应 openID 和 access_token并未存储, 现在需要用到公众号下的openID(做模板信息推送),现在该如何存这个 openID ? 想法:新建 wx_user表 ,对应 user_id ,xiao_openid,gong_openid,app_openid,access_token,access_token_time ,把对应的openid全部存到用户的关了信息表中 ,access_token 计划任务刷新 这样的话,如果新加个公众号2,又需要改数据库了,各位大佬给指点下该如何操作?谢谢了
2019-08-28 - API Promise化
本文是我的小程序开发日记的其中一篇,刚兴趣的读者可以前往 GitHub 收看更多,欢迎star,感谢万分! 前言 众所周知,前端一大坑就是回调函数。 相信很多人是从[代码]async/await[代码]的温柔乡,掉到小程序重新写回调的大坑里的。 由于开发者工具新增了 增强编译 从而原生支持了[代码]async\await[代码],避免了我们仍需通过webpack等第三方打包工具实现。因此我们需要做的就是将官方API的 异步调用 方式改成 Promise的方式 即可。 分析与实践 大致上可以有两种思路,第一种就是,逐个函数封装: [代码]let promisify = func => args => new Promise((resolve, reject) => { func(Object.assign(args, { success: resolve, fail: reject, })) }) let _login = promisify(wx.login) // 将wx.login转成Promise形式的方法 _login().then(res => console.log) [代码] 这种方式比较麻烦,每次调用都需要手动转换。 劫持WX 第二种就类似[代码]Page[代码]封装那样,劫持[代码]wx[代码]对象,进行全局统一封装。但有一点比较棘手的是,需要分析清楚哪些是函数,哪些函数是异步而不是同步的,一开始我的思路是这样的: 同步方法是以[代码]Sync[代码]结尾的 通过[代码]typeof[代码]判断是否为函数 [代码]// promisify.js let originalWX = wx let props = Object.keys(wx) for (let name of props) { let fn = wx[name] if (typeof fn === 'function' && !name.endsWith('Sync')) { wx[name] = promisify(fn) } } [代码] 尝试封装之后,发现报错了。因为[代码]wx.drawCanvas[代码]只有[代码]getter[代码]没有[代码]setter[代码],无法给它赋值。相当于这个方法是[代码]readonly[代码]。 [图片] 既然存在没有[代码]setter[代码]的方法,那么我看有多少方法是有[代码]setter[代码]的: [代码]Object.keys(wx).filter(name => { let descriptor = Object.getOwnPropertyDescriptor(wx, name) return typeof descriptor.set === 'function' }) [代码] 结果是[代码][][代码],相当于无法改变[代码]wx[代码]对象的每个属性值。 [图片] 复制模式 虽然[代码]wx[代码]的属性都是[代码]readonly[代码],不能劫持[代码]wx[代码],但我发现[代码]wx[代码]是[代码]writable[代码]的。 那么可以采用复制模式,将它的所有异步方法拷贝一份并[代码]promisify[代码]之后赋值到新对象,最后再将整个对象赋值给[代码]wx[代码]即可: [代码]let props = Object.keys(wx) let jwx = {} for (let name of props) { let fn = wx[name] if (typeof fn === 'function' && !name.endsWith('Sync')) { jwx[name] = promisify(fn) } else { jwx[name] = fn } } wx = jwx [代码] 这种方式虽可行,但是挺冗余的,因为将很多可能没用上的方法也进行了[代码]promisify[代码]。 代理模式 熟悉ES新特性的读者应该知道[代码]Proxy[代码]。 它可以用来定义对象的自定义行为,顾名思义,就是给对象挂上[代码]Proxy[代码]之后,对这个属性的任何行为都可以被代理。 那么我们就可以给[代码]wx[代码]挂上代理: [代码]let originalWX = wx wx = new Proxy({}, { get(target, name) { if (name in originalWX ) { let fn = originalWX[name] let isSyncFunc = name.endsWith('Sync') // 同步函数 let isNotFunc = typeof fn !== 'function' // 非函数 if (isSyncFunc || isNotFunc) return fn return promisify(fn) } } }); [代码] 代理的方式虽解决了复制模式的冗余问题,但是仍有一个问题待解决:异步方法的判断。 在实践中,我发现并不是所有同步方法都是以[代码]Sync[代码]结尾的。比如:[代码]wx.getMenuButtonBoundingClientRect[代码]。 因此打算手动维护一个同步方法列表,将这项方法过滤掉: [代码]let syncFuncList = ['getMenuButtonBoundingClientRect'] // name为函数名 let isSync = name.endsWith('Sync') || syncFuncList.includes(name) [代码] 优化 考虑到要兼容已上线的小程序,若匆忙替换[代码]wx[代码],必会导致全局报错,因此可以如下处理: 当用户调用API时,如果传入了[代码]success[代码]、[代码]fail[代码]、[代码]complete[代码]等回调方法的话,则仍继续使用回调的方式继续执行。那么[代码]promisify[代码]可以如下优化: [代码]let originalWX = wx let hasCallback = obj => { let cbs = ['success', 'fail', 'complete'] return Object.keys(obj).some(k => cbs.includes(k)) } wx = new Proxy({}, { get(target, name) { if (name in originalWX ) { let fn = originalWX[name] let isSyncFunc = name.endsWith('Sync') // 同步函数 let isNotFunc = typeof fn !== 'function' // 非函数 if (isSyncFunc || isNotFunc) return fn return (obj) => { if (!obj) return fn() if (hasCallback(obj)) return fn(obj) return promisify(fn)(obj) } } } }); [代码] 由于本文的前提是开启 增强编译,而该模式下也新增支持[代码]Array.prototype.includes[代码],因此可以放心使用该ES7的新特性。 后续 由于发现了微信官方也提供了一个 API Promise化 的工具类库,因此增加了本章节。 通过阅读源代码,发现官方的工具类库提供两个方法:[代码]promisify[代码] 和 [代码]promisifyAll[代码] 其中[代码]promisify[代码]与前文的同名方法是几乎一致的。而[代码]promisifyAll[代码]则是接收两个参数,第一个是被封装的对象,第二个则是封装之后的对象,如下使用将和前文我提到的封装方式类似: [代码]import { promisifyAll } from 'miniprogram-api-promise'; let jwx = {} promisifyAll(wx, jwx) wx = jwx [代码] 另外还有一点需要提到的是,官方这个工具类库,判断是否为异步函数的方式是维护了一个异步方法列表,会存在遗漏新API的可能。 相当于我的做法是黑名单机制,而官方采用了白名单机制。 最后再提醒下,开发者工具记得打开 增强编译
2020-04-01 - 小程序页面(Page)扩展,为所有页面添加公共的生命周期、事件处理等函数
背景 在小程序的原生开发中,页面中经常会用到一些公共方法,例如在页面onLoad中验证权限、所有页面都需要onShareAppMessage设置分享等 假设我们在编码时每个页面都写一遍,显然不是一个高级程序员会干的事情,太Low了。如果我们定义一个公共文件,导出这些公共方法,每个页面都引入,然后再生命周期或者事件处理函数中调用,虽然看起来很方便,但不够优雅,达不到我们最终的目的(偷懒)。 下面给大家介绍一种相对比较优雅的实现方式,扩展Page来实现以上的操作。 Page(页面) 需要传入的是一个 [代码]object[代码] 类型的参数,那么我们重载一个 [代码]Page[代码] 函数,将这个 [代码]object[代码] 参数拦截改掉就可以了,下面直接上代码。 实现 1、在根目录新建一个 [代码]page-extend.js[代码] 文件,公共的逻辑都写在这里面 [代码]/** * * Page扩展函数 * * @param {*} Page 原生Page */ const pageExtend = Page => { return object => { // 导出原生Page传入的object参数中的生命周期函数 // 由于命名冲突,所以将onLoad生命周期函数命名成了onLoaded const { onLoaded } = object // 公共的onLoad生命周期函数 object.onLoad = function (options) { // 在onLoad中执行的代码 ... // 执行onLoaded生命周期函数 if (typeof onLoaded === 'function') { onLoaded.call(this, options) } } // 公共的onShareAppMessage事件处理函数 object.onShareAppMessage = () => { return { title: '分享标题', imageUrl: '分享封面' } } return Page(object) } } // 获取原生Page const originalPage = Page // 定义一个新的Page,将原生Page传入Page扩展函数 Page = pageExtend(originalPage) [代码] 2、在 [代码]app.js[代码] 中引入 [代码]page-extend.js[代码] 文件 [代码]require('./page-extend') App({ // 其他代码 ... }) [代码] 代码片段 https://developers.weixin.qq.com/s/Cyx8iGmV7Ldp 本文内容及评论未经允许,禁止任何形式的转载与复制(代码可在程序中使用)
2019-12-24