精华内容
下载资源
问答
  • 目录 1.JS-SDK 2. 每个页面的json配置 ...10.小程序的运行环境 11.运行限制 12.小程序运行机制 13.小程序更新机制 1.JS-SDK 简单点来说,JS-SDK就是微信开发的网页开发工具包,里面包括拍摄、录音、语音...

    目录

    1.JS-SDK

    2. 每个页面的json配置

    3.文件作用域

    4.微信的WXSS

    5.尺寸单位

    6.全局样式与局部样式

    7.WXS

    8.dataset

    9.响应显示区域变化

    10.小程序的运行环境

    11.运行限制

    12.小程序运行机制

    13.小程序更新机制


     1.JS-SDK

     

    简单点来说,JS-SDK就是微信开发的网页开发工具包,里面包括拍摄、录音、语音识别、二维码、地图、支付、分享、卡券等几十个API,随着JS-SDK的不断更新迭代,有些组件的调用方式也会随着变化,就比如图片预览组件

    2. 每个页面的json配置

    每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项

    3.文件作用域

    在 JavaScript 文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会互相影响。

    通过全局函数 getApp 可以获取全局的应用实例,如果需要全局的数据可以在 App() 中设置

    4.微信的WXSS

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

    为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。

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

    • 尺寸单位
    • 样式导入

    5.尺寸单位

    rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素

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

    注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。

    6.全局样式与局部样式

    定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器

    7.WXS

    WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构

    注意

    1. WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
    2. WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。
    3. WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。
    4. WXS 函数不能作为组件的事件回调。
    5. 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异
    // page.js
    Page({
      data: {
        array: [1, 2, 3, 4, 5, 1, 2, 3, 4]
      }
    })
    <!--wxml-->
    <!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 -->
    <wxs module="m1">
    var getMax = function(array) {
      var max = undefined;
      for (var i = 0; i < array.length; ++i) {
        max = max === undefined ?
          array[i] :
          (max >= array[i] ? max : array[i]);
      }
      return max;
    }
    
    module.exports.getMax = getMax;
    </wxs>
    
    <!-- 调用 wxs 里面的 getMax 函数,参数为 page.js 里面的 array -->
    <view> {{m1.getMax(array)}} </view>

    输出:5

    8.dataset

    在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。

    在 WXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如:

    • data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType 
    • data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype 

    9.响应显示区域变化

    显示区域尺寸

    显示区域指小程序界面中可以自由布局展示的区域。在默认情况下,小程序显示区域的尺寸自页面初始化起就不会发生变化。但以下两种方式都可以改变这一默认行为。

    在手机上启用屏幕旋转支持

    从小程序基础库版本 2.4.0 开始,小程序在手机上支持屏幕旋转。使小程序中的页面支持屏幕旋转的方法是:在 app.json 的 window 段中设置 "pageOrientation": "auto" ,或在页面 json 文件中配置 "pageOrientation": "auto" 。

    以下是在单个页面 json 文件中启用屏幕旋转的示例

    {
      "pageOrientation": "auto"
    }

    如果页面添加了上述声明,则在屏幕旋转时,这个页面将随之旋转,显示区域尺寸也会随着屏幕旋转而变化。

    从小程序基础库版本 2.5.0 开始, pageOrientation 还可以被设置为 landscape ,表示固定为横屏显示。

    在 iPad 上启用屏幕旋转支持 

    从小程序基础库版本 2.3.0 开始,在 iPad 上运行的小程序可以支持屏幕旋转。使小程序支持 iPad 屏幕旋转的方法是:在 app.json 中添加 "resizable": true 

    {
      "resizable": true
    }

    如果小程序添加了上述声明,则在屏幕旋转时,小程序将随之旋转,显示区域尺寸也会随着屏幕旋转而变化。注意:在 iPad 上不能单独配置某个页面是否支持屏幕旋转 

     Media Query

    有时,对于不同尺寸的显示区域,页面的布局会有所差异。此时可以使用 media query 来解决大多数问题

    .my-class {
      width: 40px;
    }
    
    @media (min-width: 480px) {
      /* 仅在 480px 或更宽的屏幕上生效的样式规则 */
      .my-class {
        width: 200px;
      }
    }

    屏幕旋转事件 

    有时,仅仅使用 media query 无法控制一些精细的布局变化。此时可以使用 js 作为辅助。

    在 js 中读取页面的显示区域尺寸,可以使用 selectorQuery.selectViewport 。

    页面尺寸发生改变的事件,可以使用页面的 onResize 来监听。对于自定义组件,可以使用 resize 生命周期来监听。回调函数中将返回显示区域的尺寸信息。(从基础库版本 2.4.0 开始支持。)

    Page({
      onResize(res) {
        res.size.windowWidth // 新的显示区域宽度
        res.size.windowHeight // 新的显示区域高度
      }
    })
    Component({
      pageLifetimes: {
        resize(res) {
          res.size.windowWidth // 新的显示区域宽度
          res.size.windowHeight // 新的显示区域高度
        }
      }
    })

    此外,还可以使用 wx.onWindowResize 来监听(但这不是推荐的方式)。 

    10.小程序的运行环境

    微信小程序运行在三端:iOS(iPhone/iPad)、Android 和 用于调试的开发者工具。

    三端的脚本执行环境以及用于渲染非原生组件的环境是各不相同的:

    • 在 iOS 上,小程序逻辑层的 javascript 代码运行在 JavaScriptCore 中,视图层是由 WKWebView 来渲染的,环境有 iOS8、iOS9、iOS10;

    • 在 Android 上,

      • 旧版本,小程序逻辑层的 javascript 代码运行中 X5 JSCore 中,视图层是由 X5 基于 Mobile Chrome 57 内核来渲染的;

      • 新版本,小程序逻辑层的 javascript 代码运行在 V8 中,视图层是由自研 XWeb 引擎基于 Mobile Chrome 67 内核来渲染的;

    • 在 开发工具上,小程序逻辑层的 javascript 代码是运行在 NW.js 中,视图层是由 Chromium 60 Webview 来渲染的。

    平台差异

    尽管三端的环境是十分相似的,但是还是有些许区别:

    • JavaScript 语法和 API 支持不一致:语法上开发者可以通过开启 ES6 转 ES5 的功能来规避(详情);此外,小程序基础库内置了必要的Polyfill,来弥补API的差异(详情)。

    • WXSShttps://developers.weixin.qq.com/miniprogram/dev/devtools/codecompile.html#样式补全),还是建议开发者需要在 iOS 和 Android 上分别检查小程序的真实表现。

    11.运行限制

    基于安全考虑,小程序中不支持动态执行 JS 代码,即:

    • 不支持使用 eval 执行 JS 代码
    • 不支持使用 new Function 创建函数

    12.小程序运行机制

    前台/后台状态

    小程序启动后,界面被展示给用户,此时小程序处于前台状态

    当用户点击右上角胶囊按钮关闭小程序,或者按了设备 Home 键离开微信时,小程序并没有完全终止运行,而是进入了后台状态,小程序还可以运行一小段时间

    当用户再次进入微信或再次打开小程序,小程序又会从后台进入前台。但如果用户很久没有再进入小程序,或者系统资源紧张,小程序可能被销毁,即完全终止运行

    小程序启动

    这样,小程序启动可以分为两种情况,一种是冷启动,一种是热启动

    • 冷启动:如果用户首次打开,或小程序销毁后被用户再次打开,此时小程序需要重新加载启动,即冷启动。
    • 热启动:如果用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态,这个过程就是热启动

    小程序销毁时机

    通常,只有当小程序进入后台一定时间,或者系统资源占用过高,才会被销毁。具体而言包括以下几种情形

    通常,只有当小程序进入后台一定时间,或者系统资源占用过高,才会被销毁。具体而言包括以下几种情形。

    • 当小程序进入后台,可以会维持一小段时间的运行状态,如果这段时间内都未进入前台,小程序会被销毁。
    • 当小程序占用系统资源过高,可能会被系统销毁或被微信客户端主动回收。
      • 在 iOS 上,当微信客户端在一定时间间隔内(目前是 5 秒)连续收到两次及以上系统内存告警时,会主动进行小程序的销毁,并提示用户 「该小程序可能导致微信响应变慢被终止」。
      • 建议小程序在必要时使用 wx.onMemoryWarning 监听内存告警事件,进行必要的内存清理

    wx.onMemoryWarning:监听内存不足告警事件

    当 iOS/Android 向小程序进程发出内存警告时,触发该事件。触发该事件不意味小程序被杀,大部分情况下仅仅是告警,开发者可在收到通知后回收一些不必要资源避免进一步加剧内存紧张

    13.小程序更新机制

    未启动时更新

    开发者在管理后台发布新版本的小程序之后,如果某个用户本地有小程序的历史版本,此时打开的可能还是旧版本。微信客户端会有若干个时机去检查本地缓存的小程序有没有更新版本,如果有则会静默更新到新版本。总的来说,开发者在后台发布新版本之后,无法立刻影响到所有现网用户,但最差情况下,也在发布之后 24 小时之内下发新版本信息到用户。用户下次打开时会先更新最新版本再打开

    启动时更新

    小程序每次冷启动时,都会检查是否有更新版本,如果发现有新版本,将会异步下载新版本的代码包,并同时用客户端本地的包进行启动,即新版本的小程序需要等下一次冷启动才会应用上

     

    出处微信小程序文档:https://developers.weixin.qq.com/miniprogram/dev/framework/

    另一篇有关小程序中的代码知识点解释博客可供借鉴:https://blog.csdn.net/zhumizhumi/article/details/102709176

    展开全文
  • 从今天开始就来带领大家学习微信小程序了,只要你跟着我一步步来,相信你也可以上线一款属于自己的微信小程序 一,认识小程序 微信⼩程序,简称⼩程序,英⽂名 Mini Program Mini Program ,是⼀种不需要下载安装...

    讲解课程:https://edu.csdn.net/course/detail/9531

    写在前面

    1,讲解视频

    视频课我会在B站免费提供给大家,欢迎关注,欢迎三连。
    https://space.bilibili.com/419474640/video

    2,配套笔记

    配套笔记会在csdn上免费给到大家,欢迎关注,笔记会持续更新。
    https://blog.csdn.net/qiushi_1990

    3,支持石头哥😊

    3-1,源码和配套资源获取

    目前源码和配套的一些资源暂时不免费,如果有需要的同学可以私聊石头哥,拿米来换。

    3-2,笔记电子书

    笔记我也有整理一套电子书,大家也可以私聊石头哥获取电子书版的配套笔记。电子书笔记方便后期查询知识点。

    4,问题解答(●’◡’●)

    另外石头哥提供配套解答服务。当然了,知识付费时代石头哥解答是要米的,毕竟石头哥精力有限,石头哥也是要吃面包的。石头哥有推出包月,包年解答服务。你在学习过程中有任何问题,或者工作中遇到任何编程问题,都可以来找石头哥
    石头哥目前可以解答如下问题

    • 小程序方面的问题
    • 云开发方面的问题
    • Java,springboot,Javaweb方面的问题
    • 毕设方面的问题
    • 安卓app开发方面的问题
    • html+css+JavaScript方面的问题
    • 前端开发的问题
    • 后端开发的问题
    • 面试找工作方面的问题

    从今天开始就来带领大家学习微信小程序了,只要你跟着我一步步来,相信你也可以上线一款属于自己的微信小程序。

    一,认识小程序

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

    1-1,微信小程序的优势

    • 1.微信有海量⽤⼾,⽽且粘性很⾼,在微信⾥开发产品更容易触达⽤⼾;
    • 2.推⼴app或公众号的成本太⾼。
    • 3.开发适配成本低。
    • 4.容易⼩规模试错,然后快速迭代。
    • 5.跨平台。

    通过小程序和app的使用步骤,更容易看出来

    可以看出小程序和app使用相比:免安装,免注册,免卸载。正如张小龙所说“随用随走”

    1-2,小程序发展前景

    通过腾讯2020年财报可以看出,2019年上线小程序已经超过100万个,小程序日活也已经突破4亿

    2019年小程序带动就业536万个,所以我们不管是学习小程序开发,还是学习小程序运营,都有很广的就业前景。

    1-3,小程序发展历史

    • 2016年1月11日,微信之父张小龙时隔多年的公开亮相,解读了微信的四大价值观。张小龙指出,越来越多产品通过公众号来做,因为这里开发、获取用户和传播成本更低。拆分出来的服务号并没有提供更好的服务,所以微信内部正在研究新的形态,叫「微信小程序」。
    • 2016年9月21日,微信小程序正式开启内测。在微信生态下,触手可及、用完即走的微信小程序引起广泛关注。腾讯云正式上线微信小程序解决方案,提供微信小程序在云端服务器的技术方案。
    • 2017年1月9日0点,万众瞩目的微信第一批微信小程序正式低调上线,用户可以体验到各种各样微信小程序提供的服务。
    • 2017年12月28日,微信更新的 6.6.1 版本开放了小游戏,微信启动页面还重点推荐了小游戏「跳一跳」,你可以通过「微信小程序」找到已经玩过的小游戏。
    • 2018年1月18日,微信提供了电子化的侵权投诉渠道,用户或者企业可以在微信公众平台以及微信客户端入口进行投诉。
    • 2018年1月25日,微信团队在“微信公众平台”发布公告称,“从移动应用分享至微信的小程序页面,用户访问时支持打开来源应用。同时,为提升用户使用体验,开发者可以设置小程序菜单的颜色风格,并根据业务需求,对小程序菜单外的标题栏区域进行自定义。
    • 2018年3月,微信正式宣布微信小程序广告组件启动内测,内容还包括第三方可以快速创建并认证小程序、新增小程序插件管理接口和更新基础能力,开发者可以通过微信小程序来赚取广告收入。除了公众号文中、朋友圈广告以及公众号底部的广告位都支持微信小程序落地页投放广告,微信小程序广告位也可以直达小程序。
    • 2018年7月13日,微信小程序任务栏功能升级,新增“我的微信小程序”板块;而微信小程序原有的“星标”功能升级,可以将喜欢的小程序直接添加到“我的微信小程序”。
    • 2018年8月10日,微信宣布,微信小程序后台数据分析及插件功能升级,开发者可查看已添加「我的微信小程序」的用户数。此外,2018年8月1日至12月31日期间,微信小程序(含小游戏)流量主的广告收入分成比例优化上调,单日广告流水10-100万区间的部分,开发者可获得的分成由原来流水的30%上调到50%,优质微信小程序流量主可获得更高收益。
    • 2018年9月28日,微信“功能直达”正式开放,商家与用户的距离可以更“近”一步:用户微信搜一搜功能词,搜索页面将呈现相关服务的微信小程序,点击搜索结果,可直达微信小程序相关服务页面。
    • 2019年8月9日,微信向开发者发布新能力公测与更新公告,微信 PC 版新版本中,支持打开聊天中分享的微信小程序。安装最新PC端测试版微信后,点击聊天中的微信小程序,便会弹出微信小程序浮窗。而在微信小程序右上角的操作选项中,可以进行“最小化”操作,让微信小程序像其他PC软件一样最小化,排列于Windows系统的任务栏中。

    1-4,为什么学习小程序

    我们上面了解完小程序的优势和历史以后,就知道我们为什么要学习小程序了

    • 依赖微信生态
    • 就业面广
    • 上手快
    • 学习完微信小程序以后,再去学习百度小程序,抖音小程序,支付宝小程序就很方便了。因为这些小程序api都很相似。
    • 相对于Java,php,python而言,小程序更适合作为编程的入门语言
    • 相对于传统前端开发,我们在学习小程序的同时就可以学习css,JavaScript的知识

    1-5,微信小程序对创业者的优势

    • App开发的推广成本过高
    • 移动互联网格局已定,用户需求被各路巨头把持,我们要想在移动互联网有一番作为,微信是不可避免的靠山
    • 小程序能以最小的成本,最快的速度验证你的商业模式。

    二,开发者工具

    工欲善其事必先利其器,所以我们在开发小程序之前必须准备好一款适合自己的开发者工具,这里我给大家推荐官方开发者工具。原因有以下几点

    • 官方的所有更新,都会第一时间在官方开发者工具同步
    • 有任何问题,可以直接反馈给官方
    • 官方开发者工具更新迭代最及时
    • 我们用官方开发者工具,使用一些官方功能最稳定。
      下面就来教大家如何下载官方开发工具

    2-1 官方开发者工具下载地址

    https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
    建议大家下载最新的稳定版本

    然后点击自己电脑对应系统的版本下载即可。至于安装很方便,只需要双击安装包,不停的点下一步即可,安装完成以后的官方开发者工具长这样。

    2-2,认识微信开发者工具

    我们安装好开发者工具以后,只需要双击打开即可。

    通常我们第一次打开,会出现上图所示的,只需要用微信扫描即可登录开发者工具。扫码登录以后会出现下面这样的界面。

    三,创建属于自己的第一个小程序

    上面第二步已经安装好开发者工具了,接下来就来教大家如何创建一个最简单的小程序

    3-1,在桌面上创建一个空白文件

    名字可以随便取,我这里习惯取小石头

    3-2,点击 + 号,创建小程序。

    3-3,小程序项目配置

    这里需要注意下,小程序官方最新的开发者工具有了变化,所以你创建项目时如果不长下面这样。可以跳过这个图片,看下面新版的

    新版的如下,多了一个模板选择,这里注意:要选择不使用模板。

    配置好以后,点新建,即可创建属于自己的第一个小程序,然后创建会有一个过程,耐心等待即可。

    3-4,熟悉开发者工具

    3-5,开发者工具个性化的配置

    主要给大家讲一些个性化的配置

    我们可以配置主题颜色,模拟器位置,这些完全可以根据个人喜好进行设置。

    3-6,小程序结构目录

    下图是程序目录,每一个我都给大家标注出来了,大家前期不用死记硬背,后面开发学习过程中,用的多了, 自然就记住目录下每个文件的作用了。

    四,小程序开发三剑客

    4-1小程序三剑客: wxml+wxss+js

    1, wxml主要用来布局组件的(相当于大楼结构)
    如:楼有几层,每层有多少房间,有什么设备
    2, wxss主要决定显示样式(决定大楼的样式)
    如:颜色,大小,宽高等
    3, js主要用来处理逻辑(决定大楼具备哪些功能)
    如:大楼具有电梯功能,空调制冷,灯光,供水,供电,主要是为了大厦的运行。

    下面画个图,来说明三者的关系。

    4-2,小程序文件和传统web对比

    结构小程序传统web
    结构布局WxmlHtml
    样式WxssCss
    逻辑JavaScriptJavaScript
    配置Json

    五,小程序常见组件的学习

    5-1,认识view组件

    view组件:相当于一个盒子,可以用来装一些别的组件
    https://developers.weixin.qq.com/miniprogram/dev/component/view.html
    如果大家有html的web基础,就可以把我们小程序里的view理解为html里的div标签。如果你没学过也无所谓,直接跟着我学习view即可。

    5-2,认识text组件

    text组件:主要用来显示文字的
    https://developers.weixin.qq.com/miniprogram/dev/component/text.html

    5-3,认识input组件

    input组件主要用来获取用户输入的信息的,一般在用户填写信息,提交数据,登录注册时会用到。
    https://developers.weixin.qq.com/miniprogram/dev/component/input.html

    5-4,认识button组件

    button 组件:是按钮组件,自带默认的按钮效果,我们后面会经常用到
    https://developers.weixin.qq.com/miniprogram/dev/component/button.html

    六,函数和事件的学习

    6-1,注释的学习

    我们在学习后面课程之前,先来学习下注释。注释是在代码里给予提示使用的,主要是让别人更快的熟悉你的代码,也方便后期自己看自己的代码,快速回忆起来使用的。
    — 注释有快捷键的 —

    • window电脑:Ctrl+/
    • mac电脑:command+/

    wxml里的注释如下

    wxss里的注释

    js里的注释

    6-2,日志打印的学习

    我们在学习点击事件之前,需要先学习日志(log)的打印,因为我们开发过程中会经常用到日志打印。日志打印的语法如下

    console.log("我的打印出来的日志内容")
    

    6-3,函数的学习

    函数的两种使用方式如下图:

    6-4,点击事件的学习

    我们如果想给一个组件定义点击事件,就要用到bindtap,我们给一个组件绑定点击事件的语法如下。

    我们给一个组件定义点击事件,主要是给组件定义一个 bindtap=“事件名”,然后再js页面里定义和事件名一样的函数即可。视频里会作详细讲解

    6-5,获取用户输入信息

    我们获取用户输入会用到bindinput事件,其实我们在学习input组件时,官方有给出这个属性的。https://developers.weixin.qq.com/miniprogram/dev/component/input.html

    看官方的文档,可以知道bindinput主要是为了获取用户的输入内容。
    bindinput的定义如下图。

    在wxml里定义好bindinput事件以后,在js页面再定义一个和事件名一样的函数即可。视频里会作详细讲解。如果你有买老师的课程,或者购买老师的年卡,可以获取对应的学习视频。

    七,变量的学习

    7-1,什么是变量

    用大白话讲:变量就是一个装东西的盒子
    再通俗些讲:变量就是用于存放数据的容器,我们通过变量名获取对应的数据。

    如上图所示,我们的盒子(变量)可以装名字,布尔类型的true,还可以用来装数字。
    变量的本质:就是在程序的内存中申请一块用来存放数据的空间。

    7-2,变量的组成

    变量由变量名和存储的值组成,语法如下

    var x = 7;
    var y = 8;
    var z = x + y; 
    
    从上例中,您可知道x,y,z是三个不同的变量名:
    x 存储值 7
    y 存储值 8
    z 存储值 15
    

    变量有点类似我们的酒店房间。一个房间就可以看作是一个变量。例如我们的808号房间是情侣间。那么808这个房号就相当于我们的变量名,情侣间就是这个变量存储的值。

    7-3,变量的使用

    变量在使用时分两个步骤:

    • 1,声明变量

    来看下具体代码

    //声明变量
    var age 
    

    这段代码的意思是声明一个叫age的变量
    var是一个JavaScript关键字,用来声明变量,使用该关键字声明变量以后,计算机会自动为变量分配一个内存空间,用来存储数据。
    age就是我们的变量名,我们要通过变量名来访问到计算机内存里分配的空间。

    • 2,赋值

    还是拿我们的酒店房间来举例,声明变量就相当于在前台办理入住,确定要住那个房间,也就是确定房间号(变量名),然后确定房间号对应的房型,比如单人间,双人间,情侣间。而确定房型就相当于是给变量赋值。

    //给age赋值
    age=10
    

    这段代码的意思,就是给age变量赋值为10
    上面的 = 用来把右边的值赋给左边的变量名,也就是把我们的变量名age指向数值10,就可以用age来操作我们的数值了。赋值的目的就是为了后面使用数值。

    7-4,变量的初始化

    我们上面变量的使用可以直接写到一行

    var age=10 
    

    声明变量同时给变量赋值,我们称之为变量的初始化。

    7-5,变量的重新赋值

    一个变量可以被重新赋值,新的赋值会覆盖掉前面的赋值,变量值将以最后一次赋的值为准。

    var age=10
    age=18
    

    如上面的代码,我们的变量age先被赋值10,后又被赋值18,那么最后我们的age就是18
    这就好比,酒店的房间,808屋一开始住的是石头哥,后面石头哥走了,刘德华住进去了,那这个时候你再去808找人,找到的就是刘德华了。

    7-6.变量的命名规范

    • 名称可包含字母、数字、下划线和美元符号
    • 名称必须以字母开头
    • 名称对大小写敏感(y 和 Y 是不同的变量)
    • 不能是关键字,保留字(比如 JavaScript 的关键词)
    • 遵守驼峰命名法,首字母小写,后面的单词的首字母大写。如userName

    7-7,变量的小案例

    还记得我们的6-5这节学习了如何获取用户输入的信息吗?我们是不是可以用变量来存储我们获取到的用户输入信息呢。

    讲解视频里会做详细讲解:《零基础入门小程序开发》

    7-8,全局变量和局部变量

    局部变量:变量在函数内声明,只能在函数内部访问。
    全局变量:变量在函数外定义,整个代码都可以调用的变量。

    如上图所示的局部变量和全局变量的定义。

    八,数据类型

    8-1,认识数据类型

    上一节变量的学习,我们知道变量是用来装数据的盒子,可是数据有很多,有各种各样的类型。不同类型的数据占用的计算器内存也不一样。就好比胖子睡大床,瘦子睡小床就行。
    在计算机中不同的数据占用的存储空间是不同的,为了便于区分,充分利用存储空间,于是就定义了不同的数据类型。
    简单来说,数据类型就是数据的类别型号,比如“张三”是个人名,18是个数字

    8-2,常见的数据类型

    我们的数据类型可以分成下面两大类

    • 简单数据类型(Number String Boolean Undefined Null)
    • 复杂数据类型(Object)

    简单数据类型

    简单数据类型描述默认值
    Number数字型,包含整数和小数,如 18,18.80
    String字符串型,如“小石头”。注意js里字符串都要带引号“”
    Boolean布尔值类型,就true和false两个值,代表正确和错误false
    UndefinedUndefined 这个值表示变量不含有值,如var a;声明了变量a,但是没有赋值,就是undefinedundefined
    Null空值,如var a=null,声明了变量a为空值null

    8-3,数字型Number

    js数字类型的数据,既可以是整数,也可以是小数(浮点数)

    var age=21	//整数
    var PI=3.1415	//小数
    

    8-4,字符串String

    用引号或者双引号包起来的都是字符串类型,如 “编程小石头”,‘石头哥’都是字符串。字符串和羊肉串有点像,羊肉串是用竹签把羊肉一串串的串起来。字符串就是把字符串起来。

    var name="编程小石头"	//字符串
    var age1="18"		//字符串
    var age2=18		//数字型
    

    上面代码的age1和age2是有区别的,age1的18被双引号包裹着,所以是字符串,age2就是一个数字18,所以是数字型。这也进一步说明了,只要是被单引号或者双引号包裹着的都是字符串类型。

    字符串长度

    字符串是由若干字符组成的,这些字符的数量就是字符串的长度,通过字符串的length属性可以获取整个字符串的长度。
    还是拿羊肉串来类比,比如你一个羊肉串上串了5块羊肉,那么这个羊肉串的长度就是5。
    使用的语法如下

        var name="编程小石头"
        console.log(name.length)	//这里的输出结果是5
    

    字符串的拼接

    多个字符串之间可以使用 + 进行拼接,其拼接方式为 字符串+字符串=拼接之后的新字符串。
    语法如下:

        var name="编程小石头"
        var weixin=2501902696
        var test=name+weixin
        console.log(test) //输出结果:"编程小石头2501902696"
        console.log(12+12)//输出结果:24
        console.log("12"+12)//输出结果:1212
    

    上面的12+12=24,“12”+12=“1212” 这就告诉我们字符串加任何类型的数据,拼接后的结果都是字符串。

    8-5,布尔型Boolean

    布尔类型有两个值:true和false,其中true表示真,false表示假。

    var flag=true
    

    8-6,Undefined和Null

    一个声明后没有赋值的变量会有一个默认值 undefined
    一个声明变量,并且赋值null,就代表这个变量是空值(学习object对象时,我们会继续研究null)
    null 和 undefined 的值相等,但类型不同,下面的8-7会有代码演示

    8-7,typeof 操作符

    typeof 操作符用来检测变量的数据类型

    typeof "John"                // 返回 string 
    typeof 3.14                  // 返回 number
    typeof false                 // 返回 boolean
    

    打印null和undefined的数据类型如下

        var aaa=undefined
        var bbb=null
        console.log(aaa==bbb)//输出结果:true
        console.log(typeof aaa)//输出结果:undefined
        console.log(typeof bbb)//输出结果:object
    

    注意:这里的 == 用来判断值是否相等,后面会讲。
    上面的代码可以看出:null 和 undefined 的值相等,但类型不同

    8-8, 数据类型的转换

    就是把一种数据类型的变量转换成另外一种数据类型,比如把字符串的 “18”转换为数字类型的18
    常用的数据类型转换

    • 把其他类型转为字符串型
    • 把其他类型转为数字型

    转换为字符串

    方式说明案例
    toString()转为字符串var num=1 num.toString()
    String()转为字符串var num=1 String(num)
    用加号拼接字符串转为字符串var num=1 “”+num

    转换为数字型(重点)

    方式说明案例
    Number()将字符串转换为数字Number(“3.14”) // 返回 3.14
    parseFloat()解析一个字符串并返回一个浮点数parseFloat(“3.12”) //返回3.12
    parseInt()解析一个字符串并返回一个整数parseInt(“3.12”) //返回3

    转为数字的几个特殊情况

    console.log(Number(""))//空字符串转换为 0
    console.log(Number(true))//true转换为1
    console.log(Number(false))//false转换为0
    console.log(Number("编程小石头"))//其他的字符串会转换为 NaN (不是个数字)
    

    九,综合小案例~开发简单的计算器

    9-1,数据绑定

    在学习这个综合案例之前,我们需要先学习下小程序的动态数据绑定。数据绑定的语法如下

    <!--wxml-->
    <view> {{message}} </view>
    
    // js里如下
    Page({
      data: {
        message: '我是动态绑定的数据'
      }
    })
    

    9-2,效果图预览

    上一节和大家讲解了小程序的一些常用组件,这节就带大家写出自己的第一个简单计算器。做一个综合性的练习。由于是入门,这里先教大家简单的加法运算。效果图如下1.png
    实现起来特别简单,代码也特别少,就下面三个

    • index.wxml:上图的布局视图页
    • index.js:实现加法逻辑的页面
    • app.json:一些全局的配置。基本是都是默认的这里不用管
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n1U75mfw-1597396869759)(https://upload-images.jianshu.io/upload_images/6273713-2b8639cf9f1fc8ea.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
      下面就带带大家敲出属于自己的计算器小程序代码。

    9-3,先看index.wxml

    <!--index.wxml  -->
    <input placeholder="请输入数字a" bindinput="inputa" />
    <text>+</text>
    <input placeholder="请输入数字b" bindinput="inputb" />
    <button bindtap='sum'>计算</button>
    <text>结果为:{{result}}</text>
    

    代码虽然少,但是作为刚入门的你,看起来可能很茫然,下面详细给大家讲下。

    <input placeholder="请输入数字a" bindinput="inputa" /> 
    <input placeholder="请输入数字b" bindinput="inputb" />
    

    就是我们输入数字a的输入框,这里input就是我们认识的第一个小程序组件。
    input的官方简介如下:https://developers.weixin.qq.com/miniprogram/dev/component/input.html
    placeholder:设置默认显示文字(当我们输入文字时,默认的就没有了)
    bindinput=“inputa”:定义一个inputa方法来获取input的输入内容。在index.js中会用到

    • +
      这里的 组件是用来显示文本的这里我们只是为了显示一个 + 号
    <button bindtap='sum'>计算</button>
    

    这里是个按钮就是我们的计算按钮
    bindtap=‘sum’:定义个叫sum的方法,用来计算结果在index.js中会用到

    • 结果为:{{result}}
      {{result}} 这种写法,是小程序用来绑定数据用的,这里用来显示我们的计算结果用的,

    上面代码和对应的显示如下:

    4.jpg

    9-4,再来看index.js,我们加法的逻辑实现

    可以看到我们在index.wxml里定义的bindinput=“inputa”,bindtap='sum’在下面有用到

    Page({
      /**
         * 页面的初始数据
         * 初始化两个输入值
         */
      data: {
        input1: 0,
        input2: 0
      },
      //获取用户输入的值a
      inputa: function (e) {
        this.setData({
          input1: e.detail.value
        })
      },
      //获取用户输入的值b
      inputb: function (e) {
        this.setData({
          input2: e.detail.value
        })
      },
      // 拿到两个输入值以后求和
      sum: function (e) {
        var a = parseInt(this.data.input1);
        var b = parseInt(this.data.input2);
        // 求和
        var sumResult = a + b
        this.setData({
          // 把结果赋值到sum标签上
          result: sumResult
        })
      }
    })
    

    index.js的代码不多,大家可以先照着敲一下。学小程序前期不需要你理解,但是一定要多敲多练。
    这里的逻辑用文字写出来,估计大家新入门时还是不太好理解,我会录视频来给大家讲解。

    9-5,作业,自己写一个减法计算器

    十,运算符

    运算符也被称为操作符,是用于实现赋值,比较和运算等功能的符号。

    10-1,算数运算符

    运算符描述例子x 运算结果
    +加法x=5+27
    -减法x=5-23
    *乘法x=5*210
    /除法x=5/22.5
    %取模(余数)x=5%21

    10-2,表达式和返回值

    表达式:是由数字,运算符,变量等以能求得结果的有意义的操作组成的式子。
    表达式最终都会有一个结果返回给我们,这个返回结果我们称之为返回值

    • 如 let x=1+1
      这里的1+1就是由数字和加号组成的表达式,然会返回结果2赋值给x,那么x的值就是2。通俗的讲就是先把右边的表达式计算完毕然后把值返回给左边的x。

    10-3,比较运算符

    比较运算符是两个数据进行比较时所使用的运算符,比较运算以后会返回一个布尔值的结果,就是返回对或者错(true或false)

    运算符描述案例结果
    <小于号1<2true
    >大于号1>2false
    >=大于等于号(大于或等于)1>=2false
    <=小于等于号(小于或等于)1<=2true
    ==判等号(判断是否相等)1==1true
    ===绝对等于(值和类型均相等)1===‘1’false
    !=不等于1!=1false

    10-4,赋值运算符

    赋值运算符向 JavaScript 变量赋值。

    运算符例子等同于
    =x = yx = y
    +=x += yx = x + y
    -=x -= yx = x - y
    *=x *= yx = x * y
    /=x /= yx = x / y
    %=x %= yx = x % y

    =的小结

    • =:赋值,把右边赋值给左边 如a=b
    • ==:判断,判断两边的值是否相等 如 a ==b
    • === :全等,判断两边的值和数据类型是否完全相等 如 a === b

    10-5,逻辑运算符

    用于多个条件的判断,其返回值是布尔值。

    • && 逻辑与,两个条件都要满足,两侧都是true结果才为true
    • || 逻辑或,两个条件只需要满足一个即可,有一侧是真结果就真
    • ! 逻辑非 not,逻辑取反,如true的相反值是false

    比如你要充话费

    • && 你想用微信充:必须你有微信并且使用微信支付才可以充
    • || 你去营业厅充:微信或者支付宝支付都可以
    • ! 如果只有支付宝和微信两种方式:你不想用微信那就只能用支付宝了

    10-6,递增和递减运算符

    递增和递减运算符概述:如果需要反复的给数字变量加或减去1,可以使用递增(++) 和递减(–)运算符来完成。
    在js里递增(++) 和递减(–)既可以放在变量前面,也可以放在变量后面,放在前面时称为前置递增或递减运算符,放在后面时称为后置递增或递减运算符。
    注意:递增或者递减只能操作变量,不能直接操作数字。

    10-6-1,前置递增递减运算符

    注意:前置递增或递减时,是先自加或自减,然后返回值
    我们之前想要一个变量加1写法如下

    var num=1
    num=num+1 //这里就是给num加1
    

    我们有没有方便的写法呢,上面的num=num+1,可以直接写成 ++num,这样是不是更简洁。

    10-6-2,后置递增递减运算符

    注意:后置递增或递减时,先返回值,然后自加或自减

    10-6-3,前置和后置的区别

    • 前置和后置如果单独使用,效果是一样的
    • 前置是先自加或自减,然后返回值;后置先返回值,然后自加或自减
    var num=10
    console.log(++num  +10)//结果是21
    console.log(num++  +10)//结果是20
    

    我们通过下面几个小例子来强化理解下

    var a=10
    ++a
    console.log(b)//这里b的结果是几
    
    var c=10
    c++
    var d=c++ +2
    console.log(d)//这里d的结果是几
    
    var e=10
    var f=e++ + ++e
    console.log(f)//这里f的结果是几
    

    10-6-4,前置和后置递增递减的小结

    • 前置和后置的主要目的是为了简化代码编写
    • 单独使用递增或递减时,前置和后置效果一样
    • 与其他运算连用时,执行结果会不同
      后置:先返回原值,后自加(先人后己)
      前置:先自加,后返回值(先己后人)
      可以总结为:前置自私,后置无私
    • 开发时,大多使用后置递增/减。例如 num++或num- -

    十一,条件语句和循环语句

    11-1,流程控制

    在学习条件语句河循环语句之前,我们要先知道什么是流程控制,
    **流程控制:**流程控制就是来控制我们的代码按照什么顺序来执行的语句。
    流程控制主要有三种结构

    • 顺序结构
    • 分支结构
    • 循环结构

      顺序结构是程序中最简单,最基础的流程控制,就是代码按照先后顺序依次执行。我们重点是讲解分支结构和循环结构。

    11-2,分支结构

    我们上面讲的分支结构,就是代码在从上到下的执行过程中,根据不同的条件,执行不同的代码,从而得到不同的结果。分支结构常用的语句就是条件语句.
    我们常用的分支结构的语句:

    • if语句
    • switch语句

    条件语句: 用于基于不同条件执行不同的动作,通常在写代码时,您总是需要为不同的决定来执行不同的动作。您可以在代码中使用条件语句来完成该任务。
    在这里插入图片描述
    举个最简单的例子:你满18岁就可以去网吧,不满18岁就不允许进网吧。这里的判断条件就是你的年纪。
    我们这里常用的就是if条件语句,所以接下来我们会重点讲解下if条件语句。

    11-3,if条件语句

    在 JavaScript 中,我们可使用以下条件语句:

    • if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码
    • if…else 语句 - 当条件为 true 时执行代码,当条件为 false 时执行其他代码
    • if…else if…else 语句- 使用该语句来选择多个代码块之一来执行

    11-3-1,if 语句

    使用 if 语句来规定假如条件为 true 时被执行的 JavaScript 代码块。

    • 语法
    if (条件) {
        如果条件为 true 时执行的代码
    } 
    
    • 实例
    if (age< 18) {
       console.log("未成年")
    }
    

    如果年龄小于18岁,就输出未成年

    11-3-2,if else 双分支语句

    使用 else 语句来规定假如条件为 false 时的代码块。

    if (条件) {
        条件为 true 时执行的代码块
    } else { 
        条件为 false 时执行的代码块
    }
    
    • 实例
    if (age < 18) {
         console.log("未成年")
     } else {
        console.log("成年")
     } 
    

    如果年龄小于18岁,就输出未成年,否则就输出成年

    11-3-3,if else if 多分支语句

    使用 else if 来规定当首个条件为 false 时的新条件。

    语法
    if (条件 1) {
        条件 1 为 true 时执行的代码块
    } else if (条件 2) {
        条件 1 为 false 而条件 2 为 true 时执行的代码块
     } else {
        条件 1 和条件 2 同时为 false 时执行的代码块
    }
    
    • 实例
    if (age < 18) {
         console.log("未成年")
     } else if(age<60) {
        console.log("成年")
     } else {
        console.log("老年")
     } 
    

    如果年龄小于18岁,就输出未成年,年龄大于18岁小于60岁就输出成年,年龄大于60岁就输出老年。

    11-4 wxml条件渲染

    在wxml中,使用 wx:if="" 来判断是否需要渲染该代码块:

    <view wx:if="{{condition}}"> 我是可以显示的</view>
    

    也可以用 wx:elif 和 wx:else 来添加一个 else 块:

    <view wx:if="{{length > 5}}"> 1 </view>
    <view wx:elif="{{length > 2}}"> 2 </view>
    <view wx:else> 3 </view>
    

    可以看出wxml里的条件渲染和我们上面讲的if条件语句类似,只是写法上稍微有些区别。
    wxml里的条件渲染主要用来做页面展示和隐藏使用的。

    11-5,for循环语句

    如果您希望一遍又一遍地运行相同的代码,并且每次的值都不同,那么使用循环是很方便的。
    比如我们想输出5编编程小石头

    • 一般写法:
      console.log(“编程小石头”)
      console.log(“编程小石头”)
      console.log(“编程小石头”)
      console.log(“编程小石头”)
      console.log(“编程小石头”)
    • 使用for循环
    for (var i=0;i<5;i++){ 
      console.log("编程小石头")
    }
    

    for 循环的语法:

    for (初始化变量; 条件表达式; 操作表达式){
        被执行的代码块
    }
    
    • 初始化变量:开始前第一个执行,通常用于初始化计数器变量,只执行一次。
    • 条件表达式:就是用来决定每一次循环是否可以继续执行, 定义运行循环的终止条件
    • 操作表达式:在大括号里的代码块已被执行之后执行,通常用于对我们的计数器变量进行递增或者递减操作。

    实例

    for (var i=0;i<5;i++){ 
      console.log("编程小石头")
    }
    

    上面实例中
    语句1:var i=0 是在开始执行前初始化变量i
    语句2:i<5 是用来判断i是否小于5,如果小于5就继续执行循环
    语句3:i++ 是在每次循环执行一遍后对i进行加1的操作

    11-6,wxml列表渲染

    在wxml里我们使用wx:for来显示列表数据。
    在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
    默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

    <view wx:for="{{array}}">
      {{index}}: {{item.name}}
    </view>
    

    在js里定义的列表数据如下

    Page({
      data: {
        array: [{
          name: '编程小石头',
        }, {
          name: '邱石'
        }]
      }
    })
    

    11-7,continue和break的学习

    continue和break都是用来终止循环的,区别在于

    • continue:是终止循环中的某一次,继续执行后面的循环
    • beak: 直接终止整个循环执行,整个循环不在执行

    十二,数组的学习

    12-1,数组的概念

    数组就是一组数据的集合,可以把更多的数据存储在单个变量下。
    数组里面可以存储各种类型的数据。
    如: var names=[‘编程小石头’,16,true]

    12-2,创建数组的两种方式

    • 1,使用new创建数组(不常用)
    var names=new Array(); 
    names[0]="编程小石头";       
    names[1]="刘德华";
    names[2]="周杰伦";
    
    • 2,利用数组字面量创建数组(常用)
    var names=['编程小石头','刘德华','周杰伦']
    

    明显看到第二种创建数组的方式比第一种更简洁,所以以后我们创建数组就用第二种方式

    12-3,获取数组元素

    我们获取数组元素是通过数组下标来获取的,下标也叫做索引,数组的下标是从0开始的。如下图
    数组可以通过下标来访问,设置,修改对应的元素值。我们可以通过
    数组名[下标] 的方式来获取数据中的元素。
    如 names[0]就可以获取names数组里的第一个元素‘编程小石头’

    12-4,计算数组的和以及平均值

    前面我们已经学完如何遍历数组了,如果我这里让大家去求下数组里所有元素的和以及平均值,大家知道如何去求吗。

    • 作业
      已知数组 [1,2,3,4,5,6] 如果通过代码计算这个数组的和以及平均值。

    12-5,求数组中的最大值

    var nums=[1,2,3,4] 这个数组我们很明显就可以看出来4是数组里的最大值,但是如果我们数组里的元素有很多,这个时候你就未必能很快的找出来最大值了,所以我们要想求数组里的最大值,要让代码去实现,而不是你肉眼去看。

    • 思路
      其实我们找数组中的最大值,有点类似于武术比赛打擂台

      我们首先拿第一个和第二个比,胜出者在待定席位,然后第三个来挑战胜出者,这样又会产生新的胜出者,然后后面的元素都来逐个挑战胜出者,直到最后一个胜出者,就是我们要找的最大值。而这样一v一的对决,正好可以借助我们的循环来实现。
        var nums = [1, 2, 3, 4, 5]
        var max = nums[0]
        for (var i = 1; i < nums.length; i++) {
          if (max < nums[i]) {
            max = nums[i]
          }
        }
        console.log('最大值', max)  //可以得出最大值是5
    

    12-5,给数组添加新元素

    push() 方法可向数组的末尾添加一个或多个元素,所以我们一般给数组追加元素的时候,直接使用push方法就可以了。

        var nums = [1, 2, 3, 4, 5]
        nums.push(6)
        nums.push(7, 8)
        console.log(nums) //追加新元素后的数组  [1, 2, 3, 4, 5, 6, 7, 8]
    

    12-6,删除数组中的指定元素

    如我们想把数组中的指定元素删除掉,可以用一个新的数组来接受符合要求的元素,不符合要求的元素不接收,这样就可以实现删除数组元素的效果

    	// 把元素5删除
        var nums = [1, 2, 3, 4, 5]
        //1,定义一个新数组
        var newNums = []
        //2,遍历旧数组
        for (var i = 0; i < nums.length; i++) {
          //3,把符合要求的元素添加到新的数组里
          if (nums[i] !== 5) {
            newNums.push(nums[i])
          }
        }
        console.log(newNums) //删除成功 [1, 2, 3, 4]
    

    十三,对象的学习

    13-1,什么是对象

    对象只是一种特殊的数据。对象是一组无序的相关属性和方法组成。这里重点要记住属性和方法这两个新概念

    • 属性:事物的特征,对象里的属性就是用来表现该对象具备哪些特征
    • 方法:事物的行为,对象里方法就是用来表示该对象具备哪些行为。

    例如:
    石头哥具备姓名,年龄,身高,体重等属性
    石头哥具备写代码,唱歌,骑车,跑步,吃饭等行为。

    • 手机具备下面的属性和方法

    13-2,为什么需要对象

    我们在保存一个数据时,可以用变量,保存多个数据时可以用数组。但是我如果想保存一个完整的立体的信息时呢。

    • 比如保存石头哥的完整信息。
      如果我们用数组来表示就是
      var shitouge=[‘编程小石头’,‘男’,‘128’,‘180’]
      这样我虽然把石头哥的完整信息保存到了数组里,也可以大致猜出来哪些数据代表什么意思,但是后面的128和180是什么意思呢???

    但是我们如果用对象来保存这些信息呢

    {
    姓名:'编程小石头',
    性别:'男'
    体重:128
    身高:180
    }
    

    这样我们是不是就可以立体的知道每个数据代表什么意思了呢。这也是我们使用对象的原因。上面的{}里包裹的就是我们对象的一些属性。只不过我们的属性名不提倡用汉字,应该用英文或者拼音,我这里方便大家理解才这样写的。

    13-3,创建对象的三种方式

    • 利用字面量创建对象
    • 利用new Object创建对象
    • 利用构造函数创建对象

    13-3-1,利用字面量创建对象

    语法如下
    var 对象名={
    属性名:属性值,
    属性名:属性值,
    方法名:function(){}
    }

    示例如下:

    var Person = {
     name:'编程小石头',
     age:18,
     code:function(){console.log('石头哥会写代码')}
    }
    

    13-3-2,利用new Object创建对象

    语法:
    var obj = new Object();
    obj.name=‘编程小石头’
    obj.age=18
    我们这里就是先用 new Object()创建一个空对象,然后通过.属性名给这个空对象添加属性和方法

    13-3-3,利用构造函数创建对象

    构造函数是一种特殊的函数,主要用来初始化对象,它总是和new运算符一起使用,我们可以把对象里的一些公共属性和方法抽取出来,然后封装到这个函数里,方便批量创建对象。

    使用构造函数创建对象时要注意下面几点

    • 1,构造函数名字的首字母习惯大写
    • 2,构造函数里不需要return就可以返回结果
    • 3,调用构造函数创建对象时,必须用new
    • 4,我们的属性和方法前面必须添加this

    完整实例如下:

    	function Person(name, age) {//创建构造函数Person
          this.name = name;
          this.age = age;
          this.action = function (jineng) {
            console.log(name + "具备" + jineng + '的技能')
          }
        }
        //创建对象1
        var obj1 = new Person('编程小石头', 18)
        console.log(obj1.name)//编程小石头
        obj1.action('写代码')//编程小石头具备写代码的技能
         //创建对象2
        var obj2 = new Person('周杰伦', 41)
        console.log(obj2.name)//周杰伦
        obj2.action('唱歌')//周杰伦具备唱歌的技能
    

    构造函数和对象

    我们这里的构造函数就好比汽车的设计图纸,汽车具备哪些属性,拥有哪些方法,已经提前在图纸上设计好了,我们只需要根据图纸new出来一个对象,比如可以new出来一个宝马车,也可以new出来一辆兰博基尼。

    13-3-4,new关键字执行过程

    如上面我们通过构造函数new一个对象

    	function Person(name, age) {//创建构造函数Person
          this.name = name;
          this.age = age;
          this.action = function (jineng) {
            console.log(name + "具备" + jineng + '的技能')
          }
        }
        //创建对象1
        var obj1 = new Person('编程小石头', 18)
    

    这里在new一个对象出来时会执行下面四件事

    • 1,在电脑内存中创建一个空对象
    • 2,让this指向这个新的对象
    • 3,执行构造函数里的代码,给这个新对象添加属性和方法
    • 4,返回这个新对象如上面的obj1就是我们创建的新对象

    13-3-5,变量,属性,函数,方法总结

    属性和变量:

    • 相同点:
      都是用来存储数据的。
    • 不同点:
      变量单独声明并赋值,使用的时候直接使用变量名就可以;
      属性在对象里面的,不需要声明,使用的时候要用:对象.属性名。
    var dog = {
        //属性
        name:'可可',
        age:'12'
    } 
    //变量
    var num = 12;
    
    //调用变量:(直接使用变量名进行调用)
    console.log(num); 
    //调用属性:(对象名.属性名)
    console.log(dog.name);
    

    函数和方法:

    • 相同点:
      都是实现某种功能。
    • 不同点:
      函数是单独声明并且调用的,调用方法:函数名()
      方法存在于对象里面。调用方法:对象名.方法()
    var dog = {
        name:'可可',
        age:'12',
        //方法
        skill:function(){
            console.log('汪汪汪');
        }
    }
     
    //函数
    function skillDemo(){
        console.log("睡觉");
    }
    
    //调用函数:(直接使用:函数名(),进行调用)
    skillDemo();
    //调用方法:(--对象名.方法名()--)
    console.log(dog.skill());
    

    13-4,对象的使用

    13-4-1,访问对象的属性

    对象属性的调用语法有两种

    • 对象名.属性名
    • 对象名[‘属性名’]

    如我们对象如下

    var obj = {
     name:'编程小石头',
     age:18,
     code:function(){console.log('石头哥会写代码')}
    }
    

    调用name属性就是 obj.name
    这里obj就是我们的对象,name就是我们的对象的属性,obj.name里的.就相当于 的 翻译过来就是obj的name
    另外一种调用属性的方式就是 obj[‘name’]

    13-4-2,访问对象的方法

    对象中方法的调用就一种方式:对象名.方法名() 这里的这对小括号是必不可少的。
    如我们对象如下

    var obj = {
     name:'编程小石头',
     age:18,
     code:function(){console.log('石头哥会写代码')}
    }
    

    obj.code() 就是直接调用obj里的code方法

    十四,内置对象的学习

    14-1,什么是内置对象

    内置对象就是指Javascript自带的一些对象,供开发者使用,这些对象提供了一些常用的的功能。开发者可以很方便的使用这些内置对象,而不用关心这些内置对象的实现原理。
    就好比我们使用手机内置的发短信,打电话功能,我们用的时候可以很方便的快速使用,而不用关心打电话的实现原理。这就是我们使用内置对象的原因,主要就是为了快速方便的使用内置对象的

    常见的内置对象有Math、Array、Date等

    14-2,查阅文档的学习

    因为内置对象的方法太多了,我们不可能把所有的方法都记下来,所以我门就需要时不时的查阅文档,就好比我们查字典一样。
    常用的学习文档有下面几个

    • MDN
      官方地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
    • W3cschool
      https://www.w3school.com.cn/js/index.asp
    • 菜鸟教程
      https://www.runoob.com/js/js-tutorial.html

    这里建议大家使用MDN文档。因为这个文档比较全,可以快速检索

    14-3,Math对象的学习

    与其他内置对象不同的是,Math 不是一个构造器对象。Math 的所有属性与方法都是静态的。引用圆周率的写法是 Math.PI,调用正余弦函数的写法是 Math.sin(x),x 是要传入的参数。也就是说我们的Math可以直接通过Math. 来调用他的属性和方法

    由于Math对象的方法比较多,我这里只把开发过程中常用的一些方法做下讲解

    14-3-1,Math常用的属性

    • Math.PI
      圆周率,一个圆的周长和直径之比,约等于 3.14159

    14-3-2,Math常用的方法

    • Math.abs(x) 返回一个数的绝对值
    Math.abs('-1');     // 1
    Math.abs(-2);       // 2
    Math.abs(null);     // 0
    Math.abs("string"); // NaN
    Math.abs();         // NaN
    
    • Math.max() 返回多个数值的最大值
        console.log(Math.max(1, 2, 3)) //3
    
    • Math.min() 返回多个数值的最小值
      console.log(Math.min(1, 2, 3)) //1
    

    14-3-3,Math中取整数的三个方法

    • Math.ceil(x) 向上取整,往大了取
    	console.log(Math.ceil(1.2))//2
        console.log(Math.ceil(1.5))//2
        console.log(Math.ceil(1.7))//2
        console.log(Math.ceil(1.9))//2
    
    • Math.floor(x) 向下取整,往小了取
        console.log(Math.floor(1.2))//1
        console.log(Math.floor(1.5))//1
        console.log(Math.floor(1.7))//1
        console.log(Math.floor(1.9))//1
    
    • Math.round(x) 四舍五入取整
        console.log(Math.round(1.2))//1
        console.log(Math.round(1.5))//2
        console.log(Math.round(1.7))//2
        console.log(Math.round(1.9))//2
    

    14-3-4,随机数的学习

    Math.random() 得到一个大于等于0,小于1之间的随机数
    使用。

    使用场景:一般我们做抽奖时会用到随机数

    • 获取两数之间的随机数(大于等于min小于max)
    //这个随机数可能是整数,也可能是小数
    Math.random() * (max - min) + min
    
    • 得到两数之间的随机整数(大于等于min,小于max)
    // 这个随机数是min和max之间的随机整数
    function getRandomInt(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      //不含最大值,含最小值
      return Math.floor(Math.random() * (max - min)) + min; 
    }
    
    • 得到两数之间的随机整数,包括两个数在内(大于等于min,小于等于max)
    // 这个随机数是min和max之间的随机整数
    function getRandomIntInclusive(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      //含最大值,含最小值 
      return Math.floor(Math.random() * (max - min + 1)) + min; 
    }
    

    14-4,Date日期对象的学习

    我们的Date对象是一个构造函数对象,必须使用new 对象,来创建我们要使用的对象以后才可以使用。

    创建一个新Date对象的唯一方法是通过new 操作符,
    例如:let now = new Date()

    使用场景 比如我们的秒杀倒计时,显示的日期都需要借助Date日期对象

    14-4-1,创建Date对象

    有 4 种方法创建新的日期对象:

    new Date()
    new Date(year, month, day, hours, minutes, seconds, milliseconds)
    new Date(dateString)
    new Date(milliseconds)
    
    • new Date()创建Date对象
        var d = new Date()
        console.log(d)//Mon Dec 21 2020 20:02:54 GMT+0800 (中国标准时间)
    

    这样直接创建的返回的是当前的时间如上面的注释所示,我当前是2020年12月21日20时02分54,你打印的应该是你当前自己的时间。

    • new Date(year, month, …)
      new Date(year, month, …) 用指定日期和时间创建新的日期对象。
      7个数字分别指定年、月、日、小时、分钟、秒和毫秒(按此顺序):
    var d = new Date(2018, 11, 24, 10, 33, 30, 0);
    console.log(d) //Mon Dec 24 2018 10:33:30 GMT+0800 (中国标准时间)
    

    这里有一点需要注意:JavaScript 从 0 到 11 计算月份。一月是 0。十二月是11。
    4个数字指定年、月、日和小时:

    var d = new Date(2018, 11, 24, 10);
    

    3 个数字指定年、月和日:

    var d = new Date(2018, 11, 24);
    
    • new Date(dateString)
      new Date(dateString) 从日期字符串创建一个新的日期对象
      我们可以通过 年-月-日 或者年/月/日 获取Date对象
    //如我们用两种方式来创建2020年12月21日
        var d1 = new Date(2020,11,21);//月份是从0开始的 11代表12月
        console.log(d1) //Mon Dec 21 2020 00:00:00 GMT+0800 (中国标准时间)
        var d2 = new Date('2020-12-21');
        console.log(d2) //Mon Dec 21 2020 08:00:00 GMT+0800 (中国标准时间)
         var d3 = new Date('2020/12/21');
        console.log(d3) //Mon Dec 21 2020 08:00:00 GMT+0800 (中国标准时间)
    
    • new Date(milliseconds)
      new Date(milliseconds) 创建一个零时加毫秒的新日期对象
      JavaScript 将日期存储为自 1970 年 1 月 1 日 00:00:00 UTC(协调世界时)以来的毫秒数。
      零时间是 1970 年 1 月 1 日 00:00:00 UTC。
      现在的时间是:1970 年 1 月 1 日之后的 1608553621233毫秒
      如下
        var d1 = new Date(0);
        console.log(d1) //Thu Jan 01 1970 08:00:00 GMT+0800 (中国标准时间)
    

    r如果我们想获取当前时间距离1970 年 1 月 1 日之间的毫秒值可以

        var d1 = new Date();
        console.log(d1.getTime()) //1608553621233
        var d2 = new Date();
        console.log(d2) //Mon Dec 21 2020 20:27:01 GMT+0800 (中国标准时间)
    

    可以看出当前时间距离1970 年 1 月 1 日之间的毫秒值是1608553621233
    那么我们直接new Date(1608553621233)获取的日期如下

        var d1 = new Date(1608553621233);
        console.log(d1) //Mon Dec 21 2020 20:27:01 GMT+0800 (中国标准时间)
    

    所以当前的日期和通过new Date(当前日期距离1970年1月1日的毫秒值)都可以获取当前时间。两者可以相互转换。

    14-4-2,日期获取方法

    获取方法用于获取日期的某个部分(来自日期对象的信息)。下面是最常用的方法

    方法描述
    getDate()以数值返回天(1-31)
    getDay()以数值获取周名(0-6)
    getFullYear()获取四位的年(yyyy)
    getHours()获取小时(0-23)
    getMilliseconds()获取毫秒(0-999)
    getMinutes()获取分(0-59)
    getMonth()获取月(0-11)
    getSeconds()获取秒(0-59)
    getTime()获取时间(从 1970 年 1 月 1 日至今)

    14-4-3,日期设置方法

    设置方法用于设置日期的某个部分

    方法描述
    setDate()以数值(1-31)设置日
    setFullYear()设置年(可选月和日)
    setHours()设置小时(0-23)
    setMilliseconds()设置毫秒(0-999)
    setMinutes()设置分(0-59)
    setMonth()设置月(0-11)
    setSeconds()设置秒(0-59)
    setTime()设置时间(从 1970 年 1 月 1 日至今的毫秒数)

    14-4-4,倒计时(综合案例)

    我们这里带大家实现一个倒计时的案例,比如我们知道一个活动结束的时间,然后去计算活动还有多久结束。我会在视频里带着大家写一个综合的案例。大家跟着视频课来学习这个综合案例即可。

    14-5,Array数组对象的学习

    数组对象的作用是:使用单独的变量名来存储一系列的值。
    如我之前学习数组时,数组的一种创建方式

    var mycars = new Array();
    mycars[0] = "Saab";
    mycars[1] = "Volvo";
    mycars[2] = "BMW";
    

    14-5-1,判断是不是数组

    判断一个对象是不是数组有两种方式

    • 1,通过instanceof Array
    • 2,通过Array.isArray()方法
        var arr = new Array()
        console.log(arr instanceof Array) //true
        console.log(Array.isArray(arr))//true
    

    14-5-2,添加和删除数组元素

    其实我们在讲解数组的那一节有教大家如何添加和删除数组,今天再来带大家系统的来学习下数组的添加和删除

    • push方法添加
      在数组的末尾添加一个或者多个元素
    • unshift方法添加
      在数组的开头添加一个或者多个元素
    • pop方法删除
      删除数组尾部的元素,一次只能删除一个
    • shift方法删除
      删除数组最前面(头部)的元素

    14-5-3,配套练习(筛选数组)

    给你一组数据 [20,59,40,80,99,98] 筛选出所有小于60的数组,可以理解为找到所有不及格的学生的成绩,你会怎么做呢? 可以结合我们上面学过的知识,自己思考下。我会在视频里带着你写一遍。看视频之前,建议你自己先思考下。

    14-5-4,reverse方法翻转数组

    reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。

        var arr = [1, 2, 3, 4, 5]
        console.log(arr.reverse())//[5, 4, 3, 2, 1]
    

    14-5-5,sort方法对数组进行排序

    用sort方法进行排序,默认是升序排列的,如下

       var arr = [1, 3, 2, 5, 4]
       console.log(arr.sort())//[1, 2, 3, 4, 5]
    

    但是直接用sort方法会有问题

        var arr = [11, 3, 22, 55, 44]
        console.log(arr.sort())//[11, 22, 3, 44, 55]
    

    为什么会出现3在11和22后面的问题呢,因为我们sort默认排序顺序是在将元素转换为字符串,然后对字符串进行比较,再排序的,所以我们要想用sort来排序,就要用到另外一个写法了

        var arr = [11, 3, 22, 55, 44]
        //按照升序排序
        arr.sort(function (a, b) {
          return a - b
        })
        //按照降序排序
        arr.sort(function (a, b) {
          return b - a
        })
    

    上面的 写法是固定的,大家只需要记住就行了。 a-b时是升序,b-a时是降序

    function (a, b) {
          return a - b 
    }
    

    14-5-6,数组的索引方法

    • indexOf()方法
      返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
    • lastIndexOf() 方法
      返回指定元素在数组中的最后一个的索引,如果不存在则返回 -1

    14-5-7,课程作业,对数组进行去重

    给出一个数组 [1,3,5,2,4,5,6,4],现要求把数组里重复的元素给删除掉,我会在视频里带着大家写一遍,在看视频之前,建议大家先自己仔细思考下,最好自己先实现一下。

    14-5-7,把数组转换为字符串

    我们把数组转换为字符串有下面两种方法

    • toString()
      将数组通过逗号连接成一个字符串。
    • join(分隔符)
      将数组通过分隔符连接成一个字符串。join里分隔符如果不写的话,默认用逗号来连接数组元素组成一个字符串
        var arr = [1, 3, 2, 5, 4]
        console.log(arr.toString())//1,3,2,5,4
        console.log(arr.join('-'))//1-3-2-5-4
    

    这里希望大家重点掌握,因为我们实际开发中,会把数组转换为字符串传给后台开发人员。

    14-5-8,数组的其他常用方法

    • concat() 方法
      用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组
    • slice() 方法
      截取数组的一部分返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变
    • splice() 方法
      通过删除或替换现有元素或者原地添加新的元素来修改或者删除数组
      splice(从第几个开始,删除几个)
        var arr = [1, 2, 3, 4, 5]
        arr.splice(0, 2)// 从索引为0的地方开始,删除2个元素。
        console.log(arr) //[3, 4, 5]
    
    • splice(从第几个开始,替换几个,要替换的值)
        var arr = ['a', 'b', 'c', 'd', 'e']
        arr.splice(0, 2,'A','B')// 从索引为0的地方开始,替换2个元素,替换为 A和B
        console.log(arr) //["A", "B", "c", "d", "e"]
    

    十五,wxss和css样式美化

    我们上面基本上都是在学习JavaScript基础,js在小程序里主要是用来处理逻辑的,从今天开始我们就来学习一些样式相关的知识,用来美化我们的小程序。其实我们小程序三剑客里的wxss和我们的css是一样的。所以我接下来会把一些常用的css知识点给大家讲解一下。还有小程序里特有的一些样式知识也做下重点讲解。

    一些特别基础的css知识可能不会讲太多。
    这里把一些css的文档给大家一个,大家抽个几小时可以快速的学习下css基础,css不要求大家学习时全部记住,只需要大致知道相应的知识点,后面学习时会回来快速的查阅就行。

    • 菜鸟教程:https://www.runoob.com/css/css-tutorial.html
    • w3cshool教程:https://www.w3school.com.cn/css/index.asp

    15-1,css基础语法

    CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明:

    在我们小程序的代码里就体现如下

    • 1,在wxml里定义一个class选择器
    • 2,在wxss实现css样式

      我们这里主要给title选择器实现红色背景,黄色字体。效果如下

      可以看出我们css主要是实现页面美化用的,所以你如果想让你的小程序变得美丽漂亮,就要好好学习css样式了。

    15-2,CSS 注释

    注释是用来解释你的代码,并且可以随意编辑它,浏览器会忽略它。
    CSS注释以 /* 开始, 以 */ 结束, 实例如下:

    /*这是个注释*/
    .title{
        text-align:center;
        /*这是另一个注释*/
        color:black;
        font-family:arial;
    }
    

    15-3,Id 和 Class选择器

    • id 选择器以 “#” 来定义。
      下面的两个 id 选择器,第一个可以定义元素的颜色为红色,第二个定义元素的颜色为绿色:
    #red {
    	color:red;
    }
    #green {
    	color:green;
    }
    
    • class 选择器
      class 选择器用于描述一组元素的样式,class 选择器有别于id选择器,class可以在多个元素中使用,类选择器以一个点"."号显示
    .red {
    	color:red;
    }
    .green {
    	color:green;
    }
    

    我们小程序的css中用的最多的就是id和class选择器。

    15-4,CSS 背景

    CSS 属性定义背景效果常用的方式:

    • background-color(最常用)
      background-color 属性定义了元素的背景颜色.如:
      .title {background-color:red;} 就是设置类选择器title的背景颜色为红色

    我们上面的 background-color也可以简写为 background,如:
    .title {background-color:red;} 也是设置背景为红色

    15-5,css中颜色设置的三种方式

    CSS中,颜色值通常以以下方式定义:

    • 十六进制 - 如:"#ff0000"
    • RGB - 如:“rgb(255,0,0)”
    • 颜色名称 - 如:“red”

    我这里给大家提供一个颜色表,大家可以拿到自己喜欢颜色的十六进制值。
    https://tool.oschina.net/commons?type=3
    如果这个连接失效了,大家自己百度下“颜色对照表”也可以找到类似的。

    部分截图如下。

    15-6,文本常用样式

    15-6-1,文本的对齐方式

    文本排列属性是用来设置文本的水平对齐方式。
    文本可居中或对齐到左或右,两端对齐

    • text-align: center; 文本居中对齐
    • text-align: left; 文本居左对齐
    • text-align: right; 文本居右对齐

    15-6-2,文本修饰

    text-decoration 属性用来设置或删除文本的装饰

    • text-decoration: overline; 上划线
    • text-decoration: line-through; 中间划线
    • text-decoration:underline; 下划线

    15-6-3,color设置文本颜色

    如下所示,设置字体颜色为红色的三种方式

    /* 英文颜色 */
    .title {
      color: red;
    }
    /* rgb设置颜色 */
    .title {
      color: rgb(255, 0, 0);
    }
    /* 十六进制设置颜色 */
    .title {
      color: #FF0000;
    }
    


    这些颜色值,可以在我前面给到大家的颜色对照表里找到。

    15-6-4,font-size 设置字体大小

    font-size可以用来设置字体的大小

    • 不写这个属性有默认大小
    • font-size: 30px;
    • font-size: 50px;

      当然我们的文本还有好多别的样式,这里我们只讲这几个重点的,其余的大家可以自己去看下 https://www.runoob.com/css/css-text.html

    15-7,css边框和边距

    元素框的最内部分是实际的内容,直接包围内容的是内边距。内边距呈现了元素的背景。内边距的边缘是边框。边框以外是外边距,外边距默认是透明的,因此不会遮挡其后的任何元素。

    我这里画一个图,方便大家理解margin,padding,border。其实我们装手机的快递盒子有点类似。

    15-7-1,padding 内边距

    元素的内边距在边框和内容区之间。控制该区域最简单的属性是 padding 属性。padding 属性定义元素边框与元素内容之间的空白区域。padding 属性接受像素值或百分比值,但不允许使用负值

    • padding: 10px;
      如果只设置一个值,那么上下左右都是10px
    • padding: 10px 20px 30px 40px;
      按照上、右、下、左的顺序分别设置各边的内边距。这样设置就是内边距的上间距10px,右间距20px,下边距30px,左边距40px
    • 也通过使用下面四个单独的属性,分别设置上、右、下、左内边距:
      padding-top
      padding-right
      padding-bottom
      padding-left

    15-7-2,border边框

    元素的边框 (border) 是围绕元素内容和内边距的一条或多条线。
    CSS border 属性允许你规定元素边框的样式、宽度和颜色。
    如下面几种边框

    每个边框有 3 个方面:样式,宽度、以及颜色

    • border-style可以来设置样式

      我们通过设置border-style来定义上下左右四个边框样式,当让也可以定义单边样式,如果您希望为元素框的某一个边设置边框样式,而不是设置所有 4 个边的边框样式,可以使用下面的单边边框样式属性:
      border-top-style
      border-right-style
      border-bottom-style
      border-left-style

    • border-width设置边框的宽度
      您可以通过 border-width 属性为边框指定宽度。
      同样border-width: 5px;只有一个值的时候是设置上下左右4个边框的宽度。
      您也可以通过下列属性分别设置边框各边的宽度:
      border-top-width
      border-right-width
      border-bottom-width
      border-left-width

    • border-color设置边框的颜色
      您可以通过border-color 属性为边框指定颜色。
      同样border-color只有一个值的时候是设置上下左右4个边框的颜色。
      您也可以通过下列属性分别设置边框各边的颜色:
      border-top-color
      border-right-color
      border-bottom-color
      border-left-color

    • 当然我们我们的边框宽度,样式,颜色有一种简写方式

    .title{
      border:5px solid red;
    }
    

    我们只需要一个border属性,就可以设置上下左右四个边框的宽度为5px,样式为solid,颜色为red。

    15-7-3,margin外边距

    围绕在元素边框的空白区域是外边距。设置外边距会在元素外创建额外的“空白”。margin 没有背景颜色,是完全透明的
    设置外边距的最简单的方法就是使用 margin 属性,这个属性接受任何长度单位、百分数值甚至负值

    • Margin - 单边外边距属性
      在CSS中,它可以指定不同的侧面不同的边距:
      实例
      margin-top:100px;
      margin-bottom:100px;
      margin-right:50px;
      margin-left:50px;

    margin属性可以有一到四个值。

    • margin:25px 50px 75px 100px;
      上边距为25px
      右边距为50px
      下边距为75px
      左边距为100px
    • margin:25px 50px 75px;
      上边距为25px
      左右边距为50px
      下边距为75px
    • margin:25px 50px;
      上下边距为25px
      左右边距为50px
    • margin:25px;
      所有的4个边距都是25px

    15-8,border-radius设置圆角边框

    border-radius 主要是用来设置圆角用的,下面我通过几个常用的例子来给大家讲解下这个知识点

    • 1,直接可以用像素设置圆角大小
    .title {
      background: red;
      /* 可以用像素设置圆角 */
      border-radius: 10px;
    }
    

    • 2,如果有宽高值,可以设置border-radius为宽高的一半实现圆形
    .title {
      background: red;
      width: 200px;
      height: 200px;
      border-radius: 100px;
    }
    


    当有宽高的时候,设置 border-radius为50%同样可以实现上面的圆形功能。

    .title {
      background: red;
      width: 200px;
      height: 200px;
      border-radius: 50%;
    }
    

    15-9,综合案例一(画个月牙)

    比如我们想实现一个红色的半月,如下图

    那我们该怎么实现这个月牙呢。

    • 1,在wxml里定义两个view组件,并且设置好class类名
    • 2,然后再wxss里设置对应的css样式,用到我们前面学的border-radius

      可以看出来,我们就是用了border-radius实现了一个红色的圆形和一个白色的圆形,白色的圆形遮住了一部分红色的大圆,这样就实现了一个红色的月牙。

    15-10,综合案例二(写个搜索框)

    我们在小程序里经常见到下面所示的搜索框,其实这个搜索框实现起来很简单,把我们上面学的知识点都用到了,所以我们接下来用这么一个综合案例带大家熟悉下之前的知识点。

    首先我们要在wxml里定义如下布局

    布局其实很简单,就是一个父view里套一个子view。
    然后就是在wxss里定义样式就可以了

    其实到这里就已经可以轻松实现我们上面想要的效果了。

    建议大家先跟着写写看。我下面把wxss代码贴出来给大家。

    .root {
      height: 65rpx;
      background: #FFB965;
      padding: 10rpx;
    }
    
    .input {
      height: 100%;
      text-align: center;
      color: grey;
      background: white;
      border-radius: 15rpx;
    }
    

    15-11,px和rpx的转换

    我们在设置宽度,高度,边框粗细时都会用到尺寸单位,我们这里重点给大家讲解下px和rpx。rpx是微信为小程序专门设计的一个尺寸单位。
    px和rpx的换算如下:

    我们一般设计规范都是依据iPhone6来设计的,也就是说平常ui设计师给出的1px我们在写代码时要写0.5rpx。

    下面给出一个简单的例子

    上面红色小石头的字体设置了100px,黑色小石头设置了200rpx,这个时候我们可以看出,红色和黑色小石头的大小是一样的。所以我们后面开发小程序里建议大家用rpx作为小程序的尺寸单位,这样能很好的做自适应。如果我们的设计小姐姐给的是px单位的设计图,我们就要自己用px除以2得到我们对应的rpx大小。

    十六,多媒体组件的学习(图片和视频)

    16-1,认识图片image组件

    image组件:主要用来显示图片,可以是本地图片,也可以是网络图片。

    官方学习文档:https://developers.weixin.qq.com/miniprogram/dev/component/image.html

    当我们不给image设置宽高时,image组件的默认宽度是320px,高度240px。

    16-1-1,src属性显示网络图片

    我们通过src属性来设置要显示的图片资源,图片资源有两种

    • 本地图片资源
    • 网络图片资源

    由于我们本地的图片会占用小程序软件包的大小,所以这里推荐大家尽量使用网络图片。

    我们设置显示图片的语法如下

    <image src="图片资源地址"></image>
    

    如下图,我们显示一个网络图片。

    这里给大家两个网络图片地址:
    https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg

    https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2273029747,2912173232&fm=15&gp=0.jpg

    16-1-2,src属性显示本地图片

    用image显示本地图片,我们需要提前把图片放在小程序项目里,如下图我们把本地图片放在images目录里,这个images目录需要我们自己新建。

    然后在image组件里设置src属性,指向这个本地图片,就可以在小程序里展示了。
    我把网络图片和本地图片都在小程序里展示,给大家对比着学习下。

    16-1-3,通过mode设置图片裁剪、缩放的模式

    image组件另外一个比较重要的属性就是mode了。我们在使用图片时,不能百分之百保证图片的比例正好是我们想要的,这个时候就要用到图片的裁剪和缩放了。
    mode 的常用设置如下

    说明
    scaleToFill缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
    aspectFit缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
    aspectFill缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
    widthFix缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
    heightFix缩放模式,高度不变,宽度自动变化,保持原图宽高比不变 2.10.3
    top裁剪模式,不缩放图片,只显示图片的顶部区域
    bottom裁剪模式,不缩放图片,只显示图片的底部区域
    center裁剪模式,不缩放图片,只显示图片的中间区域
    left裁剪模式,不缩放图片,只显示图片的左边区域
    right裁剪模式,不缩放图片,只显示图片的右边区域
    top left裁剪模式,不缩放图片,只显示图片的左上边区域
    top right裁剪模式,不缩放图片,只显示图片的右上边区域
    bottom left裁剪模式,不缩放图片,只显示图片的左下边区域
    bottom right裁剪模式,不缩放图片,只显示图片的右下边区域

    比如我们有一个原图如下。

    设置不同的mode值,可以很明显的看出来区别

    后面我们需要对图片做裁剪或者伸缩处理时,就可以设置不同的mode值来实现不同的效果。

    16-1-4,图片懒加载

    小程序里image组件是支持图片懒加载的,当我们一个列表页有很多图片时,我们可以使用懒加载,来加快页面加载速度。使用懒加载时,我们只需要给image设置lazy-load就可以了。

    16-2,认识视频video组件

    video组件:主要用来实现视频播放。

    官方学习文档:https://developers.weixin.qq.com/miniprogram/dev/component/video.html

    16-2-1,src属性设置视频地址


    video组件里也是通过src属性来设置视频资源的。这里的视频资源都是网络连接。

    我把这几个mp4格式的视频链接贴给大家

    http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4
    
    https://media.w3.org/2010/05/sintel/trailer.mp4
    
    http://vjs.zencdn.net/v/oceans.mp4
    

    如果上面链接失效,我们可以去官方文档拿官方的视频链接

    16-2-2,设置视频弹幕属性来显示弹幕

    我们上面设置src只能保证视频的正常播放,如果我们想使用弹幕功能,就要为video设置别的属性了。

    我们如果想在视频上显示弹幕,就要设置danmu-list属性。可以看出danmu-list属性是一个数组,而这个数组就要放置我们弹幕的一些数据了。

    下面我在代码里给大家简单的演示下弹幕的显示。
    首先在wxml里设置danmu-list属性,并且给danmu-list绑定数据danmuList

    而这个danmuList就要在js里设置了。

    我们可以在danmuList的每个弹幕对象里设置弹幕显示的内容,弹幕的颜色,弹幕显示的时间。

    通过上图可以看到,我们设置的弹幕成功的显示在了视频上。这样我们就可以轻松的实现弹幕展示功能了。

    16-2-3,发送弹幕功能

    我们上面只是简单的展示了弹幕,如果我们想让用户发送弹幕该怎么做呢。下面就来教大家实现弹幕的发送功能。
    简单起见,我这里设置一个input来获取用户输入的内容,用一个button按钮来触发弹幕的发送。

    wxml文件如下:

    这里我们特意设置了一个id属性,我们下面发送弹幕时,需要先初始化一个视频对象,而初始化视频对象时就用到了这个id。

    js文件如下:

    可以看出,我们在onReady页面渲染完成时,初始化了一个视频对象videoContext,然后通过bindInput获取用户输入的弹幕内容。最后在点击发送弹幕按钮时,通过videoContext.sendDanmu来发送弹幕到视频的屏幕上。

    到这里,我们发送弹幕的功能也实现了,当然video视频组件还有很多别的属性,这里就不再一个个介绍了。大家可以自己去看官方文档:
    https://developers.weixin.qq.com/miniprogram/dev/component/video.html

    十七,授权登录退出和缓存

    我们的项目开发多多少少的都会用到用户的一些信息,比如头像,昵称,性别等。而这些信息的获取,小程序也为我们提供好了方法。

    17-1,认识wx.getUserProfile方法


    对应的文档:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserProfile.html

    使用这个方法可以获取如下的用户信息

    17-2,授权弹窗

    一般我的使用上面的wx.getUserProfile方法获取用户信息时,需要用户授权的。一般授权弹窗如下。

    只有用户点击允许以后才可以获取用户信息。

    不弹起授权弹窗解决方案

    有的同学用这个方法时,不会弹起上面的弹窗,有可能是因为基础库版本太低,这里建议升级到最新版的基础库。

    17-3,授权登录核心代码

    等下视频课程里会带着大家一起敲代码,这里先把一些核心代码贴出来。其实核心代码官方文档里有提供的。

    这里为了方便日后大家使用,我贴出来给到大家。这里要注意 desc必须保留,里面的描述尽量写的规范些。因为

        wx.getUserProfile({
          desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
          success: (res) => {
          }
        })
    

    17-4,顶部圆形头像和昵称


    其实这里倒是挺简单,重点知识只有一个圆形图片的实现这里只需要一个image组件和一个text组件即可。通过css的border-radius就可以来设置圆形图像了,我小程序基础里也有讲过的,核心代码如下。

    17-5,本地缓存的讲解

    17-5-1,使用wx.setStorageSync缓存

    这里缓存我们主要用到了wx.setStorageSync 对应的官方文档:
    https://developers.weixin.qq.com/miniprogram/dev/api/storage/wx.setStorageSync.html

    17-5-2,缓存数据的查看

    如下图所示,就是我们的本地缓存数据

    17-5-3,使用wx.getStorageSync获取缓存


    对应的官方文档:https://developers.weixin.qq.com/miniprogram/dev/api/storage/wx.getStorageSync.html

    17-6,退出登录的编写

    退出登录其实很简单,就实现一个点击事件就可以了

    然后js里具体代码就下面这几行就够了

    17-7,完整的项目代码

    我这里把wxml和js的完整代码贴出来给到大家
    index.wxml

    <button wx:if="{{!userInfo}}" bindtap="login">授权登录</button>
    <view wx:else class="root">
      <image class="touxiang" src="{{userInfo.avatarUrl}}"></image>
      <text class="nicheng">{{userInfo.nickName}}</text>
      <button bindtap="loginOut">退出登录</button>
    </view>
    

    index.js

    Page({
      data: {
        userInfo: ''
      },
      onLoad() {
        let user = wx.getStorageSync('user')
        console.log('进入小程序的index页面获取缓存', user)
        this.setData({
          userInfo: user
        })
      },
      // 授权登录
      login() {
        wx.getUserProfile({
          desc: '必须授权才可以继续使用',
          success: res => {
            let user = res.userInfo
            // 把用户信息缓存到本地
            wx.setStorageSync('user', user)
            console.log("用户信息", user)
            this.setData({
              userInfo: user
            })
          },
          fail: res => {
            console.log('授权失败', res)
          }
        })
      },
      // 退出登录
      loginOut() {
        this.setData({
          userInfo: ''
        })
        wx.setStorageSync('user', null)
      }
    })
    

    index.wxss

    .root {
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    
    .touxiang {
      width: 200rpx;
      height: 200rpx;
      border-radius: 50%;
      margin-top: 30rpx;
      margin-bottom: 10rpx;
    }
    

    我会在视频里带大家做具体代码的编写。
    《小程序入门》

    十八,swiper轮播图组件

    18-1,swiper组件

    我们在小程序里实现顶部轮播图来动态的显示一些热门商品,这个时候就要用到swiper组件了。

    官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html

    如下图,就是我们传说中的顶部轮播图。

    给大家看下官方swiper简介

    可以看出我们的swiper必须结合swiper-item来使用。

    18-2,swiper-item组件

    我们的swiper-item就是用来装每个轮播图使用的。下面我写一个简单的例子来看下

    我这里先在swiper里放三个swiper-item,给每个swiper-item设置不同的背景颜色。这个时候我们就可以实现这三个swiper-item的来回滑动切换。但是我们通常开发的时候,肯定不是仅仅显示一个颜色,我们应该在里面放置图片。要不然怎么叫轮播图呢。

    18-3,swiper-item组件里显示轮播图

    我们如果想在swiper-item里显示图片,就要借助我们前面学习的image组件了。如下图所示

    这样我们就可以完整的实现一个轮播图组件了。我把完整的代码贴出来给到大家。

    <swiper indicator-dots>
      <swiper-item>
        <image src="https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg" />
      </swiper-item>
      <swiper-item>
        <image src="https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1819216937,2118754409&fm=26&gp=0.jpg" />
      </swiper-item>
      <swiper-item>
        <image src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2273029747,2912173232&fm=15&gp=0.jpg" />
      </swiper-item>
    </swiper>
    

    18-4,swiper的常用属性。

    可以看出我们的swiper有很多属性,下面我会重点的把我们一些常用的属性,通过视频里的一个综合案例来给大家讲解下。

    还是来看官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html

    十九,通过tabBar设置多页面

    我们正常创建的默认项目是一个单页面,我们要想实现下面效果所示的多页面就要借助tabBar来实现多页面。

    官方文档:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#%E9%85%8D%E7%BD%AE%E9%A1%B9


    一个小程序可以配置2-5个多页面,

    我们这里以创建3个页面来给大家做下讲解。

    19-1,创建image目录放图标

    我们要使用tabBar就需要用到图标,所以我们要创建一个放图标的目录。

    然后把我提前给大家准备好的图标放到image里即可。

    这些图标我会在配套学习资料里给到大家。

    19-2,创建多个页面

    关于小程序里页面的快速创建我小程序基础里讲过很多遍了,这里就不再啰嗦,直接在app.json里创建下面三个页面即可

    19-3,设置tabBar实现多页面布局

    上面三个页面创建好以后,我们就可以通过tabBar来设置多页面布局了。
    在app.json里添加如下配置。

    这样我们就可以实现可以自由切换的多页面小程序了。

    到这里我们的多页面项目就创建好了。

    19-4,设置tabbar的代码

    由于这里的tabbar配置基本上是固定的,我这里把代码贴在笔记里,大家以后用到的时候,只需要把笔记里的这段代码拿过去就可以,里面的配置稍微改下既可以。

    "tabBar": {
        "color": "#Fc0",
        "selectedColor": "#f4c903",
        "borderStyle": "white",
        "list": [{
            "selectedIconPath": "image/tab1-ok.png",
            "iconPath": "image/tab1.png",
            "pagePath": "pages/home/home",
            "text": "首页"
          },
          {
            "selectedIconPath": "image/tab2-ok.png",
            "iconPath": "image/tab2.png",
            "pagePath": "pages/me/me",
            "text": "我的"
          }
        ]
      },
    

    二十,navigator页面跳转

    我们在小程序里做页面跳转有两种方式

    • 1,借助navigator组件
    • 2,借助wx.自带方法,在点击的时候做页面跳转
      如下图所示的几个wx.方法

      官方给出的几种跳转方式的解释如下

    20-1,navigator实现页面跳转

    navigator其实和我们html里的a标签有点像,也是为了实现页面跳转的。
    官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html

    我们想用navigator来跳转到别的页面,其实很简单,只需要如上图所示,做简单配置即可。
    当然了我们使用navigator来跳转页面时,分下面几种情况。当然这些跳转方式都是通过配置open-type属性来定义的。

    20-2,页面的跳转方式

    下面我把一些常用的open-type属性列出来给大家,方便大家以后使用。

    open-type值说明对应wx方法
    navigate保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面对应wx.navigateTo
    redirect关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面对应 wx.redirectTo
    switchTab跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面对应 wx.switchTab
    reLaunch关闭所有页面,打开到应用内的某个页面对应 wx.reLaunch
    navigateBack关闭当前页面,返回上一页面或多级页面对应 wx.navigateBack
    exit退出小程序,target="miniProgram"时生效

    如我们使用navigate做页面跳转,只写个url属性,open-type的值默认就是navigate

    这样我们跳转到新页面后,会有一个返回按钮。我们可以通过这个返回按钮返回上一个页面。

    我会在视频里为大家一个个演示其余的方法和功能。

    20-3,点击事件结合wx方法实现跳转

    我们做页面跳转除了使用navigate组件外,还可以通过点击事件借助wx方法实现页面跳转。

    常用的wx方法:

    wx方法说明
    wx.navigateTo保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面
    wx.redirectTo关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
    wx.switchTab跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
    wx.reLaunch关闭所有页面,打开到应用内的某个页面
    wx.navigateBack关闭当前页面,返回上一页面或多级页面

    我这里给大家举个简单的例子

    • 在wxml里设置点击事件
    • 然后再js里设置点击后跳转页面

      这样我们就可以实现页面跳转了,和使用navigate做跳转一样的效果。
      其余的几个wx跳转方法,我也会在视频里给大家做演示。

    20-4,通过switchTab跳转tabbar页面如何携带数据

    我们跳转到tabbar页面是无法直接通过url携带数据,所以我们就要通过别的方式来实现页面跳转时的数据传递,所以这时候可以有两个方式。具体代码我在视频里带大家写一遍。

    20-4-1,通过app.js里的globalData

    其实就是通过app.js里的全局变量来传递。

    20-4-2,通过本地缓存

    其实就是在A页面存数据到缓存,然后A页面跳转到B页面时通过取本地缓存来拿到数据,进而实现页面跳转传递参数的功能。

    20-5,打开别的小程序

    其实我们可以在自己的小程序里通过navigateTo打开别的小程序的,只不过有自己特定的方法:wx.navigateToMiniProgram
    对应的官方文档:https://developers.weixin.qq.com/miniprogram/dev/api/navigate/wx.navigateToMiniProgram.html

    其实我们只需要拿到别的小程序的appid就可以实现这个功能了,我会在视频里演示怎么拿到别的小程序的appid

    二十一,小程序页面生命周期

    什么是生命周期

    https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page-life-cycle.html
    这是官方给出的页面生命周期解释,如下图

    作为初学者,一开始不一定能看懂,所以我给大家总结成下面所示的。方便大家学习。其实生命周期就是一个小程序页面从创建到销毁的一个时间周期。

    官方文档

    https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html
    这是官方给出的解释,感兴趣的同学可以自己看看,我会在视频里把常用的生命周期方法给大家做具体的讲解。

    二十二,小程序应用生命周期

    官方文档

    https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html

    这里最常用的就是下面3个

    onLaunch()

    小程序初始化完成时触发,全局只触发一次。

    onShow()

    小程序启动,或从后台进入前台显示时触发

    onHide()

    小程序从前台进入后台时触发

    二十三,scrollview讲解

    23-1,认识scrollview

    首先要去看下官方文档
    https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html

    我会在课程里把一些常用的属性带大家认识一遍。

    23-2,快速创建100个view快捷方式

    先教大家一个在wxml页面里快速创建100行view代码的快捷方式
    输入 view{$}*100 然后回车键,就可以在页面里快速创建100行view了。

    23-3,设置列表条目隔行不同颜色

    效果图如下:

    其实这是借助我们css的 :nth-child知识点,如上图所示:nth-child(2n)就是设置偶数行,:nth-child(1n)就是设置奇数行。

    23-4,一键置顶,回到列表页面顶部

    主要是借助scroll-view的scroll-top属性,我会在视频里手把手的教大家实现这个功能的

    23-5,让列表里的任意位置滚动到顶部

    主要是借助scroll-view的scroll-into-view属性,我会在视频里手把手的教大家实现这个功能的

    注意事项:如上图所示,我们需要给每个条目设置一个id,并且这个id不能是数字开头。

    对应的js代码如下:

    二十四,注册小程序

    我们前面虽然可以用测试号创建小程序,但是测试号有很多功能会受限,比如我们接下来要讲的云开发,必须是注册小程序后才可以使用,所以今天我们就来讲讲小程序的注册.

    24-1,其实官方给的注册步骤很详细了


    官方注册文档:https://developers.weixin.qq.com/miniprogram/introduction/

    微信小程序注册地址:https://mp.weixin.qq.com/
    进去以后点击立即注册

    进入注册页面时,跟着提示一步步来就可以了

    24-2, 注意点

    • 如果只是学习的话,注册个人小程序即可.
    • 如果想商用,想使用微信支付,取用户手机号等复杂功能,可以注册企业小程序,不过企业小程序必须有营业执照才可以注册
    • 一个邮箱只能注册一个小程序
    • 一个身份证可以注册5个,个人小程序
    • 一个企业的营业执照可以注册50个企业小程序

    持续更新中,敬请关注。。。

    小程序入门系列(其他教程)

    1,零基础入门小程序

    https://xiaoshitou.blog.csdn.net/article/details/107557972

    2,零基础入门小程序云开发(数据后台)

    https://xiaoshitou.blog.csdn.net/article/details/112391688

    3,云开发+cms实现扫码点餐小程序

    https://xiaoshitou.blog.csdn.net/article/details/113717509

    展开全文
  • 小程序与云开发实战 36 讲

    万次阅读 多人点赞 2018-11-06 11:49:05
    小程序依托微信超过 10 亿的海量用户,它无需安装即可使用的完美用户体验,已经成为商家竞相争夺的大蛋糕,同时,小程序开发快速、容易部署广受程序员的喜爱,作为程序员的我们,还有什么理由不学习小程序开发呢?...

    课程介绍

    小程序依托微信超过 10 亿的海量用户,它无需安装即可使用的完美用户体验,已经成为商家竞相争夺的大蛋糕,同时,小程序开发快速、容易部署广受程序员的喜爱,作为程序员的我们,还有什么理由不学习小程序开发呢?

    本达人课为小程序以及云开发快速入门课程,主要分为 6 部分内容。

    • 入门部分:这部分内容结合着小实例来讲解小程序的开发环境搭建以及开发的基本步骤,然后介绍了小程序中常用的布局,如水平排列和垂直排列布局等。

    • 组件部分:主要介绍了小程序开发中常用的组件,如 text 组件、icon 组件、进度、滚动视图、轮询图、各种表单组件、多媒体组件。

    • API 部分:主要介绍了小程序开发中常用到的 API,如网络 API、多媒体 API、数据存储 API、位置 API、界面 API 和开发接口 API。

    • WeUI 部分:主要介绍了 WeUI 高级 UI 组件的核心使用方法,包括基础组件和 Badge 的用法。

    • 云开发部分:包括云数据库、云存储和云函数的核心 API 讲解。

    • 实例部分:主要介绍了 6 个小项目实例,其中美团客户端的例子支持小程序支付功能。

    学完本达人课后,读者可以快速掌握小程序的核心开发技术,熟练使用小程序的各种组件以及 API 开发包括服务端的小程序,并可以开发出复杂的小程序应用。

    作者介绍

    李宁,欧瑞科技创始人 & CEO,技术狂热分子,IT 畅销书作者,CSDN 特约讲师、CSDN 博客专家,拥有近 20 年软件开发和培训经验。主要研究领域包括 Python、深度学习、数据分析、区块链、Android、Java 等。曾出版超过 30 本 IT 畅销书,主要包括《Python 从菜鸟到高手》、《Swift 权威指南》、《Android 开发指南》等。

    作者在 GitChat 上的个人主页信息详见这里

    课程内容

    导读:小程序风口已经到来,你准备好了吗

    小程序是腾讯公司推出的,可以运行在微信中,加载速度比 H5 快,开发效率也比 App 快,所以小程序是获得用户、成为流量入口的最佳选择。随着小程序的成熟,微信体内的各入口将全面转入小程序形态。现在开发小程序的创业公司越来越多,甚至很多大公司也加入了小程序开发的序列,作为程序员的我们,是否会开发小程序,将会成为职场上升值加薪的重要筹码。

    小程序之所以现在这么火,是因为有非常多的引流模式和盈利模式,本文将介绍其中的集中引流模式和盈利模式。不管读者学了小程序开发是为了升值加薪、还是为了找工作,或是为了创业,都会有很大的帮助,毕竟老板都喜欢既会技术、又知道如何将技术变现的员工。

    到目前为止应用程序的类型已经经历了 3 个时代:PC 时代、App 时代和轻应用时代,其中 PC 时代是指桌面应用以及 Web 应用,这个时代从 2008 年基本结束了,从此以后开始进入 App 时代,App 主要指的是 Android App 和 iOS App,这一时代一直到 2016 年,虽然 Android App 和 iOS App 功能很强大,但安装和升级很费劲,大的 App 可能是有几十 M,甚至上百 M,所以从 2016 年开始,轻型应用开始走入我们的视线,这其中以微信小程序为主,其他的还包括支付宝小程序、百度轻应用、快应用等,这 3 个时代如下图所示。

    enter image description here

    下面聊聊小程序的变现渠道,目前微信用户有 10 亿左右,理论上,这 10 亿用户都有可能成为小程序的准用户,其中可挖掘的商业价值非常巨大,如电商、内容付费、游戏、广告等。由于小程序安装非常方便,只需要用手机微信扫描小程序码就可以安装,所以相比 App,用户更有安装小程序的意愿。

    enter image description here

    那么微信小程序对于我们技术人员有哪些创业机会呢?在展示新创业机会之前,我们得要重新审视这两点。

    (1)小程序不能照搬公众号的思路

    因为同属于微信这个圈子,所以很多人想当然地将小程序当作一种新型的公众号,认为做公众号的那一套方法,移植到小程序上面应该也差不多,其实这种想法是不恰当的。

    当然,小程序可以借助公众号这个已经成熟的自媒体生态获取用户,但如果完全用公众号的思路进行思考,是走不通的。

    (2)不要把小程序当作 Web App

    小程序是完全基于微信生态的产品,所以它无论在 UI 设计上还是在功能上,都和微信本身紧密结合,所以在开发和运营时,都要首先从微信这个大环境的角度出发,它可以是一个只有某项核心功能的简化版 App,也可以是一个解决用户临时需求的小工具,但无论如何,它都是基于微信而生的。

    下面就来看看小程序的新机遇在哪里?

    (1)新交互

    所谓的新交互,是指跟原来不一样的玩法,比如说基于群的互动和娱乐,它不仅仅是用群的方式来获取群的流量红利,更多的是基于这种群的关系去开发出更多适合群的场景的玩法出来,它将会是最新且变异量最大的一种。

    尤记得在 2017 年 1 月 9 号小程序上线发布会上,张小龙举了一个例子,大意就是几个喜欢看球的男生,建了一个微信群,小程序的窗口可以浮在群聊之上,在小程序里面播放视频并实时显示比分,在群里大家还可以讨论的热火朝天,甚至可以玩一些“押注”的小游戏,这样的场景可能会有很多,比如女生一起拉个群看综艺,或者一起拉个群线上 K 歌等。

    互联网最性感的地方,就在于能在线还原生活中的场景,并且门槛更低、体验更好。

    2018 年,小程序的新交互方式给我展示了这个可能性其实是爆发式的,诸如头脑王者、各种吃鸡游戏、猜歌达人等都是为场景化而生,这种新型的交互方式门槛低、用户精准,在产品有足够的谈资和趣味性很容易在圈子里面引起大家的热议。

    (2)新人群

    小程序出来之后,极大地降低了生产门槛,以前对大量没有媒体能力的人来讲,是不可能生成公众号的,但是现在如果让他们去利用小程序做一个小店铺,是可行的。

    所以现在有些人,专注到中老年市场、农村市场的有服务能力的人群,比如果农,可以很方便地生成自己的店铺并上架商品,这个就是新人群的一种,甚至更简单的,每天为中老年的女性用户推送一条养生相关的视频或者音频,也能快速的实现用户增长。

    移动端长图文内容编辑器美篇去年九月至今刚上线不久,排名就以火箭之势飞数上升——在阿拉丁统计平台公布的小程序榜单“小程序新增榜”、“小程序上升榜”及“小程序工具榜”中,稳坐第一宝座,更是在双11电商一片红火的时候,晋级总榜前十!

    (3)新场景

    小程序上线初始,主推的就是“location”属性,赋能线下商家在线触达其用户。小程序是网站或者 App 的话,二维码就像他们的网址或者 App 链接,在此之前,从来没有如此低门槛低成本的解决方案。比如对一个包子馒头店的老板,可以通过“个人号 + 群 + 小程序”的形式,持续耕耘好自己的一亩三分地。在这个形态中,可能存在帮助线下商家更好地用好“微信能量”的机会。

    零售的本质是人和商品,以前的零售,无论是线下零售还是线上网店,除了商品本身,都有自己的客户,但客户是不融合互通的,所以呈现线性增长。新零售的核心就是线上线下互通融合,随着线上线下完全融合,线上客户与线下客户形成叠加和交叉,形成指数级的效应。小程序作为连接线下的最佳工具,将成为新零售时代,线下门店拥有“线上店”最简便和最佳的方式。

    好了,讲了这么多小程序的好处,以及如何用小程序盈利、小程序的新机遇等,但有一个前提,需要先学会开发小程序。从下一课开始,我们就开始学习小程序开发,为了让读者能更好地掌握小程序的开发技术,本系列文章的最后提供了 6 个实战案例,以便让读者可以将理论和实战相结合。

    下面详细说明一下本系列文章的主要内容。

    • 小程序开发环境安装和配置
    • 开发第一个小程序:石头剪子布
    • 小程序布局,主要涉及到水平排列、水平折行排列、垂直排列、垂直折行排列、水平和垂直排列对齐方式、水平等间隔排列等
    • 基础组件(text 组件、icon 组件和 progress 组件)
    • 滚动视图
    • 轮询图
    • 表单组件(button、checkbox、input、label、radio、switch、picker 等)
    • API 详解(网络、多媒体 API、文件、数据、位置等 API)
    • 用 WeUI 开发小程序
    • 实战案例一:高仿 iOS 计算器
    • 实战案例二:快递查询
    • 实战案例三:电影订票
    • 实战案例四:绘制图表
    • 实战案例五:小程序版网上商城
    • 实战案例六:美团客户端(带支付功能)

    读者通过本系列文章,不仅可以深入了解小程序开发的所有技术,还可以获得大量的实战经验。

    第01课:小程序初体验

    微信小程序概述

    微信小程序是继订阅号、服务号、企业号之后,微信公众平台上全新的一种连接用户与服务的方式,目前已经有大量小程序上线,第一波红利开始显现,希望赶上第一波红利的同学抓紧了,时间不多了。

    注册小程序账号

    在开始学习小程序之前,先来看一下如何搭建小程序的开发环境。微信平台上的任何东西,要想使用,首先需有一个账号,小程序也不例外,先到到 官网 去注册一个小程序账号,进入该页面,单击右上角“立即注册”链接,会显示如下图的注册页面。

    image

    这 4 个注册类型需要使用 4 个不同的账号,如果读者已经有了订阅号或其他号的账号,仍然需要再次注册小程序账号。

    现在单击“小程序”选项,会让你输入邮箱、密码、验证码等信息,这些都是注册的常规流程,这里不再敖述,然后单击下方的“注册”按钮,系统会发送一封 Email 到你注册的邮箱中,单击 Email 中的链接,这时会进入填写注册信息页面。目前小程序的账号注册并不对个人开发,只对如下图所示的 4 种类型的组织。

    image

    如果读者有自己的企业,或为单位注册,可以选择相应的类型。如果读者只是个人,可以尝试选择“其他组织”,并任意填写组织代码等信息,据说可以通过,由于本人并没有做这方面的尝试,所以并不能保证一定等通过,读者可以试一下。选择其他类型需要相关的资质证明,如果选择企业需要企业营业执照等信息。

    在注册的过程中要用企业账户向腾讯官方的账号打款 0.06 元进行验证(要求在 10 天之内打款,否则验证失败,而且只能是 0.06 元)。不管验证是否成功,款都会退回到原来的企业账户,验证是自动的,但并不是实时的。腾讯的服务端应该是隔一段时间进行一次验证,可能会等几个小时,请耐心等待。

    在验证通过之前,仍然可以用注册 Email 登录小程序后台,但无法获取小程序 AppID,验证通过后,会通过站内短信(在小程序后台右上角)进行通知。要注意的是,登录小程序后台的过程中要使用手机微信扫描二维码进行登录,请用管理员的微信扫描登录小程序后台。

    当成功注册小程序账号后,可以进入官网页面进行登录,登录的过程中需要使用管理员的手机微信扫描二维码。刚一登录进小程序的后台管理页面,会看到如下图所示的主页面。

    enter image description here

    获得 AppID

    尽管开发小程序,AppID 并不是必须的,但如果要在真机上测试小程序,以及发布小程序,就必须要 AppID 了,这就和 Apple 的开发者账号一样,如果不花 99$/1 年的费用购买开发者账号,就只能在 iOS 模拟器上玩玩了。当然,小程序的 AppID 是不收钱的,只要注册者满足资质,就可以免费注册,并获得 AppID。

    如果读者按着上一节的步骤成功注册了小程序账号,并登录到小程序后台管理页面,点击左下角的“设置”链接,在右侧点击“开发设置”选项卡,就会看到“开发者 ID”列表,第一项“AppID(小程序 ID)”后面就是 AppID,如下图所示。

    enter image description here

    这个 AppID 是我做的一个小程序(极客题库)的 AppID,不过就算大家知道了这个 AppID,也用不了,因为登录时需要用管理员的微信扫描才可以,或者成为该项目的开发者,否则是无法使用别人的 AppID 的。

    设置小程序信息

    即使有了 AppID,也不能立即发布小程序,在此之前,还需要设置小程序的基本信息,点击“设置”链接,在右侧点击“基本设置”,会出现一些设置项,如小程序名称、小程序头像等。如果设置完,会有类似下图所示的信息。

    enter image description here

    当小程序发布后,如果想让别人使用你的小程序,最简单的方式就是提供小程序的二维码,点击页面“二维码”右侧的“下载”按钮,会弹出如下图的页面。

    enter image description here

    用户可以单击普通二维码和小程序码的相应下载按钮,下载不同尺寸的二维码和小程序码,下图是极客题库小程序码的样式。

    be79cfc0-98a5-11e8-a6e2-01e53da9d643

    第02课:开发第一个小程序:石头剪子布游戏

    开发第一个小程序

    这一部分将从零开始开发一款微信小程序,该程序的功能很简单,是一个猜拳游戏,单击“开始”按钮后,会快速切换“锤子”、“剪刀”和“布”,直到按“停止”按钮,会显示“锤子”、“剪刀”和“布”中的一个,该游戏可以双方或多方进行猜拳,这里猜拳的规则就不多说了,大家应该很清楚。本节内容的目的是通过该例子,将开发微信小程序的过程完整地跑一遍,从配置开发环境到建立小程序项目,一直到将微信小程序发布到微信平台,并在真机上测试为止。通过该例子,读者可以完全掌握微信小程序的开发流程。

    搭建开发环境

    腾讯推出微信小程序的同时,也推出了自己的开发工具,读者可以单击这里下载该开发工具的最新版本。

    这套开发工具目前支持 Windows32 位、Windows64 位以及 Mac OS X 系统,读者需要根据自己使用的 OS 下载合适的版本。本书主要使用 Mac OS X 版本进行讲解,Windows 版本和 Mac OS X 大同小异,并不影响读者阅读本书的内容。

    运行微信小程序 IDE 后,会看到如下图所示的窗口。

    d8cc4960-98a6-11e8-a6e2-01e53da9d643

    单击“小程序项目”按钮,会显示如下图的小程序项目管理页面。

    058a2f70-98a8-11e8-9195-95b521cd20b9

    要想新创建小程序项目,需要单击右下角的加号按钮,会弹出如下图所示的页面,选择一个空的项目目录,然后输入 AppID,如果不输入 AppID,无法在真机上发布,最后输入项目名称。

    8df7d570-98a7-11e8-9195-95b521cd20b9

    一切都搞定后,单击“确定”按钮创建小程序项目,主界面如下图所示。

    897f5030-98a8-11e8-9195-95b521cd20b9

    猜拳游戏布局

    单击如下图所示的 index.wxml 文件,输入布局代码,wxml 文件是小程序中的布局文件,用于描述小程序中的 UI。关于 wxml 文件的详细内容,会在后面的内容中详细描述。

    432c5040-98aa-11e8-a6e2-01e53da9d643

    下面先看一下猜拳游戏的主界面,如下图所示。

    9746c520-98aa-11e8-9965-cbd322341912

    猜拳游戏的布局是纵向显示了三个组件:文本组件(text)、图像组件(image)和按钮组件(button)。在创建小程序工程时,默认建立了两个页面:index 和 logs。我们不需要管 logs,在这个例子中只修改和 index 页面相关的文件,index 是小程序第一个显示的页面,其中 index.wxml 文件是 index 页面的布局文件,现在打开该文件,并按下面的内容修改代码。

    <!--index.wxml--> <view class="container">     <text class="finger_guessing">猜拳游戏</text>     <view   class="userinfo">         <image class="userinfo-avatar" src="{{imagePath}}" background-size="cover"/>         <button bindtap="guess">{{title}}</button>      </view>   </view>

    在这段代码中,image 和 button 组件的内容都需要动态改变,所以 image 组件的 src 属性和 button 组件的文本值(夹在 <button> 和 </button> 之间的部分)都分别于一个变量绑定,这是小程序的一个重要特性(和 React Native 完全相同)。在改变组件的属性值时,并不需要直接获取该组件的实例,而只需将该属性与某个同类型的变量绑定,一旦该变量的值改变,属性值也就会随之改变了,绑定变量的格式是“{{变量名}}”。改变了的定义和初始化部分,在后面的部分会详细介绍。

    我们发现,就算按前面的布局,仍然不能像上图所示那样摆放组件,这是因为还需要将下面代码调整一下样式(index.wxss 文件)。

    /**index.wxss**/ .userinfo {   display: flex;   flex-direction: column;   align-items:center;   margin-top: 50px; } .userinfo-avatar {   width: 500rpx;   height: 500rpx;   margin: 40rpx;  }  .userinfo-nickname {   color: #aaa; }  .finger_guessing {   color: #F00;   font-size: 30px;   margin-top: 20px; } 

    前面的布局代码主要调整了 userinfo-avatar 的宽度和高度,让图像显示得更大一些。最后,还需要修改一下 app.wxss 文件的代码,将 padding 属性的值改成 50 rpx 0,代码如下:

    /**app.wxss**/ .container {   height: 100%;   display: flex;   flex-direction: column;   align-items: center;   justify-content: space-between;   padding: 50rpx 0;   box-sizing: border-box; } 

    当然,现在可能仍然无法显示图像,因为 imagePath 变量还没有设置,而且图像还没有放到工程目录。现在读者可以到网上找三张图片,分别是剪子、石头和布,当然,也可以用本例提供的图像,并在小程序工程根目录建立一个 images 目录,将这三个图像文件放到该目录中。

    控制剪子、石头、布的快速切换

    猜拳游戏的核心就是快速切换剪子、石头、布三个图像,当单击“停止”按钮后,会停到其中一个图像上,这里涉及到如下两个动作:

    • 用定时器快速切换图像。
    • 图像下方的按钮,当一开始单击时,文本变成了“停止”,当再次单击该按钮后,按钮文本又变成了“开始”,也就是说,一个按钮同时负责开始和停止图像快速切换两个动作。

    控制图像快速切换和按钮文本变化两个动作的代码都要写在 index.js 文件中。首先将这三个图像文件名存储在一个全局的数组中,并使用定时器快速从这个数组中依次循环获取图像文件名,并将该文件名指定的图像显示到 image 组件中,修改按钮的文本只需要修改 title 变量即可。

    这里涉及到两个主要变量:imagePath 和 title,这两个都定义在 data 对象中,单击按钮会执行 guess 函数(在 index.wxml 文件中使用 bindtap 属性指定按钮的单击事件函数名),该函数也需要在 index.js 中编写,完整的实现代码如下:

    //index.js//获取应用实例 var app = getApp() //  在数组中存在三个图像文件名 var imagePaths = ['../../images/scissors.png', '../../images/stone.png', '../../images/cloth.png'];//  当前图像的索引 var imageIndex = 0; Page({   data: {     imagePath: imagePaths[0],  //  用于修改image组件显示图像的变量     title: '开始',                //  用于改变按钮文本的变量     isRunning:false,            //  该变量为true,表示图像正在快速切换     userInfo: {},   },   //事件处理函数   bindViewTap: function () {     wx.navigateTo({       url: '../logs/logs'     })   },   //  定时器要执行的函数   change: function (e) {     imageIndex++;     //  当前图像索引大于最大索引时,重新设为第一个索引值(已达到循环显示图像的目的)     if (imageIndex > 2) {       imageIndex = 0;     }     //  修改image组件要显示的图像(改变imagePath变量的值)     this.setData(       {         imagePath: imagePaths[imageIndex]       }     )   },    //  点击按钮要执行的函数    guess: function (e) {     //  获取isRunning变量的值     let isRunning = this.data.isRunning;     // 根据是否正在快速切换图像,决定如何修改按钮文本,以及是开启定时器,还是移除定时器     if (!isRunning) {       this.setData(         {           title: '停止',           isRunning:true         }       );       //  开启定时器(没100毫秒调用一次change函数)       this.timer = setInterval((function () {         this.change()       }).bind(this), 100);     }     else {       this.setData(         {           title: '开始',           isRunning:false         }       );       //  移除定时器       this.timer && clearInterval(this.timer);     }   },   onLoad: function () {     console.log('onLoad')     var that = this     //调用应用实例的方法获取全局数据     app.getUserInfo(function (userInfo) {       //更新数据       that.setData({         userInfo: userInfo       })     })   } })

    是不是这个猜拳游戏很简单呢,这么点儿代码就搞定了,现在可以通过左侧的模拟器来测试我们的成果了。大家可以单击“开始”按钮,看看图像是否会快速切换,再单击“停止”按钮,看看是否会停止在某个图像上。

    真机测试小程序

    现在轮到用真机测试我们的成果了。如果只想在真机上测试,用管理员微信登录小程序 IDE 都可以,单击 IDE 工具栏中的“预览”按钮,会弹出一个带二维码的页面,如下图所示。用管理员的账号登录手机微信,扫描该二维码,猜拳游戏就会在手机上运行。

    f7b05c40-98ab-11e8-9195-95b521cd20b9

    在真机上的测试效果如下图所示。

    61adb110-98ac-11e8-a6e2-01e53da9d643

    真机调试小程序

    如果在模拟器上开发小程序,很容易在 Console 中查看调试信息,但如果在真机上运行呢?其实也有办法查看调试信息。现在按着前面讲解步骤在真机上运行小程序,然后点击右上角的省略号(…)菜单,会弹出如下图所示的菜单。

    enter image description here

    点击“打开调试”菜单项,这时当前小程序需要关闭,然后重新进入,此时会看到右下角有一个绿色的 vConsole 按钮,如下图所示。

    enter image description here

    点击 vConsole 按钮,就会显示打开真机上的 Console,并显示调试信息,如下图所示,关闭 Console,用同样的操作即可。

    enter image description here

    上传和审核小程序

    如果觉得在真机上测试没问题,那么可以单击工具条上的“上传”按钮将小程序上传到腾讯的服务器,单击“上传”按钮后,也会显示一个如下图所示的窗口,输入版本号和描述,单击“上传”按钮,即可上传到腾讯服务器。

    93c81e50-98ad-11e8-9195-95b521cd20b9

    成功上传小程序后,回到小程序的后台,点击左侧的“开发管理”选项,会看到如下图所示的三个小程序版本的管理页面。我们直接上传的是开发版本,如果管理员认为没问题,可以单击“提交审核”按钮,会将小程序提交给腾讯,这就是审核版本,如果腾讯审核通过,就正式上线了,这就是线上版本。

    enter image description here

    本课用一个完整的例子从头到尾演示了从开发小程序,到真机测试,再到上传发布的完整过程。尽管本章提供的例子非常简单,但足以清楚地展示了小程序开发的完整过程,不过要想开发牛逼的小程序,还需要继续阅读后续的文章。

    第03课:小程序布局

    概述

    布局是任何支持 UI 的技术都涉及到的,小程序的布局采用了和 React Native 相同的 flex(弹性布局)方式,使用方法也类似(只是属性名不同而已),因此,如果读者已经对 React Native 的布局比较了解,那么将非常容易掌握小程序布局,即使对 React Native 的布局不了解,通过对本课的学习,也可以掌握小程序布局的核心技术。

    水平排列

    小程序的布局和 React Native 的布局类似,采用了弹性布局的方法,也就是说,分为水平和垂直布局。默认是从左向右水平依次放置组件,从上到下依次放置组件。

    wxml 文件用于放置参与布局的组件,为了更好地描述小程序是如何布局的,本课使用了带背景色的 view 组件来演示,view 是小程序中所有可视组件的根。

    任何可视组件都需要使用样式来设置自身的属性,并完成相应的布局。在小程序中,可以使用两种方式设置样式,一种是 class 属性,另外一种是 style 属性。前者需要指定在 wxss 文件中定义的样式,后者允许直接在组件中定义样式属性。例如,如果要水平放置三个 view 组件,可以在 wxml 文件中使用下面的代码。

    <view class="flex-wrp" style="flex-direction:row">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view></view>

    在这段布局代码中使用了一些样式,所以需要在 index.wxss 文件中加入下面的样式代码。

    .flex-wrp{     height: 100px;     display:flex;     background-color: #FFFFFF; }.flex-item{    width: 100px;    height: 100px;}.bc_green{     background-color: #09BB07; } .bc_red{     background-color: #F76260; } .bc_blue{     background-color: #10AEFF; } .bc_yellow{     background-color: #FFBE00; } .bc_gray{     background-color: #C9C9C9; }

    布局的效果如下图所示。

    image

    如果不想使用 style 属性,可以将 flex-direction:row 放在样式中,例如,可以在 index.wxss 文件中添加如下的样式。

      .flex-row{     flex-direction:row; }

    然后修改 index.wxml 文件中的代码如下:

    <view class="flex-wrp flex-row" >     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view> </view>

    可能很多读者会发现一个问题,本文的例子只有三个 view,如果放置了多个 view 会怎么样呢?从 flex-item 样式可知,每个 view 的尺寸是 100*100,单位是像素(px),如果放置过多,可能会发生如下两种情况。

    • 折行
    • 压缩每一个 view 的宽度

    那么到底会发生哪种情况呢?我们不妨做一个实验,代码如下:

    <view class="flex-wrp flex-row" >     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>  </view>

    上面的代码很明显,view 中包含了 9 个子 view,保存 index.wxml 文件后,会显示如下图所示的效果。

    image

    很明显,每一个 view 的宽度都被压缩了(因为每一个 view 的默认尺寸是一个正方形),以适应设备的宽度。不过可能这种处理方式并不符合我们的要求,如果要求是让每一个 view 的尺寸保持不变,如果一行放不下,就折到下一行,那应该怎么办呢?答案就在下一部分!

    水平折行排列

    其实要想让 view 折行也很简单,只需要加一个 flex-wrap:wrap 即可,代码如下:

    <view class="flex-wrp flex-row" style="flex-wrap:wrap" >     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view> </view>

    或者将 flex-wrap:wrap 添加到 flex-row 样式中,代码如下:

    .flex-row{     flex-direction:row;     flex-wrap:wrap; }

    修改后的运行效果如下图所示。

    image

    注意:选择不同的手机模拟器(如 iPhone6 Plus、iPhone5),效果可能是不同的,因为每一行能显示的彩色方块数量是不同的。

    垂直排列

    只需要设置 flex-direction 的值为 column,就可以将水平排列改成垂直排列,代码如下:

    <view class="flex-wrp" style="height: 300px;flex-direction:column;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view></view>

    在这段代码中,将顶层 view 的高度设为 300 px,而每一个子 view 的高度是 100 px,所以垂直方向三个 view 会紧挨着显示,效果如下图所示。

    image

    那么在垂直方向,如果子 view 过多会怎么样呢?如下面代码所示。

    <view class="flex-wrp" style="height: 300px;flex-direction:column;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view> </view>

    如果使用上面的布局,会看到如下图所示的显示效果。

    image

    很明显,所有的子 view 都被压缩在垂直高度 300 px 的空间内(宽度未改变),那么能否让垂直排列的子 view 折列呢?请看下一部分的介绍。

    垂直折列排列

    折列和折行的方式一样,只需要加上 flex-wrap:wrap 即可,可以使用 style 属性添加,或在样式中添加,然后使用 class 属性引用样式。下面的代码使用 style 属性添加了 flex-wrap:wrap。

    <view class="flex-wrp" style="height: 300px;flex-direction:column; flex-wrap:wrap;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view> </view>

    使用上面的布局后,会看到如下图所示的效果。

    image

    从上图的效果可以看出,折列排列是在第2列、第3列从上到下依次排列的。

    水平排列对齐方式

    在上面看到的水平排列都是从左侧开始排列的,其实这是默认的对齐方式:左对齐,在 style 属性中加入 justify-content: flex-start,代码如下:

    <view class="flex-wrp" style="flex-direction:row;justify-content: flex-start;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view></view>

    除了左对齐,还有右对齐和中心对齐,只需要将 justify-content 的值改成 flex-end 和 center,即可实现右对齐和中心对齐的效果,右对齐的布局代码如下:

    <view class="flex-wrp" style="flex-direction:row;justify-content: flex-end;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view></view>

    右对齐的效果如下图所示。

    enter image description here

    中心对齐的代码布局代码如下:

    <view class="flex-wrp" style="flex-direction:row;justify-content: center;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view></view>

    中心对齐的效果如下图所示。

    enter image description here

    垂直排列对齐方式

    对于垂直排列来说,如果改变对齐方式,是否可以采用水平排列的方式呢?例如,下面的布局代码是否有效呢?

    <view class="flex-wrp" style="flex-direction:column;justify-content: flex-end;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view></view>

    保存文件后,会看到如下图所示的效果。

    enter image description here

    很显然,垂直排列的三个 view 并没有右对齐。其实,对于垂直排列来说,需要使用 align-items 属性(默认是左对齐),而不是 justify-content 属性,这两个属性的取值基本上相同。例如,下面的布局代码让三个垂直排列的 view 右对齐。

    <view class="flex-wrp" style="flex-direction:column;align-items: flex-end;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view> </view>

    垂直排列右对齐的效果如下图所示。

    enter image description here

    下面的布局代码让垂直排列中心对齐。

    <view class="flex-wrp" style="flex-direction:column;align-items: center;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view> </view>

    垂直排列中心对齐的效果如下图所示。

    enter image description here

    如果垂直排列是右对齐或中心对齐的方式,那么如果折列,会是怎么的一种效果呢?例如,下面的布局代码垂直方向右对齐,并且折列。

    <view class="flex-wrp"  style="height:300px;flex-direction:column;align-items: flex-end;flex-wrap:wrap;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view> </view>

    运行效果如下图所示。

    enter image description here

    从上图所示的效果来看,即使是右对齐,如果需要折列,显示的第一列仍然是从靠左方向开始的(从 view 的背景色就可以看出,第 4 个 view 的背景色是蓝色),然后向右折列(但最后一列需要紧贴着父视图右边缘,因为是右对齐)。如果是中心对齐,方式相同,也是从左向右像是。

    下面是中心对齐并折列的布局代码。

    <view class="flex-wrp"  style="height:300px;flex-direction:column;align-items: center;flex-wrap:wrap;">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view> </view>

    显示效果如下图所示。

    enter image description here

    水平等间隔排列

    如果想让 view 均匀地水平分别在窗口上,每两个 view 之间的间隔相同,那么就需要将 justify-content 属性的值设为 space-between,布局代码如下:

    <view class="flex-wrp" style="flex-direction:row;justify-content: space-between">    <view class="flex-item bc_green"></view>    <view class="flex-item bc_red"></view>    <view class="flex-item bc_blue"></view></view>

    显示的效果如下图所示。

    enter image description here

    如果子 view 过多,并且设置为折行显示,那么子 view 会如何排列呢?先看下面的布局代码。

     <view class="flex-wrp"       style="flex-direction:row;justify-content: space-between;flex-wrap:wrap">     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_blue"></view>     <view class="flex-item bc_green"></view>     <view class="flex-item bc_red"></view>     <view class="flex-item bc_green"></view> <view class="flex-item bc_blue"></view>  </view>

    使用上面的布局,会得到如下图所示的效果。

    enter image description here

    从上图所示的效果来看,不管折多少行,同一行相邻两个 view 之间的间距都是相等的。

    第04课:基础组件
    第05课:小程序组件:滚动视图
    第06课:小程序组件
    第07课:表单组件(上)
    第08课:表单组件(中)
    第09课:表单组件(下)
    第10课:多媒体组件
    第11课:网络 API(上)
    第12课:网络 API(下)
    第13课:多媒体 API(上)
    第14课:多媒体 API(中)
    第15课:多媒体 API(下)
    第16课:数据存取 API:文件管理
    第17课:数据存储 API:数据缓存
    第18课:位置 API
    第19课:设备 API
    第20课:界面 API(上)
    第21课:界面 API(下)
    第22课:开发接口 API
    第23课:【WeUI 应用】基础组件
    第24课:云开发简介
    第25课:编写第一个基于小程序云的应用
    第26课:云数据库的准备工作
    第27课:云数据库的增、删、改、查
    第28课:实现用于计算阶乘的云函数
    第29课:在云函数中的操作
    第30课:【项目实战】高仿 iOS 计算器
    第31课:【项目实战】快递查询
    第32课:【项目实战】电影订票
    第33课:【项目实战】绘制图表
    第34课:【项目实战】小程序版网上商城
    第35课:【项目实战】美团客户端(带支付功能)

    阅读全文: http://gitbook.cn/gitchat/column/5b7f5f06a62b70638ef61319

    展开全文
  • 微信小程序爬虫

    千次阅读 2021-07-25 13:23:57
    Big brother是我们公司的网球王子,他总是使用某微信小程序预定网球场地。然而,热门时间段的场地总是如同变魔术一般在一瞬间被订满。 别慌,我们有黑科技。这篇文章将教你使用Python实时监控场地情况,让你在订...

    Big brother是我们公司的网球王子,他总是使用某微信小程序预定网球场地。然而,热门时间段的场地总是如同变魔术一般在一瞬间被订满。

    别慌,我们有黑科技。这篇文章将教你使用Python实时监控场地情况,让你在订网球场也内卷的时代占尽先机。

    1 软件配置

    Charles是著名的抓包工具,可以抓取移动端与pc端网络访问的所有数据。我们将使用它抓取我们与小程序交互的所有信息。我们可以去官网下载适用于自己系统的Charles安装包

    安装完成后,很重要的一步是关于证书的配置。
    以下适用于使用Windows系统的用户。
    Help -> SSL Proxying -> Install Charles Root Certificate

    Install Charles Root Certificate

    点击安装证书

    安装证书

    点击下一步

    下一步

    点击将所有证书都放入下列存储,点击浏览,选择受信任的根证书颁发机构

    存储证书

    最后完成证书导入向导,提示成功。

    完成证书导入

    我们重新进入Help -> SSL Proxying -> Install Charles Root Certificate,查看证书结果,点击证书路径,显示如图所示即可。

    查看证书结果

    接着点击Proxy->SSL Proxy Settings。在SSL Proxying中勾选Enable SSL Proxying并点击Add,添加Host和Port都为 * (代表监听所有IP地址的所有端口)。

    Enable SSL Proxying

    至此,Charles就可以抓取pc端网络访问的所有数据了。

    Charles常用的工具有工具栏下面扫帚状按钮(清除当前session的数据)和摄像头状按钮(开始以及停止抓取数据)。

    2 探索数据

    我们在pc端登录微信,打开我们想爬取的小程序,可以看到Charles已经为我们抓取了所有的访问数据。

    访问数据

    我们点开目标小程序:久事体育场馆(https://user.jusssportsvenue.com) 的文件夹,探索一下Charles为我们抓取了什么。
    我们点击api - common - advertising?type=1。可以看到右侧显示了这个请求的Overview。我们继续点击右上侧的Contents,可以看到底下呈现了这个请求所返回的内容。

    返回内容示例

    对应于小程序的正是首页的广告内容“小小体育家”。

    小小体育家

    Charles成功为我们获取了微信小程序的内容。下一步,我们将模拟整个订网球场的流程,观察这些请求以及返回的内容,以便之后用程序获取我们想要的场地信息。

    我们先关闭打开的微信小程序并点击Charles的扫帚状按钮,清除当前session的数据。我们重新打开微信小程序,点击网球,选择我们的目标场地:东方体育中心。我们选择想订的时间,例如,周二13点的三号场,点击确认提交。

    选择场地

    为了避免Charles获取其他不相关数据,我们点击摄像头状按钮停止抓取数据。我们重新点开久事体育场馆(https://user.jusssportsvenue.com) 的文件夹并点击api文件夹。

    所有数据

    • common文件夹下存取的是广告与按钮相关的信息。

    • venues文件夹下存取的是场地相关的信息,包括小程序上可以看到的仙霞网球中心、东方体育中心等可以预定的场地。

    • block文件夹下存取的是已经被预定的场地信息。

    以及和下单有关的u文件夹。u文件夹由block、order两个子文件夹以及info组成。info存储了用户的信息,从右侧Contents可以看到自己的用户名、手机号码等等。block初始化了这笔订单,并没有太多别的信息。order文件夹下包括cancel文件夹以及下订单的各种请求。其中createkBlock这个post请求对应于我们在小程序上所做的确认订单。blockPay代表了立即支付的操作。

    3 Python脚本

    下面我们将尝试使用Python,自动化的帮我们获取场地信息。我们按照两分钟打造淘宝抢单机器人文章所述,打开notebook。

    第一步,导入所需要的包。

    import requests
    import random
    import time
    import re
    import json
    

    第二步,我们在Charles中观察到,block -> ground文件夹下的请求返回了场地的信息。

    所有数据

    从Overview中我们可以拿到请求的URL。我们获取了未来几天的场地信息的URL。

    urls=[ 'https://user.jusssportsvenue.com/api/block/ground/list?venuesId=14&sportsType=11&startTime=1624204800000&skuId=5'#周一
          ,'https://user.jusssportsvenue.com/api/block/ground/list?venuesId=14&sportsType=11&startTime=1624291200000&skuId=5'#周二
          ,'https://user.jusssportsvenue.com/api/block/ground/list?venuesId=14&sportsType=11&startTime=1624032000000&skuId=5'#周六
          ,'https://user.jusssportsvenue.com/api/block/ground/list?venuesId=14&sportsType=11&startTime=1624118400000&skuId=5'#周日
          ]
    

    第三步,用Python提交请求,获取场地信息。

    response = requests.get(urls[0],verify=False)
    data=response.text
    data1=json.loads(data)
    orders=data1['data']['modelList']
    this_orders=orders[0]
    this_block=this_orders['blockModel'][0]
    

    我们打印一下获得的场地信息。

    print(this_block) 
    
    {'groundId': 41,
     'groundName': '1号场',
     'id': '41-1号场-0',
     'isCheckout': False,
     'isChoosing': False,
     'isNormal': True,
     'orderId': '202106141200125481',
     'price': 30.0,
     'source': 1,
     'sportsType': 11,
     'status': 0,
     'userAvatar': 'https://thirdwx.qlogo.cn/mmopen/vi_32/gq1EeEEFPQ9ob3aibUn7s9VpKoCjwmRIc5wKxKPqsdj06TwjHIoeC7icw6ibzJzYMC2lJvwRiay3wvvbXK2hwe2j5Q/132',
     'userId': 4919,
     'userName': 'xxx', #友情打码
     'userPhone': 'xxx' #友情打码}
    

    Bingo!我们成功使用Python获取了未来几天的场地的信息,下面我们将把代码整合起来。
    我们融入了一些自己的需求,如只考虑工作日晚上及周末的场地以及如果有空的场地就给自己的邮箱发邮件等。最终的代码如下:

    import requests
    import random
    import time
    import re
    import json
    
    user_agent_list = [
        'Mozilla/5.0 (Linux; Android 5.1.1; vivo X7 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 MicroMessenger/7.0.10.1580(0x27000A5E) Process/appbrand0 NetType/WIFI Language/zh_CN ABI/arm64',
        'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1464.0 Safari/537.36',
        'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36',
        'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36',
        'Mozilla/5.0 (X11; CrOS i686 3912.101.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36',
        'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36',
        'Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36',
        'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0.6',
        'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36',
        'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2224.3 Safari/537.36',
        'Mozilla/5.0 (X11; CrOS i686 3912.101.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36']
    
    
    header = {
        'Host': 'user.jusssportsvenue.com',
        'Connection': 'keep-alive',
        'accept': 'application/json',
        'charset': 'utf-8',
        'content-type': 'application/x-www-form-urlencoded',
        'User-Agent': random.choice(user_agent_list),
        'Accept-Encoding': 'gzip, deflate, br',
        'Referer': 'https://servicewechat.com/wx0fa97a8b900cb199/19/page-frame.html'
    }
    
    
    urls=[ 'https://user.jusssportsvenue.com/api/block/ground/list?venuesId=14&sportsType=11&startTime=1624204800000&skuId=5'#周一
          ,'https://user.jusssportsvenue.com/api/block/ground/list?venuesId=14&sportsType=11&startTime=1624291200000&skuId=5'#周二
          ,'https://user.jusssportsvenue.com/api/block/ground/list?venuesId=14&sportsType=11&startTime=1624032000000&skuId=5'#周六
          ,'https://user.jusssportsvenue.com/api/block/ground/list?venuesId=14&sportsType=11&startTime=1624118400000&skuId=5'#周日
          ]
    
    def send_email():
        import smtplib
        from email.mime.text import MIMEText
        from email.mime.multipart import MIMEMultipart  
        
        _user = "XXX"
        _pwd  = "XXX"
        _to   = "XXX"
        
        msg = MIMEMultipart('related')
        msg = MIMEText('has room')
        msg["Subject"] = "Tennis booking"
        msg["From"]    = _user
        msg["To"]      = _to
        
        try:
            s = smtplib.SMTP_SSL("smtp.qq.com", 465)
            s.login(_user, _pwd)
            s.sendmail(_user, _to, msg.as_string())
            s.quit()
            print ("Success!")
        except smtplib.SMTPException:
            print ("Falied")
            
    id=True
    while id:
        for u in range(len(urls)):
    
            pattern = re.compile('startTime=(.*)&',re.S)
            starttime = int(re.findall(pattern, urls[u])[0])
            response = requests.get(urls[u],headers=header,verify=False)
            data=response.text
            data1=json.loads(data)
            orders=data1['data']['modelList']
            for i in orders:
                if u<2 and i['startTime']/1000<starttime/1000+64800:
                    continue
                for j in i['blockModel']:
                    if j['status']!=0:
                        send_email()
                        print('has room!') 
                        id=False
                        break
            time.sleep(3)
    

    我们只需要运行这段代码,如果有空的场地,Python将自动的给我们的邮箱发送邮件。我们只需要及时下单预定场地即可。

    展开全文
  • # 效果展示:微信搜索 “王美美与曾小帅” 小程序即可查看效果 # 微信小程序入门——使用免费后端云(Bmod)搭建留言板与纪念日间隔天数(部分源码) ## 从注册小程序小程序的上线发布 ## 文后提供思维导图 ##...
  • 微信小程序底层原理

    万次阅读 2018-11-16 15:58:06
    小程序呈现形式为第三种。     双线程通信方式 为什么要双线程 ? -&gt; 为了管控安全,避免操作DOM。     小程序的渲染层和逻辑层分别由 2 个线程管理:渲染层的界面使用了 WebView 进行渲染,...
  • 小程序原理

    2020-06-28 19:59:01
    微信小程序是介于Native和WebApp之间的产物,它依托浏览器WebView展示同时可以调用原生能力,比如获取通讯录、拍照等,同一份代码可运行在Android、iOS和微信调试开发工具内。 与React Native的跨平台不同的是,...
  • java实验报告之applet(小程序

    千次阅读 2019-07-02 21:31:55
    一.实验目的与要求 1.了解java Applet基本框架...实验问题:设计如下应用程序,完成界面功能。需要完成的界面如下图所示: 图一:实验界面图 <2>实验步骤: (1)在编辑区编译java源文件,形成类文件.class...
  • 微信小程序性能优化

    2019-02-22 11:25:47
    【微信小程序】性能优化 内容整理于微信公开课 为什么要做性能优化? 一切性能优化都是为了体验优化 1. 使用小程序时,是否会经常遇到如下问题? 打开是一直白屏 打开是loading态,转好几圈 我的...
  • 微信小程序提供模板template,可以在模板中定义代码片段,然后在不同地方调用,这里面就引用了名为quantity的代码块,这样引用的好处和css样式引用一样,增加代码发复用率,引用方式如下,is后面是模板的名字,data...
  • 微信小程序开发笔记

    千次阅读 2018-11-05 21:22:26
    0.1、在实际的开发中,图片资源不会存储在小程序的目录中,因为小程序的大小不能超过1MB(现在改为2M)。超过则无法真机运行和发布项目。我们应该将图片都存放在服务器上,让小程序通过网络来加载图片资源。 0.2、在...
  • 小程序官方文档 当开发完一个小程序之后,性能优化就是一项长期的工作,那么我们就得了解一下如何做性能优化。 启动 在小程序启动时,微信会为小程序展示一个固定的启动界面,界面内包含小程序的图标、名称和加载...
  • 以下是采集的 4G网络下,不区分手机系统 的车险分包的加载耗时(作为优化前的基线数据): 实践 由于小程序有提供许多基础API、UI库,而这部分代码是每个小程序的依赖。因此初始化代码的时候,这个是最先初始化的,...
  • 微信小程序实现语音识别功能

    千次阅读 2020-10-27 18:33:06
    原标题:微信小程序实现语音识别功能使用小程序实现语音识别功能,由于语音识别可以直接使用各厂家的API接口,并且小程序为腾讯所有,因此考虑到可能的低延时,采用了腾讯提供的免费API接口,准确讲是腾讯语音的“一...
  • 【系】微信小程序云开发实战坚果商城-开篇 基础篇 【系】微信小程序云开发实战坚果商城-弹性盒子 【系】微信小程序云开发实战坚果商城-ES6 简单入门 【系】微信小程序云开发实战坚果商城-官方案例先...
  • 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,灯具商城系统被用户普遍使用,为方便用户能够可以随时进行...
  • 小程序+新零售,行业新玩法!

    千次阅读 2018-06-12 11:07:00
    而连接线上场景与线下服务的微信小程序,能否成为线下门店撬动新零售的杠杆?下面跟随道爷一起进入探索吧!小程序+新零售零售行业面临新挑战近年来,受中国经济增速放缓、电商冲击、租金成本攀升、人们消费习惯改变...
  • 微信小程序开发工具使用简介

    千次阅读 2018-07-06 13:28:35
    为了帮助开发者简单和高效地开发和调试微信小程序,我们在原有的公众号网页调试工具的基础上,推出了全新的微信开发者工具,集成了公众号网页调试和小程序调试两种开发模式。 使用公众号网页调试,开发者可以调试...
  • 微信小程序——云服务环境的配置

    千次阅读 2020-05-27 12:05:52
    选择小程序云开发 创建即可 成功后会为我们呈现一个实例 刚刚创建的云服务项目中 测试器中有以下错误 搭建云环境 点击上面的云开发 开通云开发 开始创建环境 环境名称自定义 点击确定等待30秒 搭建成功 成功...
  • 期待许久的微信小程序正式于1月9日凌晨上线,用户只要将微信更新到最新版本(V6.5.3),即可通过扫描二维码,或搜索等方式体验微信小程序。体验微信小程序后,即可在微信「发现」菜单末尾出现诸如朋友圈各种装X晒图...
  • 页面实现上传一张带有人像的图片,点击测试颜值之后返回照片中人像的年龄和颜值,此项目为颜值测试初级,access_token值为获取之后在页面中固定,注意有有效期30天,30天之后需要更换,未对生成数据进行处理和判断,...
  • 仿写“跳一跳”微信游戏

    千次阅读 2018-04-12 10:41:43
    课程简介 2017-12-28 下午,微信...孙春光表示,2017 年移动游戏的自然人有 4 亿多,他们用 20 天就达到了这样一个数据。 作为微信游戏的入门教程,此达人课共计10篇文章,带你一步一步实战仿写微信“跳一跳”游...
  • (以《微信小程序开发入门与实践》(雷磊 清华大学出版社)为主要学习资料)1、app.json文件中页面路径前不要加/2、图片尽量不要存储在小程序的目录中。(因为小程序的大小不能超过1MB,超过则无法真机运行和发布...
  • 案例上手 Python 数据可视化

    万次阅读 多人点赞 2019-02-27 23:30:05
    课程亮点 ...数据可视化是数据分析和机器学习的重要环节,比如数据清洗、特征工程、机器学习、数据分析(特别是报告)、评估等环节都会用到“数据可视化”技术。 数据可视化同时还广泛存在于各...
  • 解决数据倾斜思路 2.1 业务逻辑 2.2 程序层面 2.3 调参方面 2.4 从业务和数据上解决 一、数据仓库的8个发展阶段 1、概念阶段(1978-1988) 数据仓库最早的概念可以追溯到20世纪70年代MIT的一项研究,该研究致力于...
  • XX数据中心技术方案

    千次阅读 2020-11-15 22:49:45
    “证券公司应将数据治理纳入公司整体信息技术建设战略规划,制定数据标准,涵盖数据源管理、数据库建设、数据质量监测等环节。” 业务背景 中国金融行业发展迅速,随着互联网,软件等行业的推陈出新,全球信息化...
  • 为了更好地展示这些优秀的小程序,展现背后的开发者/团队风彩,CSDN特别推出了【寻找最佳小程序】系列访谈栏目,以期分享每款优秀小程序背后的产品创意与研发故事,探究创新性应用场景,发现不一样的创业机会。...
  • 最优秀的数据可视化案例欣赏

    万次阅读 2019-03-20 07:46:52
    优秀的可视化案例欣赏美国运通漏斗图能量预测Bullseye雷达预算图城市统计数据可视化实时游戏数据能量监测自定义分析电力图表如何可视化您的数据数据是新的生产资料,如果您无法以直观的方式显示数据,那么它基本...
  • 作为一个头目,经常会读到来自各种团队的数据分析报告,看似基于理性和事实的雄辩,然而有可能是有意或无意的诡辩。搞得我经常像傻白甜的美少女面对追求的少男一样,面对这些严谨的数据分析也不得不多长几个心眼。...
  • 【微信小程序】性能优化

    千次阅读 2018-07-14 04:00:20
    1. 使用小程序时,是否会经常遇到如下问题? 打开是一直白屏 打开是loading态,转好几圈 我的页面点了怎么跳转这么慢? 我的列表怎么越滑越卡? 2. 我们优化的方向有哪些? 启动加载性能 渲染性能 3...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,407
精华内容 13,362
关键字:

数据立即呈现小程序