精华内容
下载资源
问答
  • 仓储石油计量微信小程序辅助应用的实现.pdf
  • 微信小程序辅助延续性护理干预对维持性血液透析患者并发症及饮食依从性的影响观察.pdf
  • 基于python的微信跳一跳小程序辅助,新增详细安装说明文档,已经修复了一些程序bug。 调整参数时先根据手机分辨率调整,若效果不好,可根据机型调整,已打包好机型配置参数,包括 华为,小米,苹果,三星多种机型。
  • 前两天看见微信里有同学在玩一笔画,我就玩了一会,很简单,但是还是有比较困难的关卡,比如这个然后就想着用算法写一个辅助,首先想到的就是回溯了
  • 微信小程序-家居电商 说明: 实现了家居电商功能。 数据接口: https://api.getweapp.com/vendor/huosu/api 目录结构: images — 存放项目图片 pages — 存放项目页面相关文件 utils — 存放时间处理和相关辅助...
  • 微信小程序系统教程[初级阶段],微信小程序0基础学起,讲解微信小程序开发的基础知识。 微信小程序系统教程共有“微信小程序系统教程[初级阶段]”、“微信小程序系统教程[中级阶段]——核心技术”、“微信小程序...
  • wxSortPickerView wxSortPickerView-微信小程序首字母排序选择表 wxSortPickerView信息 版本号0.1github地址:https://github.com/icindy/wxSortPickerView解决问题:...微信小程序开发论坛垂直微信小程序

    wxSortPickerView

    wxSortPickerView-微信小程序首字母排序选择表

    wxSortPickerView信息

    开发信息

    微信小程序开发论坛 垂直微信小程序开发交流社区

    特性

    目前为版本0.1,功能单一,但可扩展场景比较多。相关场景会在0.2中加入

    • 字符串数组首字母排序
    • 左侧点击abc跳转
    • 点击item返回数据

    扩展

    • 姓名排序选择
    • 地址排序选择

    功能预览

    使用方式

    • 1.引入相关文件

    • 2.初始化

    var wxSortPickerView = require('../../wxSortPickerView/wxSortPickerView.js');
    onLoad: function () {
        console.log('onLoad')
        var that = this
        //初始化
        wxSortPickerView.init(["艾–Ai","安–Ann/An","敖–Ao","巴–Pa","白–Pai","包/鲍–Paul/Pao","班–Pan","贝–Pei","毕–Pih","卞–Bein","卜/薄–Po/Pu","步–Poo","百里–Pai-li","蔡/柴–Tsia/Choi/Tsai","曹/晁/巢–Chao/Chiao/Tsao","岑–Cheng","崔–Tsui","查–Cha","常–Chiong","车–Che","陈–Chen/Chan/Tan","成/程–Cheng","池–Chi","褚/楚–Chu","淳于–Chwen-yu","戴/代–Day/Tai","邓–Teng/Tang/Tung","狄–Ti","刁–Tiao","丁–Ting/T","董/东–Tung/Tong","窦–Tou","杜–To/Du/Too","段–Tuan","端木–Duan-mu","东郭–Tung-kuo","东方–Tung-fang","范/樊–Fan/Van","房/方–Fang","费–Fei","冯/凤/封–Fung/Fong","符/傅–Fu/Foo","G:","盖–Kai","甘–Kan","高/郜–Gao/Kao","葛–Keh","耿–Keng","弓/宫/龚/恭–Kung","勾–Kou","古/谷/顾–Ku/Koo","桂–Kwei","管/关–Kuan/Kwan","郭/国–Kwok/Kuo","公孙–Kung-sun","公羊–Kung-yang","公冶–Kung-yeh","谷梁–Ku-liang","海–Hay","韩–Hon/Han","杭–Hang","郝–Hoa/Howe","何/贺–Ho","桓–Won","侯–Hou","洪–Hung","胡/扈–Hu/Hoo","花/华–Hua","宦–Huan","黄–Wong/Hwang","霍–Huo","皇甫–Hwang-fu","呼延–Hu-yen","I:","J:","纪/翼/季/吉/嵇/汲/籍/姬–Chi","居–Chu","贾–Chia","翦/简–Jen/Jane/Chieh","蒋/姜/江/–Chiang/Kwong","焦–Chiao","金/靳–Jin/King","景/荆–King/Ching","讦–Gan","K:","阚–Kan","康–Kang","柯–Kor/Ko","孔–Kong/Kung","寇–Ker","蒯–Kuai","匡–Kuang","L:","赖–Lai","蓝–Lan","郎–Long","劳–Lao","乐–Loh","雷–Rae/Ray/Lei","冷–Leng","黎/郦/利/李–Lee/Li/Lai/Li","连–Lien","廖–Liu/Liao","梁–Leung/Liang","林/蔺–Lim/Lin","凌–Lin","柳/刘–Liu/Lau","龙–Long","楼/娄–Lou","卢/路/陆鲁–Lu/Loo","伦–Lun","罗/骆–Loh/Lo/Law/Lam/Rowe","吕–Lui/Lu","令狐–Lin-hoo","M:","马/麻–Ma","麦–Mai/Mak","满–Man/Mai","毛–Mao","梅–Mei","孟/蒙–Mong/Meng","米/宓–Mi","苗/缪–Miau/Miao","闵–Min","穆/慕–Moo/Mo","莫–Mok/Mo","万俟–Moh-chi","慕容–Mo-yung","N:","倪–Nee","甯–Ning","聂–Nieh","牛–New/Niu","农–Long","南宫–Nan-kung","欧/区–Au/Ou","欧阳–Ou-yang","P:","潘–Pang/Pan","庞–Pang","裴–Pei/Bae","彭–Phang/Pong","皮–Pee","平–Ping","浦/蒲/卜–Poo/Pu","濮阳–Poo-yang","Q:","祁/戚/齐–Chi/Chyi/Chi/Chih","钱–Chien","乔–Chiao/Joe","秦–Ching","裘/仇/邱–Chiu","屈/曲/瞿–Chiu/Chu","R:","冉–Yien","饶–Yau","任–Jen/Yum","容/荣–Yung","阮–Yuen","芮–Nei","S:","司–Sze","桑–Sang","沙–Sa","邵–Shao","单/山–San","尚/商–Sang/Shang","沈/申–Shen","盛–Shen","史/施/师/石–Shih/Shi","苏/宿/舒–Sue/Se/Soo/Hsu","孙–Sun/Suen","宋–Song/Soung","司空–Sze-kung","司马–Sze-ma","司徒–Sze-to","单于–San-yu","上官–Sang-kuan","申屠–Shen-tu","T:","谈–Tan","汤/唐–Town/Towne/Tang","邰–Tai","谭–Tan/Tam","陶–Tao","藤–Teng","田–Tien","童–Tung","屠–Tu","澹台–Tan-tai","拓拔–Toh-bah","U:","V:","W:","万–Wan","王/汪–Wong","魏/卫/韦–Wei","温/文/闻–Wen/Chin/Vane/Man","翁–Ong","吴/伍/巫/武/邬/乌–Wu/NG/Woo","X:","奚/席–Hsi/Chi","夏–Har/Hsia/(Summer)","肖/萧–Shaw/Siu/Hsiao","项/向–Hsiang","解/谢–Tse/Shieh","辛–Hsing","刑–Hsing","熊–Hsiung/Hsiun","许/徐/荀–Shun/Hui/Hsu","宣–Hsuan","薛–Hsueh","西门–See-men","夏侯–Hsia-hou","轩辕–Hsuan-yuen","Y:","燕/晏/阎/严/颜–Yim/Yen","杨/羊/养–Young/Yang","姚–Yao/Yau","叶–Yip/Yeh/Yih","伊/易/羿–Yih/E","殷/阴/尹–Yi/Yin/Ying","应–Ying","尤/游–Yu/You","俞/庾/于/余/虞/郁/余/禹–Yue/Yu","袁/元–Yuan/Yuen","岳–Yue","云–Wing","尉迟–Yu-chi","宇文–Yu-wen","Z:","藏–Chang","曾/郑–Tsang/Cheng/Tseng","訾–Zi","宗–Chung","左/卓–Cho/Tso","翟–Chia","詹–Chan","甄–Chen","湛–Tsan","张/章–Cheung/Chang","赵/肇/招–Chao/Chiu/Chiao/Chioa","周/邹–Chau/Chou/Chow","钟–Chung","祖/竺/朱/诸/祝–Chu/Chuh","庄–Chong","钟离–Chung-li","诸葛–Chu-keh"],that);
      },
    
      //处理:accept:接受点击返回的文字
      wxSortPickerViewItemTap: function(e){
        console.log(e.target.dataset.text);
      } wxSortPickerView = require('../../wxSortPickerView/wxSortPickerView.js');
    onLoad: function () {
        console.log('onLoad')
        var that = this
        //初始化
        wxSortPickerView.init(["艾–Ai","安–Ann/An","敖–Ao","巴–Pa","白–Pai","包/鲍–Paul/Pao","班–Pan","贝–Pei","毕–Pih","卞–Bein","卜/薄–Po/Pu","步–Poo","百里–Pai-li","蔡/柴–Tsia/Choi/Tsai","曹/晁/巢–Chao/Chiao/Tsao","岑–Cheng","崔–Tsui","查–Cha","常–Chiong","车–Che","陈–Chen/Chan/Tan","成/程–Cheng","池–Chi","褚/楚–Chu","淳于–Chwen-yu","戴/代–Day/Tai","邓–Teng/Tang/Tung","狄–Ti","刁–Tiao","丁–Ting/T","董/东–Tung/Tong","窦–Tou","杜–To/Du/Too","段–Tuan","端木–Duan-mu","东郭–Tung-kuo","东方–Tung-fang","范/樊–Fan/Van","房/方–Fang","费–Fei","冯/凤/封–Fung/Fong","符/傅–Fu/Foo","G:","盖–Kai","甘–Kan","高/郜–Gao/Kao","葛–Keh","耿–Keng","弓/宫/龚/恭–Kung","勾–Kou","古/谷/顾–Ku/Koo","桂–Kwei","管/关–Kuan/Kwan","郭/国–Kwok/Kuo","公孙–Kung-sun","公羊–Kung-yang","公冶–Kung-yeh","谷梁–Ku-liang","海–Hay","韩–Hon/Han","杭–Hang","郝–Hoa/Howe","何/贺–Ho","桓–Won","侯–Hou","洪–Hung","胡/扈–Hu/Hoo","花/华–Hua","宦–Huan","黄–Wong/Hwang","霍–Huo","皇甫–Hwang-fu","呼延–Hu-yen","I:","J:","纪/翼/季/吉/嵇/汲/籍/姬–Chi","居–Chu","贾–Chia","翦/简–Jen/Jane/Chieh","蒋/姜/江/–Chiang/Kwong","焦–Chiao","金/靳–Jin/King","景/荆–King/Ching","讦–Gan","K:","阚–Kan","康–Kang","柯–Kor/Ko","孔–Kong/Kung","寇–Ker","蒯–Kuai","匡–Kuang","L:","赖–Lai","蓝–Lan","郎–Long","劳–Lao","乐–Loh","雷–Rae/Ray/Lei","冷–Leng","黎/郦/利/李–Lee/Li/Lai/Li","连–Lien","廖–Liu/Liao","梁–Leung/Liang","林/蔺–Lim/Lin","凌–Lin","柳/刘–Liu/Lau","龙–Long","楼/娄–Lou","卢/路/陆鲁–Lu/Loo","伦–Lun","罗/骆–Loh/Lo/Law/Lam/Rowe","吕–Lui/Lu","令狐–Lin-hoo","M:","马/麻–Ma","麦–Mai/Mak","满–Man/Mai","毛–Mao","梅–Mei","孟/蒙–Mong/Meng","米/宓–Mi","苗/缪–Miau/Miao","闵–Min","穆/慕–Moo/Mo","莫–Mok/Mo","万俟–Moh-chi","慕容–Mo-yung","N:","倪–Nee","甯–Ning","聂–Nieh","牛–New/Niu","农–Long","南宫–Nan-kung","欧/区–Au/Ou","欧阳–Ou-yang","P:","潘–Pang/Pan","庞–Pang","裴–Pei/Bae","彭–Phang/Pong","皮–Pee","平–Ping","浦/蒲/卜–Poo/Pu","濮阳–Poo-yang","Q:","祁/戚/齐–Chi/Chyi/Chi/Chih","钱–Chien","乔–Chiao/Joe","秦–Ching","裘/仇/邱–Chiu","屈/曲/瞿–Chiu/Chu","R:","冉–Yien","饶–Yau","任–Jen/Yum","容/荣–Yung","阮–Yuen","芮–Nei","S:","司–Sze","桑–Sang","沙–Sa","邵–Shao","单/山–San","尚/商–Sang/Shang","沈/申–Shen","盛–Shen","史/施/师/石–Shih/Shi","苏/宿/舒–Sue/Se/Soo/Hsu","孙–Sun/Suen","宋–Song/Soung","司空–Sze-kung","司马–Sze-ma","司徒–Sze-to","单于–San-yu","上官–Sang-kuan","申屠–Shen-tu","T:","谈–Tan","汤/唐–Town/Towne/Tang","邰–Tai","谭–Tan/Tam","陶–Tao","藤–Teng","田–Tien","童–Tung","屠–Tu","澹台–Tan-tai","拓拔–Toh-bah","U:","V:","W:","万–Wan","王/汪–Wong","魏/卫/韦–Wei","温/文/闻–Wen/Chin/Vane/Man","翁–Ong","吴/伍/巫/武/邬/乌–Wu/NG/Woo","X:","奚/席–Hsi/Chi","夏–Har/Hsia/(Summer)","肖/萧–Shaw/Siu/Hsiao","项/向–Hsiang","解/谢–Tse/Shieh","辛–Hsing","刑–Hsing","熊–Hsiung/Hsiun","许/徐/荀–Shun/Hui/Hsu","宣–Hsuan","薛–Hsueh","西门–See-men","夏侯–Hsia-hou","轩辕–Hsuan-yuen","Y:","燕/晏/阎/严/颜–Yim/Yen","杨/羊/养–Young/Yang","姚–Yao/Yau","叶–Yip/Yeh/Yih","伊/易/羿–Yih/E","殷/阴/尹–Yi/Yin/Ying","应–Ying","尤/游–Yu/You","俞/庾/于/余/虞/郁/余/禹–Yue/Yu","袁/元–Yuan/Yuen","岳–Yue","云–Wing","尉迟–Yu-chi","宇文–Yu-wen","Z:","藏–Chang","曾/郑–Tsang/Cheng/Tseng","訾–Zi","宗–Chung","左/卓–Cho/Tso","翟–Chia","詹–Chan","甄–Chen","湛–Tsan","张/章–Cheung/Chang","赵/肇/招–Chao/Chiu/Chiao/Chioa","周/邹–Chau/Chou/Chow","钟–Chung","祖/竺/朱/诸/祝–Chu/Chuh","庄–Chong","钟离–Chung-li","诸葛–Chu-keh"],that);
      },
    
      //处理:accept:接受点击返回的文字
      wxSortPickerViewItemTap: function(e){
        console.log(e.target.dataset.text);
      }

    其他插件

    开发信息

    微信小程序开发论坛 垂直微信小程序开发交流社区

    原文  https://github.com/icindy/wxSortPickerView

     【关于我们】

    才淇(微信公众号:caiqicehua),专注于国内各大互联网公司社会招聘内推。每天更新最新互联网名企(包括但不限于今日头条、网易游戏、BAT、网易互联网、小米、京东、乐视、携程等名企)内推信息,有技术岗、有产品岗、有运营岗、有设计岗、有交互岗、有销售岗,更有其他N多相关岗位!更多内推信息请扫描以下二维码关注查阅。

     

    展开全文
  • wx_dictation:微信小程序听写辅助系统
  •   首先,我们需要知道微信小程序是什么?微信小程序内核是什么?微信小程序的开发语言什么?这样才能更好的开发微信小程序,以及解决遇到的问题。 一、微信小程序是什么 微信小程序是一个依托于微信,微信提供一个...

    前言

      工欲善其事,必先利其器

      首先,我们需要知道微信小程序是什么?微信小程序内核是什么?微信小程序的开发语言什么?这样才能更好的开发微信小程序,以及解决遇到的问题。

    一、微信小程序是什么

    微信小程序是一个依托于微信,微信提供一个接口运行浏览器内核上的一个程序。

      微信小程序是一个小程序可以有很多页面,每个页面承载不同的功能,页面之间可以互相跳转。小程序分为渲染层和逻辑层,渲染层中包含了多个 WebView,每个 WebView 对应到我们的小程序里就是一个页面 Page,每一个页面都独立运行在一个页面层级上。它也可以做得很丰富,就像native app一样,可以调用原生的各种接口,像网络状态、罗盘,重力,拨打电话等

    二、微信小程序内核是什么

    微信小程序的编译内核环境根据不同平台而不同。

    • 在 iOS 上,小程序的 javascript 代码是运行在 JavaScriptCore 中
    • 在 Android 上,小程序的 javascript 代码是通过 X5 内核来解析
    • 在 开发工具上, 小程序的 javascript 代码是运行在 nwjs(chrome内核) 中

    JavaScriptCore

    JavaScriptCores是开源的,下载地址:https://github.com/phoboslab/JavaScriptCore-iOS

    OS X Mavericks 和 iOS 7 引入了 JavaScriptCore 库,它把 WebKit 的 JavaScript 引擎用 Objective-C 封装,提供了简单,快速以及安全的方式接入世界上最流行的语言。不管你爱它还是恨它,JavaScript 的普遍存在使得程序员、工具以及融合到 OS X 和 iOS 里这样超快的虚拟机中资源的使用都大幅增长。(参考iOS官方文档:https://developer.apple.com/documentation/javascriptcore?language=objc)

    X5 内核

    唯一一个属于国人开发,大鹅厂自己的浏览器解析内核

    nwjs

    原名:node-webkit 当然也是开源的:https://github.com/nwjs/nw.js/

    nw.js 是基于 Chromium和 Node.js运行的, 以前也叫nodeWebkit。这就给了你使用HTML和JavaScript来制作桌面应用的可能。在应用里你可以直接调用Node.js的各种api以及现有的第三方包。因为Chromium和 Node.js的跨平台,那么你的应用也是可以跨平台的。现在已经有很多知名的应用是基于NW.js实现,

    三、微信小程序的开发语言是什么

    1.微信小程序的开发

      微信小程序使用了前端技术栈 JavaScript/WXML/WXSS

    • JavaScript: 微信小程序的 JavaScript 运行环境即不是 Browser 也不是 Node.js。它运行在微信 App 的上下文中,不能操作 Browser context 下的 DOM,也不能通过 Node.js 相关接口访问操作系统 API。所以,严格意义来讲,微信小程序并不是 Html5,虽然开发过程和用到的技术栈和 Html5 是相通的。
    • WXML: 作为微信小程序的展示层,并不是使用 Html,而是自己发明的基于 XML 语法的描述。
    • WXSS: 用来修饰展示层的样式。官方的描述是 “ WXSS (WeiXin Style Sheets) 是一套样式语言,用于描述 WXML 的组件样式。WXSS 用来决定 WXML 的组件应该怎么显示。” “我们的 WXSS 具有 CSS 大部分特性…我们对 CSS 进行了扩充以及修改。”基于 CSS2 还是 CSS3?大部分是哪些部分?是否支持 CSS3 里的动画?不得而知。

    四、微信小程序

    1.小程序与普通网页开发的区别

    小程序的主要开发语言是 JavaScript ,所以通常小程序的开发会被用来同普通的网页开发来做对比。两者有很大的相似性,对于前端开发者而言,从网页开发迁移到小程序的开发成本并不高,但是二者还是有些许区别的。

    网页开发渲染线程和脚本线程是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应,而在小程序中,二者是分开的,分别运行在不同的线程中。网页开发者可以使用到各种浏览器暴露出来的 DOM API,进行 DOM 选中和操作。而如上文所述,小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的DOM API和BOM API。这一区别导致了前端开发非常熟悉的一些库,例如 jQuery、 Zepto 等,在小程序中是无法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,所以一些 NPM 的包在小程序中也是无法运行的

    网页开发者需要面对的环境是各式各样的浏览器,PC 端需要面对 IE、Chrome、QQ浏览器等,在移动端需要面对Safari、Chrome以及 iOS、Android 系统中的各式 WebView 。而小程序开发过程中需要面对的是两大操作系统 iOS 和 Android 的微信客户端,以及用于辅助开发的小程序开发者工具,小程序中三大运行环境也是有所区别的.如表1-1所示。

    表1-1 小程序的运行环境
    运行环境逻辑层渲染层
    iOSJavaScriptCoreWKWebView
    安卓X5 JSCoreX5浏览器
    小程序开发者工具NWJSChrome WebView

    2.WebView

    WebView的运行流程和一些弊端。

    流程:
    打开一个 WebView 通常会经历以下几个阶段:

    • 交互无反馈
    • 到达新的页面,页面白屏
    • 页面基本框架出现,但是没有数据;页面处于 loading 状态
    • 出现所需的数据

    WebView 启动过程大概分为以下几个阶段:
    WebView启动过程

    存在的问题:
    在加载WebView页面时,时常出现白屏现象:
    加载WebView出现白屏
    除了白屏,影响 Web 体验的问题还有缺少操作的反馈,主要表现在两个方面:页面切换的生硬和点击的迟滞感。

    3.微信小程序

    1)通信模型

    小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端(下文中也会采用Native来代指微信客户端)做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型如下图所示。
    渲染过程
    这就是小程序双线程模型的由来:

    • 逻辑层:创建一个单独的线程去执行 JavaScript,在这个环境下执行的都是有关小程序业务逻辑的代码
    • 渲染层:界面渲染相关的任务全都在 WebView 线程里执行,通过逻辑层代码去控制渲染哪些界面。一个小程序存在多个界面,所以渲染层存在多个 WebView 线程.
    2)双线程下的界面渲染

    小程序的逻辑层和渲染层是分开的两个线程。在渲染层,宿主环境会把WXML转化成对应的JS对象,在逻辑层发生数据变更的时候,我们需要通过宿主环境提供的setData方法把数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的Dom树上,渲染出正确的UI界面,如下图所示。

    界面渲染
    小程序的渲染的整体流程:

    • 1.在渲染层把 WXML 转化成对应的 JS 对象。
    • 2.在逻辑层发生数据变更的时候,通过宿主环境提供的 setData 方法把数据从逻辑层传递到 Native,再转发到渲染层。
    • 3.经过对比前后差异,把差异应用在原来的 DOM 树上,更新界面。

    总之,小程序通过双线程的方式解决WebView存在的各种问题,让小程序更加想Native的体验。

    参考:《小程序开发指南》

    展开全文
  • 主要为大家详细介绍了安卓版微信小程序跳一跳辅助,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要为大家详细介绍了ios版微信小程序跳一跳辅助,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 基于微信小程序的签到辅助教学平台.pdf
  • 微信小程序—头脑王者辅助(一部手机即可,只需配置WiFi代理)
  • 主要介绍了解决mpvue + vuex 开发微信小程序 vuex辅助函数mapState、mapGetters不可用问题,需要的朋友可以参考下
  • 使用 webpack, babel, scss 开发的微信小程序项目脚手架 功能 支持引用 node_modules 模块 支持通过配置 alias 来避免 ../../../ 之类的模块引用 通过 babel 支持更丰富的 ES6 兼容,包括 async/await 内置 promise...
  • 这里先说一说下面一些(left, upper, right, lower)坐标是怎么确定的 首先,从微信进入头脑王者2,开始一场比赛 将比赛的有题目图截下来,截到图片的一般大小都是(1920*1080),比如下图: 然后以实际尺寸打开这张...

    今天来做一个好玩的,这个脚本做出来需要一点脑洞,hh~

    当然,当你可以用adb控制手机的时候,不止能干这么些,还有更多有意思的,这就需要更大的脑洞了,比如自动薅羊毛~

    思路:

    利用adb截手机实时图

    利用python图像处理库PIL处理图片将问题和答案的那一块截出来

    利用百度识图,将图片转为中文字符串

    利用百度搜索,搜索已转为中文字符串的问题

    统计百度返回网页源码中对应答案出现的次数,出现次数最多的则视为正确答案

    继续利用adb模拟点击手机中答案位置

    什么是adb?

    adb即 AndroidDebug Bridge,我们一般简称为adb,它是一个非常强大的命令行工具,通过这个工具你能够利用电脑与你的android设备进行交互。

    记得将解压后的工具包添加到系统变量上,这样方便你用python脚本调用它。

    可以参考这篇博文:常用的adb命令

    一、将手机与电脑连接上

    这一步首先需要手机开启开发者模式,因为各个手机打开的方式不一样,请根据自己机型自行百度。

    然后是将手机用usb线连接电脑,在cmd下输入adb devices

    若有如下图的返回则手机和电脑连接成功:

    1647816-20190514003814149-393172419.png

    二、按上面的思路来打码

    1、 利用adb截手机实时图

    2、利用python图像处理库PIL处理图片将问题和答案的那一块截出来

    这两步放在一个函数里就行了

    这里先说一说下面一些(left, upper, right, lower)坐标是怎么确定的

    首先,从微信进入头脑王者2,开始一场比赛

    将比赛的有题目图截下来,截到图片的一般大小都是(1920*1080),比如下图:

    1647816-20190514005626707-1487761494.jpg

    然后以实际尺寸打开这张图片,再用截图工具量一下所需位置的宽高(当你截图时,一般截图工具会显示将要截的像素大小),或者你有更好的方法就另说。比如下两图是我获取问题的位置(左,上,右,下)的思路,其他位置也是这样获取:

    1647816-20190514010119536-1397579741.png

    1647816-20190514010145981-359286161.png

    然后就确定这些坐标了~

    adb截手机实时图代码:

    importosimportrandomimportrequestsimportsubprocessfrom PIL importImagefrom aip importAipOcrfrom io importBytesIOdefget_screenshot():

    process=subprocess.Popen('adb shell screencap -p',shell=True,stdout=subprocess.PIPE)#相对于在cmd下执行了adb shell screencap -p,将会去截手机屏幕图

    screenshot=process.stdout.read()#读取截到的数据screenshot=screenshot.replace(b'\r\n', b'\n')#adb直接截的图在有点的问题,以二进制替换一下字符就可以了。

    img_fb=BytesIO()#BytesIO操作二进制数据,因为图片是二进制文件

    img_fb.write(screenshot)#写入内存

    img=Image.open(img_fb)#在内存打开图片

    title_img=img.crop((200,420,890,790))#裁剪原图,对应(left, upper, right, lower)剪出来的是问题那部分图片

    answers_img=img.crop((80,960,1000,1720))#裁剪原图,剪出来的是答案那部分图片

    new_img=Image.new('RGBA',(920,1140))#新建一张图片,用来保存上面剪问题和答案部分,就是去掉了玩家头像之类的那些杂质

    new_img.paste(title_img,(0,0,690,370))#问题粘贴到新建的大图

    new_img.paste(answers_img,(0,380,920,1140))#答案粘贴到新建的大图,过滤了不必要的元素

    new_img_fb=BytesIO()

    new_img.save(new_img_fb,'png')#保存图片

    with open('test.png','wb') as f:

    f.write(new_img_fb.getvalue())return new_img_fb #返回新生成的图片

    3、利用百度识图,将图片转为中文字符串

    到百度云注册个账号:直达

    到控制台-产品服务-人工智能-文字识别创建一个文字识别的应用如下,这种普通的文字识别每月有5w次的免费次数(开通这个应用免费,不用实名认证),我感觉没什么特殊的要求的话这已经绰绰有余了。

    1647816-20190514011312167-1085891733.png

    创建之后要找到这个位置,待会要用到里面的key:

    1647816-20190514011940568-1495284708.png

    对,还要pip安装百度云的python sdk

    pip install baidu-aip

    详情可到这里看看:文档直达

    具体的利用:

    defget_word_by_image(img):

    APPID= ''APIKey= ''SecretKey= '' #这三个都在账号里面,上面有提到

    client = AipOcr(APPID, APIKey, SecretKey) #创建链接

    res=client.basicGeneral(img) #将图片传过去

    return res #识图结果

    4、利用百度搜索,搜索已转为中文字符串的问题

    5、统计百度返回网页源码中对应答案出现的次数,出现次数最多的则视为正确答案

    这两个也在一个函数里~

    写个简单的爬虫逻辑就行了,如下:

    defbaidu(question,answer):

    url='https://www.baidu.com/s'headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}

    data={'wd':question

    }

    res=requests.get(url=url,params=data,headers=headers)

    res.encoding=res.apparent_encoding

    html=res.textfor i inrange(len(answer)):

    answer[i]=(html.count(answer[i]),answer[i],i) #循环4次,将答案在百度返回源码中出现的次数统计出来

    answer.sort(reverse=True) #按降序排序答案,以出现在源码中次数最高的为答案

    return answer

    6、继续利用adb模拟点击手机中答案位置

    defclick(point):

    cmd='adb shell input swipe %s %s %s %s %s'%(

    point[0],

    point[1],

    point[0]+random.randint(0,3), #swipe实际上是拖动手机,这里加randint(0,3)是为了模拟长按手机

    point[1]+random.randint(0,3),200 #上面4个为坐标,这个200为持续点击的时间ms为它的单位

    )

    os.system(cmd)

    三、利用以上函数

    config={ #配置'头脑王者':{'title':(200,420,890,790), #用来记录标题的位置

    'answers':(80,960,1000,1720),'point':[

    (316,993,723,1078),

    (316,1174,723,1292),

    (316,1366,723,1469),

    (316,1570,723,1657),#四个答案的位置

    ]

    }

    }defrun():print('准备答题')whileTrue:

    input('请按回车键开始答题:')

    img=get_screenshot()

    info=get_word_by_image(img.getvalue())if info['words_result_num']<5:continueanswers=[x['words'] for x in info['words_result'][-4:]] #提取返回的对应题目答案的中文字符串,这个与百度云返回的数据结构有关,不必深究,会用就行

    question=''.join([x['words'] for x in info['words_result'][:-4]]) #提取返回的问题的中文字符串

    res=baidu(question,answers)print(question)print(res)print(config['头脑王者']['point'][res[0][2]])

    click(config['头脑王者']['point'][res[0][2]]) #模拟点击

    四、总结

    因为脚本有多次图像处理及连接网络的要求,所以效率会有点慢的其实。

    而且也不一定对,因为是靠百度的答案,若你有题库就能快很多了。

    The end~

    展开全文
  • 微信小程序

    千次阅读 2021-01-19 13:36:38
    为什么是微信小程序1.2.微信小程序历史1.3.疯狂的微信小程序1.4.还有其他的小程序 不容忽视1.5.体验1.5.1.官方微信小程序体验1.5.2. 优秀的微信第三方小程序2.环境准备2.1.注册账号2.2.获取APPID2.3.开发工具3.第一...

    文章目录

    1.微信小程序介绍


    微信小程序,简称小程序,英⽂名 Mini Program ,是⼀种不需要下载安装即可使⽤的应⽤,它实现了应⽤“触⼿可及”的梦想,用户扫⼀扫或搜⼀下即可打开试用。

    1.1.为什么是微信小程序

    1. 微信有海量用户,而且粘性很高,在微信里开发产品更容易触达⽤⼾;
    2. 推广app的成本太⾼。
    3. 微信小程序开发适配成本低。
    4. 规模小容易试错,然后快速迭代。
    5. 跨平台。

    1.2.微信小程序历史

    • 2016年1⽉11⽇,微信之父张小龙时隔多年的公开亮相,解读了微信的四⼤价值观。张小龙指出,越来越多产品通过公众号来做,因为这⾥开发、获取用户和传播成本更低。拆分出来的服务号并没有提供更好的服务,所以微信内部正在研究新的形态,叫**「微信小程序」 需要注意的是,之前是叫做「应用号」 **。
    • 2016年9⽉21⽇,微信⼩程序正式开启内测。在微信生态下,触⼿可及、用完即⾛的微信小程序引
      起⼴泛关注。腾讯云正式上线微信小程序解决方案,提供小程序在云端服务器的技术⽅案。
    • 2017年1⽉9⽇,微信推出的“小程序”正式上线。“小程序”是⼀种⽆需安装,即可使⽤的⼿机“应用”。不需要像往常⼀样下载App,用户在微信中“用完即⾛”。

    1.3.疯狂的微信小程序

    1. 微信月活已经达到10.82亿。其中55岁以上的用户也达到6300万
    2. 信息传达数达到450亿,较去年增长18%;视频通话4.1亿次,增长100%
    3. 小程序覆盖超过200+行业,交易额增长超过6倍,服务1000亿+人次,创造出了5000亿+的商业价值。

    1.4.还有其他的小程序 不容忽视

    1. 支付宝小程序
    2. 百度小程序
    3. QQ小程序
    4. 今日头条+抖音小程序

    1.5.体验

    1.5.1.官方微信小程序体验

    小程序示例源码

    1.5.2. 优秀的微信第三方小程序

    • 拼多多
    • 滴滴出行
    • 欢乐斗地主
    • 智行火车票
    • 唯品会

    2.环境准备

    开发微信小程序之前,必须要准备好相应的环境

    2.1.注册账号

    微信小程序需要标注唯一的开发者信息,因此需要申请注册账号。建议使用全新的邮箱(作为登录帐号,请填写未被微信公众平台注册,未被微信开放平台注册,未被个人微信号绑定的邮箱),没有注册过其他小程序或者公众号的。

    访问注册页面,耐心完成注册即可。

    • 账户信息

    • 邮箱激活

    • 信息登记

    2.2.获取APPID

    由于后期调⽤微信⼩程序的接⼝等功能,需要索取开发者的⼩程序中的 APPID ,所以在注册成功后, 可登录,然后获取APPID。

    登录成功后可看到如下界面

    然后复制你的APPID,悄悄的保存起来,不要给别⼈看到。

    2.3.开发工具

    下载地址

    微信小程序自带开发者工具,集 **开发、预览、调试、发布 **于⼀⾝的 完整环境。

    但是由于编码的体验不算好,因此 建议使⽤ vs code + 微信小程序编辑工具 来实现编码

    vs code 负责敲代码, 微信编辑工具 负责预览

    3.第一个微信小程序

    3.1.打开微信开发者工具

    注意 第⼀次登录的时候 需要扫码登录

    3.2.新建小程序项目

    3.3.填写项目信息

    3.4.创建成功

    4.微信开发者工具介绍

    详细的使⽤,可以查看官网

    5.小程序结构目录

    小程序框架的目标是通过尽可能简单、⾼效的方式让开发者可以在微信中开发具有原生APP体验的服务。

    小程序框架提供了自己的视图层描述语言WXML 和 WXSS ,以及 JavaScript (小程序有自己的标签、样式、文件以及逻辑文件),并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑**(我们写代码的时候尽可能少关注操作页面结构,只需要关注页面本身)**。

    5.1.小程序文件结构和传统web对比

    传统web微信小程序
    结构HTMLWXML
    样式CSSWXSS
    逻辑JavaScriptjavascript
    配置JSON

    通过以上对比得出,传统web是三层结构。而微信小程序是四层结构,多了⼀层配置.json

    5.2.基本的项目目录

    6.小程序配置文件

    ⼀个小程序应用程序会包括最基本的两种配置⽂件。⼀种是全局的app.json和页面自己的page.json

    注意:JSON配置文件中不能出现注释

    6.1.全局配置app.json

    app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界⾯表现、网络超时时间、底部tab等。普通快速启动项目里面的 app.json 配置。如果想将哪个页面作为首页,只需要在pages中放在第一即可。

    此时为index页面在第一位置

    {
        "pages": [
            "pages/index/index", 
            "pages/logs/logs"
        ], 
        "window": {
            "backgroundTextStyle": "light", 
            "navigationBarBackgroundColor": "#fff", 
            "navigationBarTitleText": "WeChat", 
            "navigationBarTextStyle": "black"
        }, 
        "style": "v2", 
        "sitemapLocation": "sitemap.json"
    }
    

    字段的含义

    1. pages 字段⸺用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。

      • pages保存页面路径,不需要保存文件名后缀

      • 新增页面的只需要在微信小程序的开发者工具中编辑app.json的新增页面名称,保存就可以自动生成页面的文件夹以及配置文件。

    2. window 标题⸺定义小程序所有页面的顶部背景颜色,文字颜色定义等。

      具体内容可参考

      其他参考位置

    6.1.1.tabbar

    下方的页面的导航栏设置在app.jsp配置,主要用于导航操作。

    1. 首先准备导航栏图标样式,同一个功能图标设置两种。一是未点击状态下显示的图标,而是点击状态下显示的图标

    2. 在app.json中进行配置

      {
        "pages":[
          "pages/index/index",
          "pages/img/img",
          "pages/mine/mine",
          "pages/search/search",
          "pages/demo2/demo2",
          "pages/logs/logs",
          "pages/demo1/demo1"
        ],
        "window":{
          "backgroundTextStyle":"dark",
          "navigationBarBackgroundColor": "#0094ff",
          "navigationBarTitleText": "我的应用",
          "navigationBarTextStyle":"white",
          "enablePullDownRefresh": true,
          "backgroundColor":"#FFFF00"
        },
        "tabBar": {
          "list": [{
            "pagePath": "pages/index/index",
            "text": "首页",
            "iconPath": "icon/_home.png",
            "selectedIconPath": "icon/home.png"
          },{
            "pagePath": "pages/img/img",
            "text": "图片",
            "iconPath": "icon/_img.png",
            "selectedIconPath": "icon/img.png"
          },{
            "pagePath": "pages/search/search",
            "text": "搜索",
            "iconPath": "icon/_search.png",
            "selectedIconPath": "icon/search.png"
          },{
            "pagePath": "pages/mine/mine",
            "text": "我的",
            "iconPath": "icon/_my.png",
            "selectedIconPath": "icon/my.png"
          }],
          "color": "#0094ff",
          "selectedColor": "#ff9400",
          "backgroundColor": "#ff5533",
          "position":"buttom"
        },
        "style": "v2",
        "sitemapLocation": "sitemap.json"
      }
      
      • 首先在pages设置所有的显示页面,首页放在第一位置
      • 在tabBar中的list中存放所有导航栏每个按钮的信息。
        • pagePath为跳转的页面地址
        • text为显示提示文本信息
        • iconPath为默认状态下的图标
        • selectedIconPath选中状态下的图标
      • 在tabBar的color设置text为显示提示文本的颜色。
      • 在tabBar的selectedColor设置text为显示提示文本选中后的颜色
      • 在tabBar的position设置tabBar的位置,默认为buttom即在屏幕底部,设置为top则显示在顶部
    3. 显示效果

    6.2.pageName.json

    这里的page.json其实用来表示页面目录下的page.json 这类和小程序页面相关的配置。

    开发者可以独立定义每个页面的⼀些属性,如顶部颜色、是否允许下拉刷新等等。

    页面的配置只能设置 app.json 中部分 window 配置项的内容,页面中配置项会覆盖 app.json 的 window 中相同的配置项数据。

    属性类型默认值描述
    navigationBarBackgroundColorHexColor#000000导航栏背景颜色,如 #000000
    navigationBarTextStyleStringwhite导航栏标题颜色,仅⽀持 black / white
    navigationBarTitleTextString导航栏标题文字内容
    backgroundColorHexColor#ffffff窗口的背景色
    backgroundTextStyleStringdark下拉 loading 的样式,仅支持 dark / light
    enablePullDownRefreshBooleanfalse是否全局开启下拉刷新。 详见Page.onPullDownRefresh
    onReachBottomDistanceNumber50页面上拉触底事件触发时距页面底部距离,单位为px。 详见Page.onReachBottom
    disableScrollBooleanfalse设置为 true 则页⾯整体不能上下滚动;只在页面配置中有 效,无法在app.json中设置该项

    6.3.sitemap配置-了解即可

    小程序根目录下的sitemap.json⽂件⽤于配置小程序及其页面是否允许被微信索引。

    7.模板语法

    WXML(WeiXin Markup Language)是框架设计的⼀套标签语言,结合基础组件、事件系统,可以构建出页面的结构。

    小程序因为存在模板语法,所有才能实现页面渲染和动态功能。

    7.1.数据绑定

    pageName.js中Page()方法传入一个对象{……},对象有格式要求。data:{},名字是关键字,不可修改,存放初始化数据,其他的都是生命周期函数。

    数据绑定的主要内容就是获取pageName.js中的data:{}中的数据,展示出来。

    VS CODE可以使用微信小程序开发助手插件辅助编程

    7.1.1.普通写法

    1. 准备数据

      Page({
            data: {
              	message: 'Hello MINA!'
           }
      })
      
    2. 获取数据

      <view> {{ message }} </view>
      

    7.1.2.组件属性

    1. 准备数据

      Page({
            data: {
              	id: 0
           }
      })
      
    2. 获取数据

      <view id="item-{{id}}"> </view>
      

    7.1.3.bool类型

    不要直接写 checked=false,其计算结果是⼀个字符串

    <checkbox checked="{{false}}"> </checkbox>
    

    7.1.4.示例

    1. 准备数据

      Page({
            /**
             * 页面的初始数据
             */
            data: {
                  msg: "hello mina",
                  num: 10000,
                  isGirl: false,
                  person: {
                        age: 74,
                        height: 145,
                        weight: 200,
                        name: "牛"
                  },
                  isChecked:true
            },
      })
      
    2. 测试

      <!-- 
        1 text 相当于以前web中的 span标签 行内元素  不会换行
        2 view 相当于以前web中的 div标签 块级元素  会换行
        3 checkbox 以前的复选框标签 
       -->
      <!-- <text>1</text>
      <text>2</text>
      <view>1</view>
      <view>2</view> -->
      
      <!-- 1 字符串 -->
      <view> {{msg}} </view>
      <!-- 2 数字类型 -->
      <view>{{num}}</view>
      <!-- 3 bool类型  -->
      <view> 是否是女生: {{isGirl}} </view>
      <!-- 4 object类型 -->
      <view>{{person.age}}</view>
      <view>{{person.height}}</view>
      <view>{{person.weight}}</view>
      <view>{{person.name}}</view>
      
      <!-- 5 在标签的属性中使用 -->
      <view data-num="{{num}}"> 自定义属性</view>
      
      <!-- 
        6 使用bool类型充当属性 checked  
          1 字符串和花括号之间一定不要存在空格 否则会导致识别失败 
            以下写法就是错误的示范
               <checkbox checked="       {{isChecked}}"> </checkbox>
       -->
      <view>
        <checkbox checked="{{isChecked}}"> </checkbox>
      </view>
      
    3. 效果

    7.1.5.复杂data数据设置

    Page({
        data: {
            userInfo:{},
        },
        
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {
            //页面加载是接受数据,设置参数
            this.setData({
                userInfo: {
                    xm: options.xm,
                    sfzh: options.sfzh,
                    openid:options.opendid
                },
            })
        },
    })
    

    7.2.表达式运算

    表达式运算是指可以在花括号中加入表达式进行简单运算

    概念区分:

    • 表达式:指的是一些简单运算、数字运算、字符串拼接、逻辑运算。
      1. 数字的加减
      2. 字符串拼接
      3. 三元表达式
    • 语句:指复杂的代码段
      1. if else
      2. switch
      3. do while
      4. for

    7.2.1.三元运算

    <view hidden="{{flag ? true : false}}"> Hidden </view>
    

    7.2.2.算数运算

    Page({
      data: {
        a: 1,
        b: 2,
        c: 3
     }
    })
    
    <view> {{a + b}} + {{c}} + d </view>
    

    最终显示结果:3 + 3 + d

    7.2.3.逻辑判断

    Page({
      data: {
        length:6
     }
    })
    
    <view wx:if="{{length > 5}}">大于5</view>
    

    最终结果:大于5

    7.2.4.字符串运算

    Page({
      data:{
        name: 'Stonebridge'
     }
    })
    
    <view>{{"hello," + name}}</view>
    

    最终显示结果:hello,Stonebridge

    7.2.5.注意

    花括号和引号之间如果有空格,将最终被解析成为字符串

    7.2.6.示例

    <view>{{1+1}}</view>
    <view>{{'1'+'1'}}</view>
    <view>{{ 11%2===0 ? '偶数' : '奇数' }}</view>
    

    最终效果:

    7.3.列表渲染

    7.3.1.列表循环

    1. wx:for="{{数组或者对象}}" wx:for-item=“循环项的名称” wx:for-index=“循环项的索引”

    2. wx:key=“唯一的值” 用来提高列表渲染的性能

      • wx:key 绑定一个普通的字符串的时候那么这个字符串名称肯定是循环数组中的对象的唯一属性

      • wx:key ="*this" 就表示你的数组是一个普通的数组 *this 表示是循环项

        [1,2,3,44,5]
        [“1”,“222”,“adfdf”]

    3. 当出现数组的嵌套循环的时候,尤其要注意以下绑定的名称不要重名

      wx:for-item=“item” wx:for-index="index"

    4. 默认情况下我们不写wx:for-item=“item” wx:for-index=“index”。小程序也会把循环项的名称和索引的名称item和index。故只有一层循环的话 (wx:for-item=“item” wx:for-index=“index”)可以省略。

    示例

    1. 准备数据

      Page({
          /**
         * 页面的初始数据
         */
          data: {
              list:[
                      {
                          id:0,
                          name:"尤里"
                      },
                      {
                          id:1,
                          name:"普莱斯"
                      },
                      {
                          id:2,
                          name:"麦克塔维什"
                      }
              	]
          	},
      })
      
    2. 显示数据

       <view>
             <view wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="id">
               索引:{{index}}
               --
               值:{{item.name}}
             </view>
       </view>
      

      **wx:for-item=“item” wx:for-index=“index”**可省略

    3. 最终效果

    7.3.2.对象循环

    1. wx:for="{{对象}}" wx:for-item=“对象的值” wx:for-index=“对象的属性”
    2. 循环对象的时候最好把 item和index的名称都修改一下wx:for-item=“value” wx:for-index=“key”

    示例

    1. 准备数据

      Page({
        /**
         * 页面的初始数据
         */
          person: {
            age: 74,
            height: 145,
            weight: 200,
            name: "麦克塔维什"
          }
        },
      })
      
    2. 展示数据

      <view>
         <view>对象循环</view>
         <view wx:for="{{person}}" wx:for-item="value"  wx:for-index="key" wx:key="age">属性:{{key}}--值:{{value}}</view>
       </view>
      
    3. 最终效果

    7.3.3.列表循环

    result.modlist为一个JSON列表,通过for循环进行遍历,通过编号获取其中的值,进行修改后再赋值进去

    var result = JSON.stringify(response);
    result = JSON.parse(result);
    //遍历首页的功能模块,为其跳转的地址根据功能代码(gndm)为其赋值参数
    //1.如果是跳转到H5页面,将地址和参数准备好后使用Base64编码后存放在url中,在container.js中获取后直接解码使用
    for (var i = 0; i < result.modlist.length; i++) {
        var module = result.modlist[i];
        if (module.gndm == "WAK01") {
            module.url = Base64.encode(module.url + "?openid=" + userInfo.openid + "&yhdm=" + userInfo.yhdm);
        } else if (module.gndm == "WAK02") {
            module.url = Base64.encode(module.url + "?yhid=" + userInfo.yhdm + "&fydm=" + userInfo.dwdm);
        }
    }
    

    7.3.4.block

    1. 占位符的标签
    2. 写代码的时候可以看到这标签存在
    3. 页面渲染小程序会把它移除掉

    示例

    1. 展示数据

      <view>
          <block wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="id" class="my_list">
            索引:{{index}}
            --
            值:{{item.name}}
          </block>
      </view>
      
    2. 最终效果

    7.4.条件渲染

    7.4.1.wx:if

    在框架中,使⽤ wx:if="{{condition}}" 来判断是否需要渲染该代码块,condition为true/false;

    以及if , else , if else
    wx:if
    wx:elif
    wx:else

    示例:

    <view>
         <view>条件渲染</view>
         <view wx:if="{{true}}">显示</view>
         <view wx:if="{{false}}">隐藏</view>
    
         <view wx:if="{{flase}}">1</view>
         <view wx:elif="{{flase}}">2</view>
         <view wx:else> 3 </view>
    </view>
    

    示例:

    7.4.2.hidden

    1. 在标签上直接加入属性 hidden
    2. hidden="{{true}}"

    示例

    <view>
         <view>条件渲染</view>
         <view>---------------</view>
         <view hidden >hidden1</view>
         <view hidden="{{false}}" >hidden2</view>
    
         <view>-----000-------</view>
         <view wx:if="{{false}}">wx:if</view>
         <view hidden>hidden</view>
    </view>
    

    **注意:**hidden属性不要和样式display一起使用

    7.4.3.二者选择

    **当标签频繁的切换显示的时候 优先使用 hidden通过添加样式的方式来切换显示 **

    8.小程序事件的绑定

    小程序中绑定事件,通过bind关键字来实现。如bindtap、bindinput、bindchange等不同的组件支持不同的事件,具体看组件的说明即可。

    8.1.wxml绑定事件

    <input bindinput="handleInput" />
    

    8.2.page定义函数

    Page({
          // 绑定的事件
          handleInput: function(e) {
                console.log(e);
                console.log("值被改变了");
         }
    })
    

    8.3.注意

    1. 绑定事件时不能带参数不能带括号,以下为错误写法

      <input bindinput="handleInput(100)" />
      
    2. 事件传值通过标签自定义属性的方式 和 value

      <input bindinput="handleInput" data-item="100" />
      
    3. 事件触发时获取数据

      handleInput: function(e) {
          // {item:100}
          console.log(e.currentTarget.dataset)
          // 输入框的值
          console.log(e.detail.value);
      }
      

    8.4.示例

    需求:

    1. page.WXML

      <input type="text" bindinput="handleInput"/>
      <view>
            {{num}}  
      </view>
      <button style="color:red;background:#0044ff" bindtap="handletap" data-operation="{{1}}">+</button>
      <button style="color:blue;background:#ff4400" bindtap="handletap" data-operation="{{-1}}">-</button>
      
    2. page.JS

      // pages/demo4/demo4.js
      Page({
      
            /**
             * 页面的初始数据
             */
            data: {
                  num:0
            },
            handleInput(e){
                  this.setData({
                    	num:e.detail.value
                  })
                  console.log(e.detail.value);
            },
            handletap(e) {
                  // console.log(e);
                  // 1 获取自定义属性 operation
                  const operation = e.currentTarget.dataset.operation;
                  this.setData({
                    	num: this.data.num + operation
                  })
            }
      })
      

    注意点:

    • 需要给input标签绑定input事件绑定关键字 bindinput

    • 如何获取输入框的值通过事件<源对象e>来获取e.detail.value

    • 把输入框的值赋值到data当中

      不能直接

      1. this.data.num=e.detail.value

      2. this.num=e.detail.value

      正确的写法

      this.setData({

      ​ num:e.detail.value

      })

    • 需要加入一个点击事件

      1. bindtap

      2. 无法在小程序当中的事件中直接传参

      3. 通过自定义属性的方式来传递参数

      4. 事件源中获取自定义属性

    9.样式WXSS

    WXSS( WeiXin Style Sheets )是⼀套样式语言,⽤于描述 WXML 的组件样式。

    与 CSS 相比,WXSS 扩展的特性有:

    • 响应式长度单位
    • rpx 样式导入

    9.1.尺寸单位

    rpx (responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx ,不管使用iPhone,iPad其屏幕宽度均是750rpx,故不同的设备单位rpx的长度(像素)不同

    如在 iPhone6 上,屏幕宽度为375px ,共有750个物理像素,则 750rpx = 375px = 750物理像素 , 1rpx = 0.5px = 1物理像素

    当我们要做一个页面布局的时候,如果要实现页面的某些元素大小跟随屏幕做自适应变化,就要使用rpx。

    设备rpx换算px (屏幕宽度/750)px换算rpx (750/屏幕宽度)
    iPhone51rpx = 0.42px1px = 2.34rpx
    iPhone61rpx = 0.5px1px = 2rpx
    iPhone6 Plus1rpx = 0.552px1px = 1.81rpx

    建议: 开发微信小程序时设计师可以⽤ iPhone6 作为视觉稿的标准。

    使用步骤:

    1. 确定设计稿宽度 pageWidth
    2. 计算⽐例 750rpx = pageWidth px ,因此 1px=750rpx/pageWidth 。
    3. 在less⽂件中,只要把设计稿中的 px => 750/pageWidth rpx 即可。

    9.1.1.像素定义元素长度

    1. wxml

      <view>RPX</view>
      
    2. wxss

      view{
              width:200px;
              height:200px;
              font-size:40px;
              background-color:aqua;
      }
      
    3. 效果

      使用像素定义元素长度不管使用什么设备,元素长度不变。

      iPhone6屏幕

      iPad屏幕

    9.1.2.使用rpx定义元素长度

    1. wxss

      view{
              width:200rpx;
              height:200rpx;
              font-size:40rpx;
              background-color:aqua;
      }
      
    2. 效果

      使用rpx定义元素长度,元素长度自适应屏幕比例为该长度在750rpx的长度比例

      • iPhone6屏幕

      • ipad屏幕

    9.1.3.总结

    1. 小程序中不需要主动来引入样式文件,页面的会自动引入其样式文件PageName.wxss

    2. 需要把页面中某些元素的单位由px改成 rpx

      • 设计稿 750x

        750 px = 750 rpx

        1 px = 1 rpx

      • 把屏幕宽度 改成 375px

        375 px = 750 rpx

        1 px = 2rpx

        1rpx = 0.5px

    3. 存在一个设计稿宽度100像素(px)在未知页面page像素

      • 设计稿 page存在一个元素宽度100px

      • 拿以上的需求 去实现 不同宽度的页面适配

        page px = 750 rpx

        1px = 750 rpx / page

        100 px = 750 rpx * 100 / page

    4. 利用一个属性calc属性 css 和 wxss 都支持一个属性

      width:calc(750rpx * 100 / 375);,375为屏幕像素

      • 750 和 rpx 中间不要留空格
      • 运算符的两边也不要留空格

      示例:

       view{
         /* width: 200rpx; */
         height: 200rpx;
         font-size: 40rpx;
         background-color: aqua;
        /* 以下代码写法是错误  */
        /*  width:750 rpx * 100 / 375 ;  */
        width:calc(750rpx * 100 / 375);
       }
      

      效果

    9.2.样式导入

    wxss中直接就⽀持,样式导⼊功能。

    也可以和 less中的导⼊混⽤。

    使用@import 语句可以导⼊外联样式表,只⽀持相对路径。

    1. 创建style/common.wxss

      view{
        color: aqua;
        font-size: 100px;
      }
      
    2. 在页面的wxss中引入

      /* 
      1 引入的 代码 是通过 @import 来引入
      2 路径 只能写相对路径
       */
      @import "../../styles/common.wxss";
      

    9.3.选择器

    特别需要注意的是小程序不支持通配符 * 因此以下代码无效!

    *{
        margin:0;
        padding:0;
        box-sizing:border-box;
    }
    

    解决方案:view,text,img{……}

    目前支持的选择器有:

    选择器样例样例描述
    .class.intro选择所有拥有 class=intro 的组件
    #id#firstname选择拥有 id=firstname 的组件
    elementview选择所有 view 组件
    element, elementview, checkbox选择所有⽂档的 view 组件和所有的 checkbox 组 件
    nth-child(n)view:nth-child(n)选择某个索引的标签
    ::afterview::after在 view 组件后边插⼊内容
    ::beforeview::before在 view 组件前边插⼊内容

    9.4.小程序中使用less

    原⽣⼩程序不⽀持 less ,其他基于⼩程序的框架⼤体都⽀持,如 wepy , mpvue , taro 等。 但是仅仅因为⼀个less功能,⽽去引⼊⼀个框架,肯定是不可取的。因此可以⽤以下⽅式来实现

    1. 编辑器是 vscode

    2. 安装插件 easy less

    3. 在vs code的设置中settings.json加入如下

       "less.compile": {
              "outExt":".wxss"
         }
      
    4. 在要编写样式的地⽅,新建 less ⽂件,如 index.less ,然后正常编辑即可。

    10.常见组件

    重点讲解小程序中常⽤的布局组件 view,text,rich–text,button,image,navigator,icon,swiper,radio,checkbox。 等

    10.1.view

    代替原来的 div 标签

    <view hover-class="h-class">
        点击我试试
    </view>
    

    10.2.text

    1. ⽂本标签
    2. 只能嵌套text
    3. ⻓按⽂字可以复制(只有该标签有这个功能) ,增加selectable属性即可
    4. 可以对空格 回⻋ 进⾏编码,增加decode属性即可
    属性名类型默认值说明
    selectableBooleanfalse⽂本是否可选
    decodeBooleanfalse是否解码

    示例:

    1. 不使用decode属性

      <!-- 
        1 长按文字复制 selectable
        2 对文本内容 进行 解码
       -->
      <text selectable>
        text &nbsp; 123 &lt;
      </text>
      
      

      效果

    2. 使用decode属性

      <text selectable decode>
        text &nbsp; 123 &lt;
      </text>
      

    10.3.image

    1. 图片标签,image组件默认宽度320px、⾼度240px
    2. ⽀持懒加载
    3. 建议最好把图片放在网络上,通过src引用
    属性名类型默认值说明
    srcString图⽚资源地址
    modeStringscaleToFill图⽚裁剪、缩放的模式
    lazy-loadBooleanfalse图⽚懒加载

    mode 有效值:

    mode 有 13 种模式,其中 4 种是缩放模式,9.种是裁剪模式。

    模式说明
    缩放scaleToFill不保持纵横比缩放图片,使图片的宽⾼完全拉伸⾄填满image 元素
    缩放aspectFit保持纵横比缩放图片,使图片的长边能完全显⽰出来。
    缩放aspectFill保持纵横比缩放图片,只保证图片的短边能完全显⽰出来。
    缩放widthFix宽度不变,⾼度⾃动变化,保持原图宽⾼⽐不变
    裁剪top不缩放图片,只显示图片的顶部区域
    裁剪bottom不缩放图片,只显示图片的底部区域
    裁剪center不缩放图片,只显示图片的中间区域
    裁剪left不缩放图片,只显示图片的左边区域
    裁剪right不缩放图片,只显示图片的右边区域
    裁剪top left不缩放图片,只显示图片的左上边区域
    裁剪top right不缩放图片,只显示图片的右上边区域
    裁剪bottom left不缩放图片,只显示图片的左下边区域
    裁剪bottom right不缩放图片,只显示图片的右下边区域

    示例:

    1. WXML

      <!-- 
        image 图片标签
        1 src 指定要加载的图片的路径
          图片存在默认的宽度和高度 320 * 240      原图大小是 200 * 100
        2 mode 决定 图片内容 如何 和 图片标签 宽高 做适配
          1 scaleToFill 默认值 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 
          2 aspectFit 保持宽高比 确保图片的长边 显示出来   页面轮播图 常用
          3 aspectFill 保持纵横比缩放图片,只保证图片的 短 边能完全显示出来。  少用
          4 widthFix 以前web的图片的 宽度指定了之后 高度 会自己按比例来调整   常用  
          5 bottom。。 类似以前的backgroud-position 
        3 小程序当中的图片 直接就支持 懒加载  lazy-load
          1 lazy-load 会自己判断 当 图片 出现在 视口  上下 三屏的高度 之内的时候  自己开始加载图片 
       -->
       <image mode="widthFix" lazy-load src="https://tva2.sinaimg.cn/large/007DFXDhgy1g51jlzfb4lj305k02s0sp.jpg" />
      
    2. WXSS

      image{
        box-sizing: border-box;
        border: 1px solid red;
      
        width: 300px;
        height: 200px;
      }
      
    3. 效果

      宽度不变,高度自动变化,保持原图宽高比不变

    10.4.swiper

    微信内置轮播图组件

    轮播图的默认宽度 100% 高度 150px

    属性名类型默认值说明
    indicator-dotsBooleanfalse是否显⽰⾯板指⽰点(小圆点)
    indicator-colorColorrgba(0, 0, 0, .3)指⽰点(小圆点)颜⾊
    indicator-active-colorColor#000000当前选中的指⽰点(小圆点)颜⾊
    autoplayBooleanfalse是否⾃动切换
    intervalNumber5000⾃动切换时间间隔
    circularBooleanfalse是否循环轮播

    10.4.1.swiper

    滑块视图容器。

    10.4.2.swiper-item

    滑块

    滑块 默认宽度和⾼度都是100%

    10.4.3.示例

    1. WXML

      <!-- 
        1 轮播图外层容器 swiper
        2 每一个轮播项 swiper-item
        3 swiper标签 存在默认样式
          1 width 100% 默认横向占满整个屏幕
          2 height 150px (高度无法实现由内容撑开 )
        4 根据原图的长宽等比例给swiper定宽度和高度
          原图的宽度和高度  1125 * 352 px
          swiper 宽度 / swiper  高度 =  原图的宽度  /  原图的高度
          swiper  高度  =  swiper 宽度 *  原图的高度 / 原图的宽度
          height: 100vw * 352 /  1125
      	具体实现看WXSS
        5 autoplay 自动轮播
        6 interval 修改轮播时间
        7 circular 衔接轮播
        8 indicator-dots 显示指示器、分页器、索引器(轮播中的小圆点)
        9 indicator-color 指示器的未选择的颜色 
        10 indicator-active-color 选中的时候的指示器的颜色 
       -->
      <swiper autoplay interval="1000" circular indicator-dots indicator-color="#0094ff" indicator-active-color="#ff0094">
          <swiper-item> 
              <image mode="widthFix" src="//gw.alicdn.com/imgextra/i1/44/O1CN013zKZP11CCByG5bAeF_!!44-0-lubanu.jpg" /> 			</swiper-item>
          <swiper-item> 
              <image mode="widthFix" src="//aecpm.alicdn.com/simba/img/TB1CWf9KpXXXXbuXpXXSutbFXXX.jpg_q50.jpg" /> 
          </swiper-item>
          <swiper-item> 
              <image mode="widthFix" src="//gw.alicdn.com/imgextra/i2/37/O1CN01syHZxs1C8zCFJj97b_!!37-0-lubanu.jpg" /> 		 	</swiper-item>
      </swiper>
      
    2. WXSS

      /* pages/demo10/demo10.wxss */
      swiper {
        width: 100%;
        /* height: calc(100vw * 352 /  1125); */
        height: 31.28vw;/*calc(100vw * 352 /  1125)的结果*/
      }
      image {
        width: 100%;
      }
      
    3. 效果

    10.5.navigator

    导航组件 类似超链接标签

    属性名类型默认值说明
    targetStringself在哪个目标上发⽣跳转,默认当前小程序,可选值 self/miniProgram
    urlString当前小程序内的跳转链接
    opentypeStringnavigate跳转方式

    open-type 有效值:

    说明
    navigate保留当前页面,跳转到应⽤内的某个页面,但是不能跳到tabbar 页面
    redirect关闭当前页面,跳转到应⽤内的某个页面,但是不允许跳转到tabbar 页面。
    switchTab跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
    reLaunch关闭所有页面,打开到应⽤内的某个页面
    navigateBack关闭当前页面,返回上一页⾯或多级页面。可通过 getCurrentPages() 获取当 前的页⾯栈,决定需要返回几层
    exit退出小程序,target=miniProgram时⽣效

    示例

    1. WXML

      <!--
        导航组件navigator
        1.块级元素,默认会换行,可以直接加宽度和高度
        2.url要跳转的页面路径:绝对路径/相对路径
        3.target要跳转到当前的小程序,还是其他的小程序页面
            self(默认值):自己小程序
            或者其他小程序的页面
        4.open-type:跳转的方式
          1 navigate 默认值 	保留当前页面(可返回),跳转到应用内的某个页面,但是不能跳到 tabbar 页面
          2 redirect	关闭当前页面(不可返回),跳转到应用内的某个页面,但是不允许跳转到 tabbar 页面。
          3 switchTab	跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
          4 reLaunch	关闭所有页面,打开到应用内的某个页面
      -->
       <navigator url="/pages/demo10/demo10"> open-type的默认值(navigate)轮播图页面 </navigator>
       <navigator url="/pages/index/index">open-type的默认值(navigate) 不能直接跳转到 tabbar页面 </navigator>
       <navigator open-type="redirect" url="/pages/demo10/demo10"> open-type的redirect 轮播图页面  </navigator>
       <navigator open-type="switchTab" url="/pages/index/index">  switchTab直接跳转到 tabbar页面 </navigator>
       <navigator open-type="reLaunch" url="/pages/index/index">  reLaunch 可以随便跳 </navigator> 
      
      
    2. 效果

    10.6.rich-text

    富文本标签

    可以将字符串解析成 对应标签,类似 vue中 v–html 功能

    10.6.1.nodes属性

    nodes 属性⽀持 字符串 和 标签节点数组

    属性说明类型必填备注
    name标签名string⽀持部分受信任的 HTML 节点
    attrs属性object⽀持部分受信任的属性,遵循 Pascal 命名法
    children⼦节点列表array结构和 nodes ⼀致

    ⽂本节点:type = text

    属性说明类型必填备注
    text⽂本string⽀持entities
    1. nodes 不推荐使⽤ String 类型,性能会有所下降。
    2. rich–text 组件内屏蔽所有节点的事件。
    3. attrs 属性不⽀持 id ,⽀持class 。
    4. name 属性大小写不敏感。 如果使⽤了不受信任的 HTML 节点,该节点及其所有子节点将会被移除。
    5. img 标签仅⽀持⽹络图⽚。

    示例1:

    1. js(拷贝淘宝主页div串)

      // pages/demo12/demo12.js
      Page({
      
        /**
         * 页面的初始数据
         */
        data: {
              html:'<div class="tpl-wrapper" data-tpl-id="m_h_v31icon_1" style="margin-top: -10px;">……</div></div>'
        },
      })
      
    2. wxml

      <!-- 
        rich-text 富文本标签
        1 nodes属性来实现
          1 接收标签字符串 
          2 接收对象数组 
       -->
       <rich-text nodes="{{html}}"></rich-text>
      
    3. 效果

    示例2:

    1. js

      // pages/demo12/demo12.js
      Page({
        data: {
          // 1 标签字符串 最常用的
          // 2 对象数组
          html:[
            {
              // 1 div标签 name属性来指定
              name:"div",
              // 2 标签上有哪些属性
              attrs:{
                // 标签上的属性 class  style
                class:"my_div",
                style:"color:red;"
              },
              // 3 子节点 children 要接收的数据类型和 nodes第二种渲染方式的数据类型一致 
              children:[
                {
                  name:"p",
                  attrs:{},
                  // 放文本
                  children:[
                    {
                      type:"text",
                      text:"hello"
                    }
                  ]
                }
              ]
            }
          ]
        }
      })
      
    2. WXML

      同示例1

    3. 效果

    10.7.button

    <!-- 
      button 标签
      1 外观的属性
        1 size 控制按钮的大小
          1 default 默认大小
          2 mini 小尺寸
        2 type 用来控制按钮的颜色
          1 default 灰色
          2 primary 绿色
          3 warn 红色
        3 plain  按钮是否镂空,背景色透明
        4 loading 文字前显示正在等待图标
     -->
    <button>默认按钮</button>
    <button size="mini">mini 默认按钮</button>
    <button type="primary"> primary按钮</button>
    <button type="warn"> warn按钮</button>
    <button type="warn" plain> plain按钮</button>
    <button type="primary" loading>primary按钮</button>
    
    属性类型默认值必填说明
    sizestringdefault按钮的大小
    typestringdefault按钮的样式类型
    plainbooleanfalse按钮是否镂空,背景⾊透明
    disabledbooleanfalse是否禁⽤
    loadingbooleanfalse名称前是否带 loading 图标
    form-typestring⽤于 组件,点击分别会触发 组件的 submit/reset 事件
    form-typestring微信开放能⼒

    size 的合法值

    说明
    default默认大小
    mini⼩尺⼨

    type 的合法值

    说明
    primary绿⾊
    default⽩⾊
    warn红⾊

    form-type 的合法值

    说明
    submit提交表单
    reset重置表单

    open-type 的合法值

    说明
    contact打开客服会话,如果用户在会话中点击消息卡片后返回⼩程序,可以从 bindcontact 回调中获得具体信息,具体说明
    share触发用户转发,使⽤前建议先阅读使用指引
    getPhoneNumber获取用户手机号,可以从bindgetphonenumber回调中获取到⽤⼾信息, 具体说明
    getUserInfo获取用户信息,可以从bindgetuserinfo回调中获取到用户信息
    launchApp打开APP,可以通过app-parameter属性设定向APP传的参数具体说明
    openSetting打开授权设置页
    feedback打开“意见反馈”页面,⽤⼾可提交反馈内容并上传日志,开发者可以登 录小程序管理后台后进⼊左侧菜单“客服反馈”页面获取到反馈内容

    open-type 的contact的实现流程

    1. 将小程序 的 appid 由测试号改为自己的 appid
    2. 登录微信小程序官网,添加 客服 – 微信
    3. . 为了方便演示,准备了两个账号
      1. 普通用户
      2. 客服-微信
    4. 操作
    <!-- 
    
      button 开发能力
      open-type:
      1 contact 直接打开  客服对话功能  需要在微信小程序的后台配置   只能够通过真机调试来打开 
      2 share 转发当前的小程序 到微信朋友中   不能把小程序 分享到 朋友圈 
      3 getPhoneNumber 获取当前用户的手机号码信息 结合一个事件来使用  不是企业的小程序账号 没有权限来获取用户的手机号码 
        1 绑定一个事件 bindgetphonenumber 
        2 在事件的回调函数中  通过参数来获取信息 
        3 获取到的信息  已经加密过了 
          需要用户自己待见小程序的后台服务器,在后台服务器中进行解析 手机号码,返回到小程序中 就可以看到信息了
      4 getUserInfo 获取当前用户的个人信息
        1 使用方法 类似 获取用户的手机号码
        2 可以直接获取 不存在加密的字段 
      5 launchApp 在小程序当中 直接打开 app
        1 需要现在 app中 通过app的某个链接 打开 小程序
        2 在小程序 中 再通过 这个功能 重新打开 app
        3 找到 京东的app 和 京东的小程序  
      6 openSetting 打开小程序内置的 授权页面
        1 授权页面中 只会出现 用户曾经点击过的 权限 
      7 feedback 打开 小程序内置的 意见反馈页面 
        1 只能够通过真机调试来打开 
      -->
    <button open-type="contact">contact</button>
    <button open-type="share">share</button>
    <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">getPhoneNumber</button>
    <button open-type="getUserInfo" bindgetuserinfo="getUserInfo">getUserInfo</button>
    <button open-type="launchApp">launchApp</button>
    <button open-type="openSetting">openSetting</button>
    <button open-type="feedback">feedback</button>
    

    10.8.icon

    属性类型默认值必填说明
    typestringicon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search, clear
    sizenumber/string23icon的⼤⼩
    colorstringicon的颜⾊,同css的color
    1. WXML

      <view class="group">
        <block wx:for="{{iconSize}}">
          <icon type="success" size="{{item}}"/>
        </block>
      </view>
      <view class="group">
        <block wx:for="{{iconType}}">
          <icon type="{{item}}" size="40"/>
        </block>
      </view>
      <view class="group">
        <block wx:for="{{iconColor}}">
          <icon type="success" size="40" color="{{item}}"/>
        </block>
      </view>
      
      
    2. JS

      Page({
        data: {
          iconSize: [20, 30, 40, 50, 60, 70],
          iconType: [
            'success', 'success_no_circle', 'info', 'warn', 'waiting', 'cancel',
      'download', 'search', 'clear'
         ],
          iconColor: [
            'red', 'orange', 'yellow', 'green', 'rgb(0,255,255)', 'blue', 'purple'
         ],
       }
      })
      
      

    10.9.radio

    可以通过 color属性来修改颜色

    需要搭配radio-group⼀起使用

    1. WXML

      <!-- 
        radio 单选框
        1 radio标签 必须要和 父元素 radio-group来使用
        2 value 选中的单选框的值 
        3 需要给 radio-group 绑定 change事件 
        4 需要在页面中显示 选中的值
       -->
       <radio-group bindchange="handleChange">
         <radio color="red" value="male"></radio>
         <radio color="red" value="female" ></radio>
       </radio-group>
      
       <view>您选中的是:{{gender}}</view>
      
    2. javascript

      // pages/demo15/demo15.js
      Page({
        data: {
          gender: ""
        },
        handleChange(e){
          // 1 获取单选框中的值
          let gender=e.detail.value;
          // 2 把值 赋值给 data中的数据
          this.setData({
            // gender:gender
            gender
          })
        }
      })
      
    3. 效果

    10.10.checkbox

    可以通过 color属性来修改颜色

    需要搭配radio-group⼀起使用

    11.自定义组件

    类似vue或者react中的自定义组件

    小程序允许我们使用自定义组件的方式来构建页面。

    11.1.创建自定义组件

    类似于页面,一个自定义组件由 json、wxml、wxss、js 4个文件组成

    可以在微信开发者工具中的根目录下快速创建组件的文件结构components文件夹-》创建一个和自定义组件名相同的文件夹componentsName,在该文件夹上点击右键<新建Component>并输入componentsName就创建好相应的组件的需要的文件

    在⽂件夹内 components/Tabs ,创建组件 名为Tabs

    11.1.1.声明组件

    ⾸先需要在组件的 json 文件中进行自定义组件声明

    Tabs.json

    {
      "component": true,
      "usingComponents": {}
    }
    

    11.1.2.编辑组件

    同时,还要在组件的 wxml 文件中编写组件模板,在 wxss 文件中加入组件样式 slot 表⽰插槽,类似vue中的slot

    Tabs.wxml

    <!-- 这是自定义组件的内部WXML结构 -->
    <view class="inner">
     {{innerText}}
        <slot></slot>
    </view>
    

    在组件的 wxss ⽂件中编写样式

    注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

    Tabs.wxss

    /* 这里的样式只应用于这个自定义组件 */
    .inner {
      color: red;
    }
    

    Tabs.json

    {
      "component": true,//标注这是一个component
      "usingComponents": {}//如果引用其他组件,在这里添加即可
    }
    

    11.1.3.注册组件

    在组件的 js ⽂件中,需要使⽤ Component() 来注册组件,并提供组件的属性定义、内部数据和自定义方法

    Tab.js

    Component({
      properties: {
        // 这里定义了innerText属性,属性值可以在组件使用时指定
        innerText: {
          // 期望要的数据是 string类型
          type: String,
          value: 'default value',
        }
      },
       data: {
         // 这里是一些组件内部数据
         someData: {}
      },
       methods: {
         // 这里是一个自定义方法
         customMethod: function(){}
      }
     })
    

    11.2. 声明引入自定义组件

    首先要在页面的 json 文件中进行引用声明。还要提供对应的组件名和组件路径。

    index.json

    {   
       "usingComponents": {
         "Tabs":"../../components/Tabs/Tabs"
      }
     }
    

    11.3. 页面中使用自定义组件

    index.wxml

    <Tabs></Tabs>
    

    效果:

    11.4.其他属性

    11.5. 定义段与示例方法

    Component 构造器可用于定义组件,调⽤ Component 构造器时可以指定组件的属性、数据、方法等。

    定义段类型是否必填描述
    propertiesObject Map组件的对外属性,是属性名到属性设置的映射表,参⻅下⽂
    dataObject组件的内部数据,和 properties ⼀同⽤于组件的模板渲 染
    observersObject组件数据字段监听器,⽤于监听 properties 和 data 的变 化,参见数据监听器
    methodsObject组件的方法,包括事件响应函数和任意的⾃定义⽅法,关于 事件响应函数的使用,参见组件事件
    createdFunction组件⽣命周期函数,在组件实例刚刚被创建时执行,注意此 时不能调⽤ setData ,参见组件生命周期
    attachedFunction组件⽣命周期函数,在组件实例进⼊页面节点树时执行,参见组件生命周期
    readyFunction组件⽣命周期函数,在组件布局完成后执行,参见组件⽣命周期
    movedFunction组件生命周期函数,在组件实例被移动到节点树另⼀个位置 时执行,参见组件生命周期
    detachedFunction组件生命周期函数,在组件实例被从页面节点树移除时执 行,参见组件生命周期

    11.6.组件-自定义组件传参

    1. ⽗组件通过属性的⽅式给⼦组件传递参数
    2. ⼦组件通过事件的⽅式向⽗组件传递参数

    11.6.1. 过程

    1. ⽗组件 把数据 {{tabs}} 传递到 ⼦组件的 tabItems 属性中
    2. ⽗组件 监听 onMyTab 事件
    3. ⼦组件 触发 bindmytap 中的 mytap 事件
      1. ⾃定义组件触发事件时,需要使⽤ triggerEvent ⽅法,指定 事件名 、 detail 对象
    4. ⽗ -> ⼦ 动态传值 this.selectComponent("#tabs");

    父组件代码

    子组件代码

    11.7.示例

    1. 要求

    2. 自定义组件components(子组件)

      • 组件Tab的tab.wxml

        
        <view class="tabs">
          <view class="tabs_title">
            <!-- <view class="title_item active">首页</view>
            <view class="title_item">原创</view>
            <view class="title_item">分类</view>
            <view class="title_item">关于</view> -->
        
            <view 
            wx:for="{{tabs}}"
            wx:key="id"
            class="title_item {{item.isActive?'active':''}}"
            bindtap="hanldeItemTap"
            data-index="{{index}}"
            >
            {{item.name}}
          </view>
          </view>
          <view class="tabs_content">
            <!-- 
              slot 标签 其实就是一个占位符 插槽
              等到 父组件调用 子组件的时候 再传递 标签过来 最终 这些被传递的标签
              就会替换 slot 插槽的位置 
             -->
            <slot></slot>
          </view>
        </view>
        
      • 组件Tab的tab.js

        // components/Tabs.js
        Component({
          /**
           * 里面存放的是 要从父组件中接收的数据
           */
          properties: {
            // 要接收的数据的名称
            // aaa:{
            //   // type  要接收的数据的类型 
            //   type:String,
            //   // value  默认值
            //   value:""
            // }
            tabs:{
              type:Array,
              value:[]
            }
          },
        
          /**
           * 组件的初始数据
           */
          data: {
            // tabs
          },
          /* 
          1 页面.js 文件中 存放事件回调函数的时候 存放在data同层级下!!!
          2 组件.js 文件中 存放事件回调函数的时候 必须要存在在 methods中!!!
           */
         
        
          methods: {
            hanldeItemTap(e){
              /* 
              1 绑定点击事件  需要在methods中绑定
              2 获取被点击的索引 
              3 获取原数组 
              4 对数组循环
                1 给每一个循环性 选中属性 改为 false
                2 给 当前的索引的 项 添加激活选中效果就可以了!!!
        
               
               5 点击事件触发的时候 
                  触发父组件中的自定义事件 同时传递数据给  父组件  
                  this.triggerEvent("父组件自定义事件的名称",要传递的参数)
               */
        
              //  2 获取索引
              const {index}=e.currentTarget.dataset;
              // 5 触发父组件中的自定义事件 同时传递数据给  
              this.triggerEvent("itemChange",{index});
              // 3 获取data中的数组
              // 解构  对 复杂类型进行结构的时候 复制了一份 变量的引用而已
              // 最严谨的做法 重新拷贝一份 数组,再对这个数组的备份进行处理,
              // let tabs=JSON.parse(JSON.stringify(this.data.tabs));
              // 不要直接修改 this.data.数据 
              // let {tabs}=this.data;
              // let tabs=this.data;
              // 4 循环数组
              // [].forEach 遍历数组 遍历数组的时候 修改了 v ,也会导致源数组被修改
              // tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
        
              // this.setData({
                // tabs
              // })
            }
          }
        })
        
      • 组件Tab的Tab.wxss

        .tabs_title{
          display: flex;
          padding: 10rpx 0;
        }
        .title_item{
          flex: 1;
          display: flex;
          justify-content: center;
          align-items: center;
        }
        .active{
          color:red;
          border-bottom: 5rpx solid currentColor;
        }
        
      • 组件Tab的Tab.json

        {
          "component": true,
          "usingComponents": {}
        }
        
    3. 在页面(父组件)中使用组件Tab(子组件)

      • 引入组件Page.json

        {
          "usingComponents": {
            "Tabs":"../../components/Tabs/Tabs"
          }
        }
        
      • Page.js

        // pages/demo17/demo18.js
        Page({
        
          /**
           * 页面的初始数据
           */
          data: {
        
            tabs: [
              {
                id: 0,
                name: "首页",
                isActive: true
              },
              {
                id: 1,
                name: "原创",
                isActive: false
              }
              ,
              {
                id: 2,
                name: "分类",
                isActive: false
              }
              ,
              {
                id: 3,
                name: "关于",
                isActive: false
              }
            ]
        
          },
        
          // 自定义事件 用来接收子组件传递的数据的
          handleItemChange(e) {
            // 接收传递过来的参数
            const { index } = e.detail;
            let { tabs } = this.data;
            tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false);
            this.setData({
              tabs
            })
          }
        })
        
      • Page.wxml

        <!-- 
          1 父组件(页面) 向子组件 传递数据 通过 标签属性的方式来传递
            1 在子组件上进行接收
            2 把这个数据当成是data中的数据直接用即可
          2 子向父传递数据 通过事件的方式传递
            1 在子组件的标签上加入一个 自定义事件
          
         -->
        <Tabs tabs="{{tabs}}" binditemChange="handleItemChange" >
        <block wx:if="{{tabs[0].isActive}}">0 </block>
        <block wx:elif="{{tabs[1].isActive}}">1 </block>
        <block wx:elif="{{tabs[2].isActive}}">2 </block>
        <block wx:else>3</block>
        </Tabs>
        

    11.7. 小结

    1. 标签名 是 中划线的⽅式
    2. 属性的⽅式 也是要中划线的⽅式
    3. 其他情况可以使⽤驼峰命名
      1. 组件的⽂件名如 myHeader.js 的等
      2. 组件内的要接收的属性名 如 innerText
    4. 更多参考文档

    12.小程序生命周期

    分为应用生命周期页面生命周期

    关于小程序前后台的定义和小程序的运行机制,请参考运行机制章节。

    12.1. 应用生命周期

    应用指小程序的入口文件,也就是app.js

    属性类型必填说明
    onLaunchfunction监听小程序初始化,应用第一次启动就会触发的事件(例如在应用第一次启动的时候,获取用户的个人信息)。
    onShowfunction监听小程序启动或切前台,应用被用户看到时候触发(例如应用切换启动时,页面效果重置)。
    onHidefunction监听小程序切后台,应用被隐藏的时候触发(暂停或者清除定时器触发)。
    onErrorfunction错误监听函数,当应用代码发生错误的时候会触发,会有一个err的错误信息参数(在应用发生代码错误触发,可以通过异步请求将错误信息发送给后台)。
    onPageNotFoundfunction页面不存在监听函数,页面找不到的时候报错,相当于onError中的一种()。
    //app.js
    App({
      //  1 应用第一次启动的就会触发的事件  
      onLaunch() {
        //  在应用第一次启动的时候 获取用户的个人信息 
        // console.log("onLaunch");
        // aabbcc
    
        // js的方式来跳转 不能触发 onPageNotFound
        // wx.navigateTo({
        //   url: '/11/22/33'
        // });
          
      },
    
      // 2 应用 被用户看到 
      onShow(){
        // 对应用的数据或者页面效果 重置 
        // console.log("onShow");
      },
      // 3 应用 被隐藏了 
      onHide(){
        // 暂停或者清除定时器 
        // console.log("Hide");
      },
      // 4 应用的代码发生了报错的时候 就会触发
      onError(err){
        // 在应用发生代码报错的时候,收集用户的错误信息,通过异步请求 将错误的信息发送后台去
        // console.log("onError");
        // console.log(err);
      },
      // 5 页面找不到就会触发 
      //  应用第一次启动的时候,如果找不到第一个入口页面 才会触发
      onPageNotFound(){
        // 如果页面不存在了 通过js的方式来重新跳转页面 重新跳到第二个首页
        // 不能跳到tabbar页面导航组件类似  
        wx.navigateTo({
          url: '/pages/demo09/demo09' 
        });  
          
        // console.log("onPageNotFound");
      }
    })
    

    12.2.页面生命周期

    属性类型说明
    dataObject页面的初始数据
    onLoadfunction页面加载完毕触发,一般在这个函数发送一些异步请求来初始化页面数据
    onShowfunction页面显示时触发
    onReadyfunction页面初次渲染完毕后触发
    onHidefunction页面隐藏的时候触发,应用隐藏以及跳转到其他页面时触发
    onUnloadfunction页面卸载的时候触发,即关闭当前页面,跳转其他页面。(可参考10.5navigator中opne-type为关闭的时候)
    onPullDownRefreshfunction监听用户下拉动作触发,在app.js的window中设置。可以进行页面数据属性
    onReachBottomfunction页面上拉触底事件的处理函数,当页面数据足够多,需要往上拉到底部的时候触发。可以用来加载下一页数据。
    onShareAppMessagefunction用户点击右上角转发时触发
    onPageScrollfunction页面滚动触发事件的处理函数
    onResizefunction页面尺寸改变时触发,详见响应显示区域变化,横屏,竖屏的时候发生。如果要可以发生横屏竖屏在page.json中添加"pageOrientation": “auto”,或者在app.json中设置,所有的页面都可以。
    onTabItemTapfunction当前是tab页时,点击tab时触发

    Page.js

    // pages/demo18/demo18.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
    
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
        console.log("onLoad");
        // onLoad发送异步请求来初始化页面数据 
      },
      /**
       * 生命周期函数--监听页面显示
       */
      onShow: function () {
        console.log("onShow");
      },
      /**
        * 生命周期函数--监听页面初次渲染完成
        */
      onReady: function () {
        console.log("onReady");
      },
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide: function () {
        console.log("onHide");
      },
    
      /**
       * 生命周期函数--监听页面卸载 也是可以通过点击超链接来演示 
       * 
       */
      onUnload: function () {
        console.log("onUnload");
      },
    
      /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
      onPullDownRefresh: function () {
        console.log("onPullDownRefresh");
        // 页面的数据 或者效果 重新 刷新
      },
    
      /**
       * 页面上拉触底事件的处理函数
       * 需要让页面 出现上下滚动才行 
       */
      onReachBottom: function () {
        console.log("onReachBottom");
        // 上拉加载下一页数据 
      },
    
      /**
       * 用户点击右上角分享
       */
      onShareAppMessage: function () {
        console.log("onShareAppMessage");
      },
      /**
       * 页面滚动 就可以触发 
       */
      onPageScroll(){
        console.log("onPageScroll");
      },
      /**
       * 页面的尺寸发生改变的时候 触发
       * 小程序 发生了 横屏竖屏 切换的时候触发 
       */
      onResize(){
        console.log("onResize");
      },
      /**
       * 1 必须要求当前页面也是tabbar页面
       * 2 点击的自己的tab item的时候才触发
       */
      onTabItemTap(){
        console.log("onTabItemTap");
      }
    })
    

    12.3. 页面生命周期图解

    13.补充说明

    13.1微信小程序版本发布

    13.1.1.设置小程序的APPID

    13.1.2.在微信公众平台设置小程序访问的后台地址(http协议)

    • 小程序访问的后台程序地址

    • 在微信公众平台设置访问地址

    13.1.3.关闭不进行Https协议以及证书的校验

    13.1.4.上传

    13.1.5.提交审批

    13.2.版本测试说明

    当版本发布后现场进行手机端测试时,一定要将手机端的小程序删除后重新搜索添加到手机上,再进行测试

    13.3.小程序开发常见错误

    13.3.1.微信小程序开发出现:Unexpected token o in JSON at position 1;at api request success callback function异常

    该错误一般出现在处理返回JSON数据时

    RN解析数据时报错,原因是返回的数据已经是object格式

    解决方案:

    1. JSON.stringify(对象);把对象转String
    2. 2.JSON.parse();把string转对象

    示例:

     App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
        var result = JSON.stringify(response);
        result = JSON.parse(result);
        console.log(result);
        if(result.CODE=="00"){
            that.setData({
                tab: result.MODLIST
            })
        }        
    })
    

    13.3.2.微信小程序开发出现:Cannot read property ‘setData’ of undefined;at api request success callback

    作用域问题——回调函数中的作用域已经脱离了调用函数了,因此需要在回调函数外边把this赋给一个新的变量才可以了。
    此处将this赋值给变量self

    loadModInfo :function(){
        var self = this
        var param ={
            "MOD_ID":"WAK",
            "FYDM":App.globalData.FYDM
        }
        console.log(param);
        App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
            var result = JSON.stringify(response);
            result = JSON.parse(result);
            console.log(result);
            if(result.CODE=="00"){
                that.setData({
                    tab: result.MODLIST
                })
            }        
        })
    }
    

    13.4.小程序访问后台网络数据建议格式

    13.4.1.涉及文件

    13.4.1.在app.js定义后台请求地址IPURL

    var net_js = require('./net/net')
    App({
        globalData: {
            userInfo: null,
            CID: "0000",
            // 示例:IPURL:'http://ip:port/xszfweb/'
            IPURL: 'http://192.168.1.169:8088/xszfweb/',
            FYDM: "320000",
            //订阅消息模板
            SubscribeMsgTemplate:['F9eVJkbsidSFWadWAdXsj7Cjlzxg_CbtCc5e3CyOK1g']
        },
        request: {
            checkUserYhdm:net_js.checkUserYhdm,
            getUserOpenid:net_js.getUserOpenid,
            bindUser:net_js.bindUser,
            loadModInfo:net_js.loadModInfo,
        }
    })
    

    13.4.2.定义net.js的工具方法getUserOpenid

    module.exports创建接口,便于引用

    var Base64 = require('../utils/base64Decode');
    /**
     * 1.根据code,appid,fydm获取用户openid
     * @param {*} ip :请求地址
     * @param {*} param :携带参数;1.code.appid,3.fydm
     * @param {*} callback :回调函数
     */
    function getUserOpenid(ip,param,callback){
        var data={"method":"getOpenid","body":param};
        postRequest(ip+"web/wakTransmit", data, "application/json", function (res) {
            return typeof callback == "function" && callback(res)
        })
    }
    /**
     * 发送post请求
     * @param {*} ip 
     * @param {*} param 
     * @param {*} content_type 
     * @param {*} callback 
     */
    function postRequest(ip, param, content_type, callback) {
        wx.request({
            url: ip,
            header: {
                'Content-Type': content_type
            },
            method: "POST",
            data: param,
            async:false,
            success: function (res) {
                return typeof callback == "function" && callback(res.data)
            },
            fail: function (res) {
                var msg = res.errMsg
                var err = {
                    code: '1',
                    message: msg
                }
                return typeof callback == "function" && callback(err)
            }
        })
    }
    
    module.exports = {
        getUserOpenid: getUserOpenid,
    }
    

    13.4.3.在登录页面的login.js使用该方法

    引入getApp(),通过App.request.checkUserYhdm调用

    var Base64 = require('../../utils/base64Decode.js');
    const App = getApp();
    Page({
        data: {
            xm: '',
            sfzh: '',
        },
        /**
         * 根据用户的身份信息以及openid开始验证用户是否已绑定用户
         */
        verifyUser: function(openid){
            const xm = this.data.xm;
            const sfzh = this.data.sfzh;
            var param = {
                "yhxm":xm,
                "sfzhm":sfzh,
                "openid":openid
            }
            App.request.checkUserYhdm(App.globalData.IPURL,param,function(response){
                var result = JSON.stringify(response);
                result = JSON.parse(result);
                if(result.code=='00'){
                    var userInfo = {
                        "xm": xm,
                        "sfzh": sfzh,
                        "yhdm": result.userinfo.yhdm,
                        "openid": openid,
                        "dwdm": result.userinfo.dwdm,
                    }
                    wx.setStorageSync("userInfos", userInfo)
                    wx.reLaunch({
                        url: "/pages/index/index",
                    })
                }
            })
        },
    })
    

    13.5.setData函数设置复杂数据

    13.5.1.设置类似map类型数据

    Page({
        data: {
            userInfo:{},
        },
        
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {
            //页面加载是接受数据,设置参数
            this.setData({
                userInfo: {
                    xm: options.xm,
                    sfzh: options.sfzh,
                    openid:options.opendid
                },
            })
        },
    })
    

    13.5.2.设置类似list数据

    直接将json中返回的list赋值即可

    Page({
        /**
         * 页面的初始数据
         */
        data: {
            tab:[]
            //测试数据
            //tab: [
                 //     {"name": "我的案款","url": "web/login","info": "浏览本人办理的案件款项","code": "1"}, 				
                 //   	{"name":"我的审批","url": "web/login", "info": "本人的待审批信息","code": "2"}
         		 //]
        },
         /**
         * 初始化时获取页面的功能模块信息
         */
        loadModInfo :function(){
            var self = this
            var param ={
                "mod_id":"WAK",
                "fydm":App.globalData.FYDM
            }
            console.log(param);
            App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
                var result = JSON.stringify(response);
                result = JSON.parse(result);
                if(result.code=="00"){
                    //直接将json中返回的list赋值即可
                    self.setData({
                        tab: result.modlist
                    })
                }        
            })
        }
    }
    

    13.6.消息订阅接口

    13.7.获取openid

    获取openid首先要获取通过wx.login()获取code,然后code获取appid

    13.7.1.小程序端通过wx.login获取code

    获取openid首先要获取通过wx.login()获取code

    checkYhdm: function(){
            var self = this
            //1.通过微信获取code
            wx.login({
                success:function(res){
                    //2.根据获取的code,appid,fydm调用后台服务器去获取openid
                    var code = res.code;
                    var data={
                        "code": code,
                        "appid": wx.getAccountInfoSync().miniProgram.appId,
                        "fydm":App.globalData.FYDM
                    };
                    App.request.getUserOpenid(App.globalData.IPURL,data,function(response){
                        var result = JSON.stringify(response);
                        result = JSON.parse(result);
                        if(result.code=="00"){
                            //3.当获取openid成功后进行绑定操作
                            self.verifyUser(result.openid)
                        }else{
                            wx.showModal({
                                title: '温馨提示',
                                content: "openid获取失败,请联系管理员",
                                showCancel: false
                            })
                        }
                    })
                }
            })
        },
    

    13.7.2.将code和appid传递给后台服务器请求微信接口获取openid

    public WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException {
            WxMaConfig config = this.getWxMaConfig();
            Map<String, String> params = new HashMap(8);
            params.put("appid", config.getAppid());
            params.put("secret", config.getSecret());
            params.put("js_code", jsCode);
            params.put("grant_type", "authorization_code");
            String result = this.get("https://api.weixin.qq.com/sns/jscode2session", Joiner.on("&").withKeyValueSeparator("=").join(params));
            return WxMaJscode2SessionResult.fromJson(result);
        }
    

    13.8.小程序之间的跳转

    13.8.1.原小程序通过准备跳转到其他小程序

    通过wx.navigateToMiniProgram完成跳转

    • appId是目标小程序的APPID
    • path是目标小程序的页面,如果需要携带参数,在path后加?param1=xxxx&param2=yyyy
    //跳转博思支付小程序完成支付
    payBosiRequest: function(res){
        if (res.data.success == true) {
            var extraInfo = JSON.parse(res.data.extraInfo);
            wx.navigateToMiniProgram({
                appId: extraInfo.miniprogram.appid,
                path: extraInfo.miniprogram.pagepath,
                success(res) {
                    console.log("跳转博思支付成功");
                }
            })
        }
    }
    

    13.8.2.目标小程序的接收参数并加载页面

     /**
       * 生命周期函数--监听页面显示
       */
      onShow: function () {
        this.setData({
          zfje: 0.00
        })
        var obj = wx.getLaunchOptionsSync()
        var userInfo = obj.referrerInfo.extraData
        var appId = obj.referrerInfo.appId
        if (appId != undefined && appId.length > 0) {
          if (userInfo != undefined) {
            var xm = userInfo.xm
            var sfzh = userInfo.sfzh
            if (xm != undefined && xm.length > 0 && sfzh != undefined && sfzh.length > 0) {
              wx.setStorageSync("userInfos", userInfo)
              this.getWjYjDzfRequest()
            } else {
              wx.navigateTo({
                url: '/pages/login/login',
              })
            }
          } else {
            wx.navigateTo({
              url: '/pages/login/login',
            })
          }
        } else {
          this.getWjYjDzfRequest()
        }
      },
    
    

    13.9.微信小程序嵌套H5页面

    13.9.1.定义小程序的H5容器container.js

    对于调用H5页面使用微信小程序的H5容器,对传递来的参数先使用base64编码,避免链接中的问号等情况造成错误

    const App = getApp();
    var Base64 = require('../../utils/base64Decode.js');
    Page({
        /**
         * 页面的初始数据
         */
        data: {
            urlstr:""
        },
    
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {
            //页面加载时
            //1.获取服务后台地址+options携带的h5页面路径+缓存的必要参数拼接页面地址
            var userInfos = wx.getStorageSync("userInfos");
            this.setData({
                urlstr: App.globalData.IPURL + Base64.decode(options.pageUrl)+"?yhdm="+userInfos.yhdm
            })
        },
    })
    

    13.9.2.定义小程序的H5容器container.wxml

    <web-view src="{{urlstr}}"></web-view>
    

    container.wxss和container.json不需要任何配置,省略即可

    13.9.3.其他页面跳转到该页面

    通过navigator标签携带参数跳转到container页面,携带参数通过onLoad的options接受处理

    <!-- 4.根据传入的数据动态显示宫格(一行两列图标)信息 -->
    <view class="weui-grids">
        <view class="weui-grid" wx:for="{{tab}}" wx:key="gndm">
            <navigator url="/pages/container/container?pageUrl={{item.url}}&openid={{openid}}&yhdm={{yhdm}}">
                <view class='weui_grid_bg'>
                    <!-- 4.1.显示功能模块log -->
                    <view class="weui_grid_icon">
                        <image src="{{item.icon}}" mode="scaleToFill" />
                    </view>
                    <!-- 4.2.显示功能模块名称 -->
                    <text class="weui_grid_label">{{item.name}}</text>
                    <!-- 4.3.显示功能模块说明 -->
                    <text class="weui_grid_info">{{item.info}}</text>
                </view>
            </navigator>
        </view>
    </view>
    

    13.10.H5.页面的事件携带参数跳转到微信小程序

    13.10.1.H5.页面引入相关的JS文件

    <script type="text/javascript" th:src="@{/static/js/jweixin-1.3.2.js}"></script>
    

    13.10.2.H5.页面JS函数跳转到微信小程序页面

    function downloadSp(id) {
        if("miniProgram" == pageType){
            var wsAhdm = $.trim(id.split("_", -1)[0]);
            var xh = $.trim(id.split("_", -1)[1]);
            if (wsAhdm == "" || xh == "") {
                layerMsg("文书尚未生成");
                return;
            }
            wx.miniProgram.navigateTo({url: "/pages/downloadFile/downloadFile?ahdm=" +wsAhdm + "&jzxh=" + xh});
        }else {
          //略
        }
    }
    

    13.10.3.微信小程序准备downloadFile页面

    1. downloadFile.js

      // pages/downloadFile/downloadFile.js
      const App = getApp();
      Page({
          /**     
           * 页面的初始数据     
           */
          data: {},
          /**     
           * 生命周期函数--监听页面加载     
           */
          onLoad: function (options) {
              var ahdm = options.ahdm;
              var jzxh = options.jzxh;
              console.log("ahdm:" + ahdm);
              wx.downloadFile({
                  url: App.globalData.IPURL + 'wak/downloadSp?ahdm=' + ahdm + '&jzxh=' + jzxh,
                  success: function (res) {
                      wx.saveFile({
                          tempFilePath: res.tempFilePath,
                          success: function (res2) {
                              wx.openDocument({
                                  filePath: res2.savedFilePath,
                                  success: function (res) {}
                              })
                          }
                      })
                  }
              })
              wx.navigateBack();
          }
      })
      
    2. downloadFile.wxml

      <view></view>
      

    13.11.定义全局变量

    一般设置全局变量做到修改时全部修改,例如后台服务器地址

    13.11.1.在微信小程序的app.js定义全局变量

    globalData: {
        // 示例:IPURL:'http://ip:port/xszfweb/'
        IPURL: 'http://192.168.1.169:8088/xszfweb/',
        //订阅消息模板
        SubscribeMsgTemplate:['F9eVJkbsidSFWadWAdXsj7Cjlzxg_CbtCc5e3CyOK1g']
    },
    

    13.11.2.在需要使用的页面的js中使用全局变量

    1. 首先引用getApp()赋值给App
    2. 然后通过变量App使用获取全局变量App.globalData.IPURL
    const App = getApp();
    Page({
        /**
         * 初始化时获取页面的功能模块信息
         */
        loadModInfo :function(){
            var self = this
            var param ={
                "mod_id":"WAK",
                "fydm":App.globalData.FYDM
            }
            App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
                var result = JSON.stringify(response);
                result = JSON.parse(result);
                if(result.code=="00"){
                    self.setData({
                        tab: result.modlist
                    })
                }        
            })
        }
    })
    

    13.12.获取小程序APPID

    wx.getAccountInfoSync().miniProgram.appId
    

    13.13.注意请求异步性问题

    function sendCheckMsg(param){
        var result="error";
        App.request.noticeCheckRes(App.globalData.IPURL, param, function (response) {
            var msg = JSON.stringify(response);
            msg = JSON.parse(msg);
            console.log(msg);
            if(msg.code=="00"){
                result = "succ";
            }   
        })
        return result;
    }
    

    当别的方法调用该函数,当noticeCheckRes调用成功时,因为其函数的请求的异步性,return函数已经执行,故返回的还是error

    13.14.文件下载

    13.14.1.downloadFile.wxml

    <view>
    	<view class="btn" bindtap="load">下载</view>
        <loading hidden="{{  loadingHidden }}">加载中...</loading>
    </view>
    

    13.14.2.downloadFile.js

    Page({
        /**
         * 页面的初始数据
         */
        data: {
            loadingHidden: "true"
        },
    
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {},
        load: function () {
            this.setData({
                loadingHidden: false
            })
            let self = this;
            wx.downloadFile({
                url: 'http://192.168.1.160:8088/xszfweb/wak/downloadSp?ahdm=115020201002000050&jzxh=0052&ver=1600409402056',
                success: function (res) {
                    var filePath = res.tempFilePath;
                    console.log(res)
                    //页面显示加载动画
                    wx.openDocument({
                        filePath: filePath,
                        success: function (res) {
                            self.setData({
                                loadingHidden: true
                            })
                            console.log('打开文档成功')
                        }
                    })
                }
            })
        }
    })
    

    13.15.在图标加上数量提示

    在图标上醒目的数字提示,告知用户有待办事项

    13.15.1.index.wxml

    <view class="weui-grid" wx:for="{{tab}}" wx:key="gndm">
        <!-- 4.1.当页面为H5页面时(对应T_MODULE_ONLINE的type字段为01),跳转到container(H5页面容器),打开H5页面 -->
        <view wx:if="{{item.type=='01'}}">
            <navigator url="/pages/container/container?pageUrl={{item.url}}">
                <view class='weui_grid_bg'>
                    <!-- 4.1.1.显示功能模块log -->
                    <view class="weui_grid_icon">
                        <image src="{{item.icon}}" mode="scaleToFill" />
                        <!-- 4.1.2.针对需要在图片右上角显示提示数字的设置,例如未审批的流程数-->
                        <text class="span"
                              wx:if="{{(item.mark=='true')&&(item.digital>0)&&(item.digital<=99)}}">{{item.digital}}</text>
                        <text class="span" wx:elif="{{(item.mark=='true')&&(item.digital>99)}}">99+</text>
                    </view>
                    <!-- 4.1.3.显示功能模块名称 -->
                    <text class="weui_grid_label">{{item.name}}</text>
                    <!-- 4.1.4.显示功能模块说明 -->
                    <text class="weui_grid_info">{{item.info}}</text>
                </view>
            </navigator>
        </view>
    </view>
    

    13.15.2.index.js

    保证item中包含digital参数,大于0即可

    13.15.3.index.wxss

    .weui-grid .span {
        position: absolute;
        /* 根据需要调整top和right */
        top: 0rpx;
        right: 85rpx;
        display: inline-block;
        padding: 4rpx 10rpx;
        min-width: 16rpx;
        border-radius: 36rpx;
        background-color: #fa5151;
        /* background-color: var(--weui-RED); */
        color: #fff;
        line-height: 1.2;
        text-align: center;
        font-size: 24rpx;
    }
    

    13.16.在H5页面增加排序图片

    13.16.1.示例

    31085229571

    13.16.2.实现

    1. 引入对应的layer的js文件和css文件

      <script th:src="@{/static/ext/layui/layui.js}"></script>
      <script th:src="@{/static/ext/layer_mobile/layer.js}"></script>
      <link rel="stylesheet" th:href="@{/static/ext/layui/css/layui.css}" media="all">
      <style type="text/css">
          html, body {
              width: 100%;
              height: 100%;
          }
      
          .arrUp {
              width: 0;
              height: 0;
              border: 8px solid transparent;
              border-bottom-color: #ccc;
              cursor: pointer;
          }
      
          .arrDown {
              width: 0;
              height: 0;
              border: 8px solid transparent;
              border-top-color: #ccc;
              margin-top: 5px;
              cursor: pointer;
          }
      </style>
      
    2. H5

      <div class="arr" style="height: 0.70rem;width: 100%">
          <table style="width: 100%">
              <tr>
                  <td style="width: 25%;text-align: center">已缴金额</td>
                  <td style="width: 25%;text-align: left">
                      <div class="arrUp" name="yjje" id="TKZE_ASC"></div>
                      <div class="arrDown" name="yjje" id="TKZE_DESC"></div>
                  </td>
                  <td style="width: 25%;text-align: center">可退金额</td>
                  <td style="width: 25%;text-align: left">
                      <div class="arrUp" name="tkje" id="WTKZE_ASC"></div>
                      <div class="arrDown" name="tkje" id="WTKZE_DESC"></div>
                  </td>
              </tr>
          </table>
      </div>
      <input type="hidden" value="" id="sortType"/>
      <input type="hidden" value="ASC" id="sortDirection"/>
      
    3. JS函数

      $(document).ready(function () {
          $("div[name='yjje']").on("click", function () {
              var sortDirection = $('#sortDirection').val();
              if ("ASC" === sortDirection) {
                  $(".arrUp").css("border-bottom-color", '')
                  $(".arrDown").css("border-top-color", '')
                  $("#TKZE_DESC").css("border-top-color", "#3176ee");
                  sort("TKZE_DESC");
              } else {
                  $(".arrUp").css("border-bottom-color", '')
                  $(".arrDown").css("border-top-color", "")
                  $("#TKZE_ASC").css("border-bottom-color", "#3176ee");
                  sort("TKZE_ASC");
              }
          })
          $("div[name='tkje']").on("click", function () {
              var sortDirection = $('#sortDirection').val();
              if ("ASC" == sortDirection) {
                  $(".arrUp").css("border-bottom-color", '')
                  $(".arrDown").css("border-top-color", '')
                  $("#WTKZE_DESC").css("border-top-color", "#3176ee");
                  sort("WTKZE_DESC");
              } else {
                  $(".arrUp").css("border-bottom-color", '')
                  $(".arrDown").css("border-top-color", "")
                  $("#WTKZE_ASC").css("border-bottom-color", "#3176ee");
                  sort("WTKZE_ASC");
              }
          })
          searchData('init');
      });
      function sort(id) {
          var arr = id.split('_');
          $('#sortType').val(arr[0]);
          $('#sortDirection').val(arr[1]);
          search('refreshAll');
      }
      function search(optype) {
          var rowsNum = $("#rowsNum").val();
          var currentPage = Number($("#currentPage").text());
          var totalPage = $("#totalPage").text();
          if ("pageDown" == optype && currentPage < totalPage) {
              currentPage += 1;
          } else if ("pageUp" == optype && currentPage != 1) {
              currentPage -= 1;
          } else if ("refreshAll"==optype){
              //针对输入新的查询内容,全部数据刷新的操作
              currentPage = 1;
          } else if ("refresh" == optype) {
              //针对上拉只刷新刷新本页数据
          }
          var param = {
              "yhdm": $("#yhdm").val(),
              "ahorje": $("#ahorje").val(),
              "pagenum": rowsNum,
              "curpage": (currentPage - 1),
              "sortType": $('#sortType').val(),
              "sortDirection": $('#sortDirection').val()
          };
          sendMsg(param);
      }
      

      sortType,sortDirection存储参数

    13.17.在首页生成九宫格

    一般首页中需要展示为九宫格,或者六宫格展示所有的功能信息。点击功能一般为跳转到H5页面,打开小程序的另一个页面,或者调用小程序的函数等。故需要对不同情况进行不同的配置。

    31104419763

    13.17.1.在数据库中配置不同的功能模块

    31102728870

    建表SQL:

    CREATE TABLE T_MODULE_ONLINE (
    	LSH varchar(10) NOT NULL,
    	GNDM varchar(10) NOT NULL,
    	GNMC varchar(20) NOT NULL,
    	GN_URL varchar(250) NULL,
    	IMG_URL varchar(250) NULL,
    	PXH int NULL,
    	STATE varchar(1) NULL,
    	REMAKE varchar(250) NULL,
    	MOD_ID varchar(20) NULL,
    	FYDM varchar(6) NOT NULL,
    	PAGE_TYPE varchar(2) NULL,
    	CONSTRAINT T_MODULE_ONLINE_PK PRIMARY KEY (LSH)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    INSERT T_MODULE_ONLINE (LSH,GNDM,GNMC,GN_URL,IMG_URL,PXH,STATE,REMAKE,MOD_ID,FYDM,PAGE_TYPE) VALUES('1','WAK01','我的案款','wak/wdakView','/icon/wdakLog.png',1,'1','进行线上支付','WAK','999999','01');
    

    13.17.2.index.js加载功能模块

    const App = getApp();
    var Base64 = require('../../utils/base64Decode.js');
    Page({
        /**
         * 页面的初始数据
         */
        data: {
            yhxm: '',
            dwdm: '',
            yhdm: '',
            tab: []
            //测试数据
        },
    
        /**
         * 生命周期函数--监听页面加载
         */
        onLoad: function (options) {
            var userInfo = wx.getStorageSync("userInfos");
            this.setData({
                yhxm: userInfo.xm,
                dwdm: userInfo.dwdm,
                yhdm: userInfo.yhdm,
            })
            //加载功能模块数据
            this.loadModInfo();
        },
        /**
         * 初始化时获取页面的功能模块信息
         */
        loadModInfo: function () {
            var self = this;
            var userInfo = wx.getStorageSync("userInfos");
            var param = {
                "mod_id": "WAK",
                "fydm": App.globalData.FYDM,
                "yhdm": userInfo.yhdm
            }
            console.log("初始化时获取页面的功能模块的参数是:" + param);
            App.request.loadModInfo(App.globalData.IPURL, param, function (response) {
                var result = JSON.stringify(response);
                result = JSON.parse(result);
                // console.log(result);
                if (result.code == "00") {
                    //遍历首页的功能模块,为其跳转的地址根据功能代码(gndm)为其赋值参数
                    //1.如果是跳转到H5页面,将地址和参数准备好后使用Base64编码后存放在url中,在container.js中获取后直接解码使用
                    for (var i = 0; i < result.modlist.length; i++) {
                        var module = result.modlist[i];
                        if (module.gndm == "WAK01") {
                            module.url = Base64.encode(module.url + "?openid=" + userInfo.openid + "&yhdm=" + userInfo.yhdm);
                        } else if (module.gndm == "WAK02") {
                            module.url = Base64.encode(module.url + "?yhid=" + userInfo.yhdm + "&fydm=" + userInfo.dwdm);
                        }
                        //如果module.url为空,则为未配置页面,跳转到指定的404页面
                        if (module.url == " " || module.url == "") {
                            module.type = '01';
                            module.url = Base64.encode("wak/errorPage" + "?title=" + module.name);
                        }
                    }
                    self.setData({
                        tab: result.modlist
                    })
                }
            })
        },
    
        /** 
         * 调用微信扫一扫进行识别二维码进行,并将二维码的内容传递到sendCheckMsg做处理
         */
        getScancode: function () {},
    })
    

    13.17.3.index.wxml

    <view class="safk_index">
    	<!-- 2.页面上部,显示上部主体图片 -->
    	<view class="index_platform_img">
    		<view class="index_platform_view">
    			<view class="title"></view>
    			<image mode="widthFix" src="/images/banner1.jpg" class="background"></image>
    			<view class='imagesize'>
    				<image src="/icon/wakLogo.png" style="position: fixed" class="logo"
    					style="width: 200rpx;height:200rpx ;margin-top:60rpx;padding-left:275rpx;padding-right:275rpx">
    				</image>
    			</view>
    			<view class="child">人民法院微案款平台</view>
    		</view>
    	</view>
    
    	<!-- 3.显示欢迎用户信息-->
    	<view class="user_welcome_wrap">
    		<view>{{'欢迎您,'+yhxm}}</view>
    	</view>
    
    	<!-- 4.根据传入的数据动态显示宫格(一行两列图标)信息 -->
    	<view class="weui-grids">
    		<view class="weui-grid" wx:for="{{tab}}" wx:key="gndm">
    			<!-- 4.1.当页面为H5页面时(对应T_MODULE_ONLINE的type字段为01),跳转到container(H5页面容器),打开H5页面 -->
    			<view wx:if="{{item.type=='01'}}">
    				<navigator url="/pages/container/container?pageUrl={{item.url}}">
    					<view class='weui_grid_bg'>
    						<!-- 4.1.1.显示功能模块log -->
    						<view class="weui_grid_icon">
    							<image src="{{item.icon}}" mode="scaleToFill" />
    							<!-- 4.1.2.针对需要在图片右上角显示提示数字的设置,例如未审批的流程数-->
    							<text class="span"
    								wx:if="{{(item.mark=='true')&&(item.digital>0)&&(item.digital<=99)}}">{{item.digital}}</text>
    							<text class="span" wx:elif="{{(item.mark=='true')&&(item.digital>99)}}">99+</text>
    						</view>
    						<!-- 4.1.3.显示功能模块名称 -->
    						<text class="weui_grid_label">{{item.name}}</text>
    						<!-- 4.1.4.显示功能模块说明 -->
    						<text class="weui_grid_info">{{item.info}}</text>
    					</view>
    				</navigator>
    			</view>
    			<!-- 4.2.当页面为微信小程序页面时(对应T_MODULE_ONLINE的type字段为03),跳转到该微信小程序页面 -->
    			<view wx:elif="{{item.type=='03'}}">
    				<navigator url="{{item.url}}">
    					<view class='weui_grid_bg'>
    						<!-- 4.2.1.显示功能模块log -->
    						<view class="weui_grid_icon">
    							<image src="{{item.icon}}" mode="scaleToFill" />
    						</view>
    						<!-- 4.2.2.显示功能模块名称 -->
    						<text class="weui_grid_label">{{item.name}}</text>
    						<!-- 4.2.3.显示功能模块说明 -->
    						<text class="weui_grid_info">{{item.info}}</text>
    					</view>
    				</navigator>
    			</view>
    			<!-- 4.3.当点击为打开首页的一个函数时(对应T_MODULE_ONLINE的type字段为02),点击 -->
    			<view wx:else>
    				<view bindtap="{{item.url}}" class='weui_grid_bg'>
    					<!-- 4.3.1.显示功能模块log -->
    					<view class="weui_grid_icon">
    						<image src="{{item.icon}}" mode="scaleToFill" />
    					</view>
    					<!-- 4.3.2.显示功能模块名称 -->
    					<text class="weui_grid_label">{{item.name}}</text>
    					<!-- 4.3.3.显示功能模块说明 -->
    					<text class="weui_grid_info">{{item.info}}</text>
    				</view>
    			</view>
    		</view>
    	</view>
    </view>
    

    13.17.4.index.wxss

    .safk_index .title_index {
        height: 80rpx;
    }
    
    .safk_index .title_index .title_msg {
        display: flex;
    }
    
    .safk_index .title_index .title_msg .title_img_wrap {
        flex: 1;
        display: flex;
        justify-content: left;
        align-items: center;
    }
    
    .safk_index .title_index .title_msg .title_img_wrap image {
        margin-left: 10rpx;
        width: 65rpx;
        height: 65rpx;
    }
    
    .safk_index .title_index .title_msg .title_info_wrap {
        flex: 7;
        display: flex;
        justify-content: left;
        align-items: left;
        flex-direction: column;
        justify-content: space-around;
    }
    
    .safk_index .index_platform_img .index_platform_view {
        width: 750rpx;
        height: 340rpx;
        position: relative;
    }
    
    .safk_index .index_platform_img .index_platform_view image {
        width: 100%;
    }
    
    .safk_index .user_welcome_wrap {
        margin-top: 80rpx;
        background-color: #fff;
        padding: 20rpx;
    }
    
    .weui-grids {
        position: relative;
        overflow: hidden;
    }
    
    .weui-grids:before {
        content: " ";
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        height: 2rpx;
        border-top: 2rpx solid #d9d9d9;
        color: #d9d9d9;
        -webkit-transform-origin: 0 0;
        transform-origin: 0 0;
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
    
    .weui-grids:after {
        content: " ";
        position: absolute;
        left: 0;
        top: 0;
        width: 2rpx;
        bottom: 0;
        border-left: 2rpx solid #d9d9d9;
        color: #d9d9d9;
        -webkit-transform-origin: 0 0;
        transform-origin: 0 0;
        -webkit-transform: scaleX(0.5);
        transform: scaleX(0.5);
    }
    
    .weui-grid {
        position: relative;
        float: left;
        padding: 20rpx 20rpx;
        width: 50%;
        height: 200rpx;
        box-sizing: border-box;
    }
    
    .weui-grid:before {
        content: " ";
        position: absolute;
        right: 0;
        top: 0;
        width: 2rpx;
        bottom: 0;
        border-right: 2rpx solid #d9d9d9;
        color: #d9d9d9;
        -webkit-transform-origin: 100% 0;
        transform-origin: 100% 0;
        -webkit-transform: scaleX(0.5);
        transform: scaleX(0.5);
    }
    
    .weui-grid:after {
        content: " ";
        position: absolute;
        left: 0;
        bottom: 0;
        right: 0;
        height: 2rpx;
        border-bottom: 2rpx solid #d9d9d9;
        color: #d9d9d9;
        -webkit-transform-origin: 0 100%;
        transform-origin: 0 100%;
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
    
    .weui-grid:active {
        background-color: #ECECEC;
    }
    
    .weui_grid_bg {
        position: relative;
        float: left;
        padding: 0rpx 0rpx;
        width: 100%;
        box-sizing: border-box;
    }
    
    .weui_grid_icon {
        width: 64rpx;
        height: 64rpx;
        margin: 0 auto;
    }
    
    
    .weui_grid_icon image {
        display: block;
        width: 100%;
        height: 100%;
    }
    
    .weui_grid_icon+.weui_grid_label {
        margin-top: 4rpx;
    }
    
    
    .weui_grid_label {
        display: block;
        text-align: center;
        font-weight: bold;
        color: #000;
        font-size: 28rpx;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
    }
    
    .weui_grid_info {
        display: block;
        text-align: center;
        font-weight: bold;
        color: #C0C0C0;
        font-size: 24rpx;
        text-overflow: ellipsis;
        overflow: hidden;
    }
    
    .child {
        width: 750rpx;
        height: 48rpx;
        position: absolute;
        font-size: 52rpx;
        color: white;
        left: 0;
        top: 260rpx;
        right: 0;
        bottom: 0;
        margin: auto;
        text-align: center;
    }
    
    .background {
        width: 100%;
        height: 100%;
        position: fixed;
        background-size: 100% 100%;
        z-index: -1;
    }
    
    .title_name {
        width: 750rpx;
        height: 40rpx;
        position: absolute;
        font-size: 28rpx;
        color: white;
        left: 0;
        top: 40rpx;
        right: 0;
        bottom: 0;
        text-align: center;
    }
    
    .bgv {
        width: 100%;
        height: auto;
        position: absolute;
        top: 0;
        bottom: 0;
    }
    
    .weui-grid .span {
        position: absolute;
        /* 根据需要调整top和right */
        top: 0rpx;
        right: 85rpx;
        display: inline-block;
        padding: 4rpx 10rpx;
        min-width: 16rpx;
        border-radius: 36rpx;
        background-color: #fa5151;
        /* background-color: var(--weui-RED); */
        color: #fff;
        line-height: 1.2;
        text-align: center;
        font-size: 24rpx;
    }
    
    展开全文
  • 在小程序中怎么做客服的功能呢?想要自动客服功能的小程序?...为丰富小程序的服务能力,提高服务质量,微信为小程序提供客服消息能力,在微信小程序的各项功能当中这项功能的辅助性也有很大的作用。 在小程序端...
  • 微信小程序合集

    2018-10-13 15:53:29
    微信小程序合集 
  • 在入门微信小程序的时候,在其他编译软件中有使用less插件的小伙伴都会发现,在微信小程序-开发者工具中是没有下载插件这个入口的,所以我们可以借助vscode来辅助微信小程序-开发者工具安装less插件。 一、首先我们...
  • 微信小程序代码上传辅助工具,可处理前端操作,实现自动化上传工作流,理论上支持任何微信小程序项目。 利用提供的能力实现。 此工具适合小程序代码上传前需要许多先前工作的项目,如需要编译,修改环境配置,跑钩子...
  • 开发前必读简要 基于大量无效开发,无法上线的案例,所以开发前部分知识十分重要;| 链接 微信小程序个人注册简单步骤 ... 微信开发者工具【项目】详解 ...为了方便大家了解并入门微信小程序,我将一些可能会需
  • 当你的微信小程序编译包大小超过 1024kb 时,不要急着砍模块,我觉得它还能再挽救一下。   做了些什么 压缩 js/json/wxml/wxss 文件; 优化 jpg/gif/png/svg 文件; 没了。 目录说明 ./src 为开发目录 ./dist 为...
  • 基于微信小程序的学科竞赛辅助平台设计与实现.pdf
  • APP 抓包和微信小程序抓包-Charles 的精简使用教程

    万次阅读 多人点赞 2018-10-11 16:11:55
    APP 抓包和微信小程序抓包-Charles 的精简使用教程目标教程一、安装 Charles二、Charles 简介(1)Charles 欢迎页面(2)基础功能按钮(3)抓包内容显示方式(4)过滤抓包内容三、手机配置 Charles 代理四、解决配置...
  • Fundebug专注于JavaScript、微信小程序、微信小游戏,Node.js和Java实时BUG监控。真的是一个很好用的bug监控费服务,众多大佬公司都在使用。 1、申请小程序 我们假设你是从零开始开发第一个微信小程序,那么首先...
  • 1. 完成注册登录 在微信公众平台注册小程序,完成注册后得到APPID,可以同步进行信息... 2. 下载开发工具 根据计算机系统,下载 微信web开发者工具 3. 新建项目 ...微信小程序 ...传统的web是三层结构,而微信小程序是...
  • 微信小程序答题

    2018-05-16 09:22:41
    微信小程序答题,单选、多选和判断,在线得分和查看排行榜

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,563
精华内容 6,625
关键字:

微信小程序辅助

微信小程序 订阅