目录

微信小程序从入门到精通

目录

微信小程序从入门到精通

本篇文章是笔者在学习微信小程序的过程中写下的笔记,之所以写这篇是因为csdn上几乎没有一篇博客能够系统的记录小程序的学习,我希望这篇博客能给想要看文档学习小程序的同学提供一些帮助。

另外,关于小程序的学习我强烈建议有vue操作的人来学习,因为小程序的思路和原理与vue及其稳和,所以如果大家在学习过程中需要复习vue,可以看我的这篇博客:

如果学习中有问题也可也私信我交流或者评论区一起交流。私信一般会回!

话不多说,码字不易,希望大家多点赞多关注收藏!!咱们开始学习!

小程序与普通网页开发:

运行环境:网页运行在浏览器中,小程序用于微信中;

API:小程序无法调用浏览器中的DOM和BOM的API,但是可以调用微信环境提供的API(地理定位、扫码、支付);

开发模式:网页的开发(浏览器+代码编辑器),小程序,申请开发账号,安装开发者工具,创建和配置小程序项目。

注册开发账号:https://mp.weixin.qq.com/

点击立即注册,选择小程序,接着走流程即可。

在注册好之后,可以获取AppID。

这个字符串日后开发会用到:

https://i-blog.csdnimg.cn/blog_migrate/84b6cc68bc68927ee1ea9d7a660da3ab.png

作用:创建项目、编辑调试代码、调试功能、小程序预览与发布。

下载:

https://i-blog.csdnimg.cn/blog_migrate/75ad4752865788969648341a4622535f.png

点开之后可以下载稳定版本的。

下载安装包后安装即可。

安装完成后,微信扫码打开登录

https://i-blog.csdnimg.cn/blog_migrate/ba31cad4b4e594c838558373897f48dd.png

这属于一项配置,直接操作即可。

点击右上角设置按钮,改成第一项:

https://i-blog.csdnimg.cn/blog_migrate/5cb02b705947745d8ffbb8f1b17af722.png

点击加号按钮:

https://i-blog.csdnimg.cn/blog_migrate/5d0f0fe0928ae2a0e2a58b7f5130ba66.png

配置好一些信息,设置存放目录后,把之前的AppID复制过去, 不使用云服务 ,确保语言是js。

完成配置后,点开,页面如此:

https://i-blog.csdnimg.cn/blog_migrate/519b01dd494fa7988240ca8eeb6ea2b1.png

左侧是页面模拟器,右边有一个编译的按钮,点击后,就可解析代码到左侧的模拟器中。

如果想在手机查看,可点击编译按钮右侧的预览,扫码即可:

https://i-blog.csdnimg.cn/blog_migrate/8759ec076961ad9727b0612664810083.png

点击帮助,开发者文档即可打开:

https://i-blog.csdnimg.cn/blog_migrate/6af4ffad68960b70d76a001b1cc921c1.png

一般选择iPhone6、7、8版本:

https://i-blog.csdnimg.cn/blog_migrate/ba98f1cf58468319136e950b32d6405c.png

缩放显示屏:

https://i-blog.csdnimg.cn/blog_migrate/0b7526cd812d770acd408ad9da01d243.png

https://i-blog.csdnimg.cn/blog_migrate/63fa39ed7cbbd233b0c8104e5ca4847f.png

pages:存放项目中所有小程序页面;
utils:所有工具性质的模块(如格式化时间);
app.js:小程序项目入口文件;
app.json: 小程序项目的全局配置文件;
app.wxss:小程序项目的全局样式文件(全局);
project.config.json:项目的配置文件;
sitemap.json:用来配置小程序及其页面是否允许被微信索引。

https://i-blog.csdnimg.cn/blog_migrate/612711434c2e681c60d965ad9bb2ef98.png

一个页面由四个文件组成

.js:脚本文件,存放数据,事件处理函数等;
.json:配置文件,配置窗口外观,表现等;(json文件一般都是配置文件)
.wxml:页面模板结构摁键;
.wxss:当前页面的样式表文件。

当前小程序的全职配置,包括:页面路径、窗口外观、界面表现、底部tab等。

下面是初始化app.json文件的代码:

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

pages:用来记录当前小程序所有页面路径;

window:全局定义小程序所有页面的背景色、文字颜色等;

style:全局定义小程序组件所使用的样式版本;

sitemapLocation:用来指明sitmap.json的位置。

这个文件一般用于做一些自定义配置,本节看一下基本配置。

appid:如果拿到一个别人的项目,可以把appid改成自己的,就可以在自己的电脑上运行:

https://i-blog.csdnimg.cn/blog_migrate/02d3ac48534b96ed3324807dffa979fd.png

projectname:项目名称,不等于小程序名称。

https://i-blog.csdnimg.cn/blog_migrate/074fb24b9aeaa19f66ed9532668e90f7.png

配置小程序页面是否允许微信索引:

{
  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
  "rules": [{
  "action": "allow",
  "page": "*"
  }]
}

上面这段代码,page后面是星号,表示所有页面,action后面是allow,表示所有页面都允许被索引。(不允许可以改成disallow)

对本页面的窗口外观进行配置,页面中的配置项会覆盖app.jsono的window中相同的配置项。

https://i-blog.csdnimg.cn/blog_migrate/ae8a960287a38fe549e24b7941069593.png

https://i-blog.csdnimg.cn/blog_migrate/f3b1a26fad48857cff0aed85e32031a8.png

app.json是全局配置,如果页面配置与全局配置发生冲突,则依照页面配置来。

注意,文章中只要更改了代码,都要ctrls保存一下,右边才会有显示。

只需要在pages中新增页面存放路径,小程序开发者工具会自动帮我们创建页面文件:

https://i-blog.csdnimg.cn/blog_migrate/02bcb7e85b5c7bbb594720f5927ddff5.png

https://i-blog.csdnimg.cn/blog_migrate/d3d7ac5f377ad844c8a63ea64df97503.png

WXML是小程序框架设计的一套 标签语言,用老构建小程序页面的结构 ,类似网页开发中的HTML。

WXML和HTML区别

标签名称不同:
HTML(div、span、img、a)
WXML(view、text、image、navigator)

属性节点不同:
<a href="#">超链接</a>
<navigator url="/pages/home/home"></navigator>

提供了类似Vue中的模板语法:
数据绑定、列表渲染、条件渲染
新增了rpx尺寸单位:
CSS需要手动单位换算,如rem;
WXSS在底层支持新的尺寸单位rpx,在不同大小屏幕上自动换算

提供了全局样式和局部样式:
项目根据app.wxss设置全局页面,局部页面.wxss仅对自己的页面生效

WXSS仅支持部分CSS选择器。
类选择器、id选择器、元素选择器、并集选择器、后代选择器、伪类选择器
app.js:入口文件,可调用App()函数来启动整个小程序;
页面.js:页面入口文件,通过调用Page()函数来创建并运行页面;
普通.js: 用来封装公共函数或者属性供页面使用。

宿主环境:程序运行所必须的依赖环境。

安卓和IOS系统是两个不同的宿主环境, 脱离了宿主环境的软件是没有任何意义的。

这里以安卓为例。同样,IOS系统也有一套IOS系统的宿主环境(不放图了以此类推)。

https://i-blog.csdnimg.cn/blog_migrate/0bb9bbb88ed9c8449d363e9cd92dda1b.png

1.通信模型

通信主体:渲染层和逻辑层

渲染层与逻辑层通过微信客户端进行通信。

https://i-blog.csdnimg.cn/blog_migrate/71b94cc78cc9eafae9a16941b1474c42.png

2.运行机制

启动过程:

下载包->解析app.json->执行app.js,通过App()->渲染小程序首页->启动完成

页面渲染:

加载.json->加载.wxml模板和.wxss样式->执行.js文件,调用Page()->渲染完成

组件的存在,是为了代码的复用。系统封装好的导航,按钮,我们可以拿过来直接用,这就是组件。

官方把小程序组件分为九大类:==视图容器、基本内容、表单组件、导航组件、==媒体组件、map地图组件、canvas画布组件、开放能力、无障碍访问。

本节内容将带领读者了解小程序的常用组件。

本节讲一些微信小程序的常用组件。

注意哦,wxss几乎与css一样,后文基于样式的,不详细讲,按照css来写即可。

一开始打开后:

https://i-blog.csdnimg.cn/blog_migrate/c903c74dd7cf68b052b97f1d949c4763.png

但是如果我们要在其中一个页面中写样式,如何在模拟器中查看呢?

在app.json中改变地址顺序即可:

https://i-blog.csdnimg.cn/blog_migrate/d331a5f4dc412f0591384e7b3e4ab5f6.png

先介绍view。view可以理解为div,也可也当div去用。在list中的wxml中的代码:

<view class="container1">
  <view>A</view>
  <view>B</view>
  <view>C</view>
</view>

可以在wxss中写样式,样式的写法和css一样。

最后效果:

https://i-blog.csdnimg.cn/blog_migrate/bab502635f46e15ced020c4e3341b7a8.png

实现纵向滚动效果:

https://i-blog.csdnimg.cn/blog_migrate/b9368bdf30f172a009f5497aad7b7a1f.png

https://i-blog.csdnimg.cn/blog_migrate/52b9b15595313a3e9206ffc1731b5e1e.png

做法,在刚刚的基础上,把外面的标签改为scroll-view;如果纵向滚动,在外侧加一个强制属性:scr0ll-y,并且给scroll-view指定一个高度;如果是横向滚动,则强制属性为scroll-x,并且给scroll-view指定一个宽度。

可以看下代码:

.wxml:

<scroll-view class="container1" scroll-y>
  <view>A</view>
  <view>B</view>
  <view>C</view>
</scroll-view>

在之前的基础上指定高度:

https://i-blog.csdnimg.cn/blog_migrate/bde4e43c05184d483591e9a2618c36f3.png

轮播图组件用swiper和swiper-item来做。

外层用swiper包裹,内层用swiper-item来做。swiper-item内部可以自己写。看一下代码:

<swiper class="container2">
  <swiper-item>
    <view class="item">A</view>
  </swiper-item>
  <swiper-item>
    <view class="item">B</view>
  </swiper-item>
  <swiper-item>
    <view class="item">C</view>
  </swiper-item>
</swiper>

最后效果出来,就是个轮播

https://i-blog.csdnimg.cn/blog_migrate/2427f6412fd9c17014dac4156428b836.png

https://i-blog.csdnimg.cn/blog_migrate/61d935767ff2e4aeffb2b777b50f5d4f.png

样式也可自己写,写完样式就很好看,下面这个是轮播过程截的图:

https://i-blog.csdnimg.cn/blog_migrate/a915748c0e7ff54e3196dc8a7d53b734.png

指示点:indicator-dots

指示点颜色:indicator-color

指示点选中颜色:indicator-active-color

是否自动切换:autoplay

自动切换时间间隔:interval

是否采用衔接滑动:circular(到头了是否衔接到第一张)

https://i-blog.csdnimg.cn/blog_migrate/09e02f079e6a228738d422cf0473c421.png

本节讲解text与rich-text

text:文本组件,类似于html中的span标签,是一个行内元素;

rich-text:富文本组件,支持把html字符串渲染为wxml结构。

先看text,只有text属性又selectable属性,这个属性出现之后可以长按选中:

<view>
  <text selectable>2092844344</text>
</view>

https://i-blog.csdnimg.cn/blog_migrate/45912a3e09c340f94a9ea3a8caec64ed.png

可以在真机上尝试一下。

通过rich-text组件的nodes属性节点,可以把html字符串渲染为对应的ui结构。

https://i-blog.csdnimg.cn/blog_migrate/14cdbe95edb32dab88b7e7a3da234727.png

按钮组件,功能比html中的button更丰富,且通过 open-type 属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)

默认button:

https://i-blog.csdnimg.cn/blog_migrate/b9301d2d52d1b759f4872ceda6e919e7.png

指定不同类型可以使得按钮有不同颜色:

<button>默认按钮</button>
<button type="primary">主色调按钮</button>
<button type="warn">警告按钮</button>
<!-- 小尺寸size="mini" -->
<button size="mini">按钮</button>
<button type="primary" size="mini">按钮</button>
<button type="warn" size="mini">按钮</button>
<!-- 镂空按钮 -->
<button plain>默认按钮</button>
<button type="primary" size="mini" plain>按钮</button>
<button type="warn" size="mini" plain>警告按钮</button>

https://i-blog.csdnimg.cn/blog_migrate/1a5a03aa14e85551aa18d927ea5b6fda.png

功能类后文会讲解。

图片组件,image组件默认宽度约300px,高约240px。

现在来渲染图片:

https://i-blog.csdnimg.cn/blog_migrate/27a4d774507e1e01ea46353e9ff45c53.png

https://i-blog.csdnimg.cn/blog_migrate/91116892dc41b9ede62d1e0f3846c8fe.png

image中有一个mode属性,用来指定图片的 裁剪和缩放模式 ,常用的mode属性值如下:

scaleToFill:默认值,缩放模式,不包吃纵横比缩放图片,使图片的宽高完全拉伸至填满image元素;

aspectFit:缩放模式,保持纵横比缩放图片,使图片可以完整显示;

aspectFill:缩放模式,只保证图片的短边可以完全显示出来;

widthFix:缩放模式,宽度不变,高度自动变化(保持原图宽高比不变);

heightFix:缩放模式,高度不变,宽度自动变化(保持原图宽高比不变)。

大家可以拿来试一下。

页面导航组件,类似于html中的a链接。有机会单独出一篇博客。

在app.json文件中有一个样式版本:

https://i-blog.csdnimg.cn/blog_migrate/6568dd3f24dc13b13a63c37fb9dbe71f.png

style后面是v2是目前最新版本的样式。如果删掉,样式会发生很大变化,以按钮为例吧:

https://i-blog.csdnimg.cn/blog_migrate/ddd94cbf27bd2219061e646deae87a01.png

样式也是要基于需求的。

基本原则:在当前页面对应的.js文件中有个data,在data中定义数据,在WXML中使用数据,与Vue非常类似。

https://i-blog.csdnimg.cn/blog_migrate/b1f4a9b762d6c8012fd64de6b8bce19d.png

我们现在往里面写数据:

Mustache语法:{ {}},两个大括号 ,数据在data中定义好了,在页面中使用直接:

<view>{{要绑定的数据名称}}</view>

定义数据:

https://i-blog.csdnimg.cn/blog_migrate/04b42c07a060d5a7c3f8bdfe91e71c27.png

渲染数据:

https://i-blog.csdnimg.cn/blog_migrate/b6f2c666317ffe830ffe7fd529e30321.png

最后效果:

https://i-blog.csdnimg.cn/blog_migrate/0fbc2f13958dc7309a67b0ef0ca4e469.png

绑定内容

刚刚上面讲的就是动态绑定内容

绑定属性

比如我的wxml中有一个image,但是src不是固定的,那么我们可以动态绑定地址数据:

https://i-blog.csdnimg.cn/blog_migrate/f7d1c8f909005eb91f2bd6aacebcd0b4.png

这里需要注意一下,写法与vue稍有差别。vue中img中的src可以采取单向绑定v-bind,但是这里直接用模板语法就好了。

https://i-blog.csdnimg.cn/blog_migrate/c16efbb8adc2887411df99404508743a.png

绑定计算

在模板语法中是可以对数据进行操作的

https://i-blog.csdnimg.cn/blog_migrate/cd2e7083a6591c669ece64a0583d1bd4.png

三元运算:

https://i-blog.csdnimg.cn/blog_migrate/726e9dfc299db83d4b39a9e4f22ebed9.png

在Appdata中可以查看到全部数据:

https://i-blog.csdnimg.cn/blog_migrate/14f0024942ed7e9aa9cb004580ab4a11.png

事件是什么?==是渲染层到逻辑层的通讯方式。==渲染层(页面)->逻辑层(js代码),中间的方式是事件。

事件有哪些?点击事件,鼠标移动事件等等。

小程序中常用的事件:

类型绑定方式事件描述
tapbindtap 或 bind:tap手指触摸后马上离开,类似于Html中的click事件
inputbindinput 或 bind:input文本框的输入事件
changebindchange 或 bind:change状态改变时触发

事件回调触发,会收到一个参数event(对象),对象有这些属性:

属性类型说明
typeStringevent.type获取,反应事件类型
timestampInteger页面打开到触发事件所经过的毫秒数
targetObject触发事件的组件(遇到冒泡就是源头组件)的一些属性集合
currentTargetObject当前所绑定的组件的一些属性值集合
detailObject额外的信息
touchesArray触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouchesArray触摸事件,当前变化的触摸点信息的数组

在小程序中,通过tap事件来响应用户的触摸行为。现以bindtap为例讲解。

现给按钮绑定触摸事件:

<button type="primary" bindtap="clickit">按钮</button>

接着在js中编写回调

  // 回调
  clickit(e) {
    console.log(e)
  }

效果:

https://i-blog.csdnimg.cn/blog_migrate/c1bb39c21f3c59850fc1390f3794c486.png

通过调用this.setData(dataObject)方法,可以给页面data中的数据重新赋值。

需求:在data中定义一个count,页面上有个按钮,点击后data自增。

给按钮绑定事件:

<button type="primary" bindtap="addcount">点击后count值自增</button>

定义count:

https://i-blog.csdnimg.cn/blog_migrate/1e23359c5c89e5915c8af0b9f6f48460.png

自增代码:

    addcount() {
      this.setData({
        count: this.data.count+1
      })
    },

在vue的事件中,可以直接在函数括号内传递参数,但是小程序中不行,小程序会默认把括号内的字符串当作事件名称来处理。

传参方式:为组件提供 data-*自定义属性传参,其中 星号代表的是参数的名字。

传参方法:event.target.dataset.参数名可获取到具体的参数的值。

点击按钮后,count+2:

<button type="primary" bindtap="canshu" data-info="{{2}}">count+传参</button>
    canshu(e) {
      this.setData({
        count: this.data.count + e.target.dataset.info
      })
    },

在小程序中,通过input事件来响应文本框输入事件。

先定义文本框,注意,输入框默认是看不见的,但是鼠标过去光标会一闪一闪的。是存在的。

https://i-blog.csdnimg.cn/blog_migrate/cda8155886ac5caeb73750cc9468c754.png

在json文件中配置:

// input的内容
    inputHandler(e) {
      console.log(e.detail.value)
    },

最后的效果:

https://i-blog.csdnimg.cn/blog_migrate/846e4198c9190d8b07677fc91101ce79.png

实现步骤:

定义数据

https://i-blog.csdnimg.cn/blog_migrate/32d158fe6565679f7d4822ee502060fd.png

渲染结构

https://i-blog.csdnimg.cn/blog_migrate/55f8d40e1453215c94028eb6455e1bed.png

https://i-blog.csdnimg.cn/blog_migrate/2bf8eb027adc5edca890f13a4116f0cf.png

美化样式

https://i-blog.csdnimg.cn/blog_migrate/1cca05c68bc1ce82323df0772d80580f.png

绑定input事件处理函数

https://i-blog.csdnimg.cn/blog_migrate/3c81603929207c605e431fbe8836c7ea.png

实现同步:

https://i-blog.csdnimg.cn/blog_migrate/0010d88559cda41e358dd1741d563eb0.png

https://i-blog.csdnimg.cn/blog_migrate/b24ef7aae0e531bf0ca68fbda5f1cce9.png

在小程序中,使用wx:if="{ {}}“来判断是否需要渲染代码块

定义一个判断调价type:

https://i-blog.csdnimg.cn/blog_migrate/424d283a16e4eac80f90aa9a6cd572dd.png

使用wx:if进行条件渲染,根据type的值来展示对应信息:

https://i-blog.csdnimg.cn/blog_migrate/72d1ed96b6076ef7d9168ffe4bb1c286.png

最后结果:

https://i-blog.csdnimg.cn/blog_migrate/3f2d5437d0892f0cea9ef79a7bdbe181.png

同样还可以由elif,else:

https://i-blog.csdnimg.cn/blog_migrate/39dbf4678e94989f58421521d9d8a3b3.png

上面这个就跟if的逻辑是一样的。但是要注意的是,else中什么都不用写。

如果有多个wx:if可以使用包裹标签block进行包裹,一次性的控制内容显示或隐藏:

https://i-blog.csdnimg.cn/blog_migrate/c81dd00261b23ba3e2554662447e1edf.png

https://i-blog.csdnimg.cn/blog_migrate/f63009573d6bc15b68069f340e846ee6.png

block类似于vue中的template,不参与页面结构,不会把block渲染出来,避免渲染出一些不必要的结点。

使用hidden也可也控制元素的显示和隐藏。

设置一个flag,布尔类型:

https://i-blog.csdnimg.cn/blog_migrate/67084f6c19ab8e685c1a8d931cdf7bd2.png

在页面中使用:

https://i-blog.csdnimg.cn/blog_migrate/ca1add1458cbc1898c25c1ae5b469242.png

wx:if以动态创建和移除元素的方式,控制元素的显示和隐藏;(移除后结构不存在)

hidden以切换样式的方式,类似于display,控制元素的显示和隐藏。(结构存在但是隐藏)

使用情况:

频繁切换的时候,建议使用hidden;不频繁可以使用wx:if,目的在于提高性能。

可以根据指定的数组,循环渲染重复的组件结构。

在data中定义一个数组arr:

https://i-blog.csdnimg.cn/blog_migrate/84bb34a28c78dea8260ef4b3f4e5d283.png

接着在页面中渲染,这个我觉得比vue要高级一点,小程序中数组的index和item都是内置的,index是索引,item是索引对应的项。

https://i-blog.csdnimg.cn/blog_migrate/e0c8530f3b1c6fd67b7067aec33a013b.png

直接就可以渲染在页面中:

https://i-blog.csdnimg.cn/blog_migrate/c9ecf71f282ed0687948088b9d0bc585.png

给index和item重命名:

https://i-blog.csdnimg.cn/blog_migrate/2affcbd5f0e31a82033f20914aa7ed1c.png

类似于vue中的:key,小程序在实现列表渲染,也建议为渲染出来的列表项指定唯一的key,从而提高渲染的效率。

解释一下,这里的key是当前项的唯一标识(id),但是最好不要用index作为key使用。

设置一个数组username:

https://i-blog.csdnimg.cn/blog_migrate/a2c3e2a2553cb495a68d8754f2df57f5.png

https://i-blog.csdnimg.cn/blog_migrate/3a47c931a8e4dc270f09964ff0fa9388.png

有个建议,每用一个数组都要带上这个wx:key,是为了提高渲染性能,否则在终端中会出现黄色警告


上面的内容讲了很多,都在围绕着wxml来讲解。因为内容很多,所以分了很多个大块。后面wxss的内容较少,所以一个块讲解就够了,也就是下面的这一个。

wxss是一套样式语言,类似于css。

wxss具有大部分css特性,并且还对css进行了扩展——rpx尺寸单位于@import样式导入。

rpx是微信小程序独有的, 用来解决适配的尺寸单位。

实现原理:把所有屏幕宽度上等分为 750份 。(当前屏幕的总宽度为750rpx)

在 较小 的设备上,1rpx所代表的宽度较小;

在 较大 的设备上,1rpx所代表的宽度较大。

当小程序在不同设备上运行的时候,会自动把rpx的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配。

那么,rpx与px怎么换算?

在iphone6上(标准,标准设计稿),屏幕宽度为375px,共有750个物理像素,等分为750rpx,则1px = 2rpx,也就是说,1rpx = 0.5px;

其他手机型号换算多少会有些不一样,但是这个不影响,实际开发都是用rpx,页面会在不同设备上进行自动缩放。

使用wxss提供的@import语法,可以导入外联的样式表。

@import后面需要导入外联样式表的 相对路径 ,用;表示语句结束。

举个例子,新建一个common作为公共样式表:

https://i-blog.csdnimg.cn/blog_migrate/51f6e076d048e44db29224a13975a919.png

在内部定义公共样式:

https://i-blog.csdnimg.cn/blog_migrate/d1f1828c819623099ada01001de8e6db.png

在另一个模块导入这个样式表:

https://i-blog.csdnimg.cn/blog_migrate/be135884db4460d1595f5a3d38ca7068.png

于是在当前模块可以看到效果:

https://i-blog.csdnimg.cn/blog_migrate/13612068fe306e1a20b2738c88603a1c.png

全局样式可以理解为所有页面都遵循的样式;而局部央视只为所在页面服务。

全局样式在app.wxss中编写,而局部样式在当前页面的文件夹内部的wxss文件中编写。

注意,当局部样式和全局昂是冲突,根据就近原则,局部样式会 覆盖 全局样式

当局部样式 权重大于或等于 全局样式的权重,才会覆盖全局样式。

小程序根目录下的app.json文件是小程序的全局配置文件,常用配置:

pages:
记录当前小程序所有页面的存放路径;

window:
全局设置小程序窗口的外观;

tabBar:
设置小程序底部的tabBar效果;

style:
是否启用新版的组件样式。

一个个说吧,pages之前讲过,但是唯一要注意的是pages中的页面顺序,第一个页面是展示页面,比如下面这个,展示的就是wcs页面:

https://i-blog.csdnimg.cn/blog_migrate/ab5af47473638366d8c0bf62d4cd16da.png

style上文在讲按钮的时候也说过,style是组件的样式版本,如果改动,样式会有很大的改变。

https://i-blog.csdnimg.cn/blog_migrate/dc8befe124193ab4346658a0aa007885.png

比较重要的就是,window和tabBar。

本节的重点也在这两个上面。

window的几个部分:

头部导航栏,有微信两字的栏目;

背景区域,默认不展现,下拉展现:

https://i-blog.csdnimg.cn/blog_migrate/9a47e38e421cef8cfb7583f787a51372.png

主体部分,除却导航栏下面的展示部分。

下面是截取json中的window部分。

https://i-blog.csdnimg.cn/blog_migrate/207f13380fe07abaaf6a95e9a77ce76a.png

window中有很多常用配置项:

属性名说明
navigationBarTitleText导航栏标题文字内容
navigationBarBackgroundColor导航栏背景色
navigationBarTextStyle导航栏标题颜色,仅支持black/white
backgroundColor窗口背景色
backgroundTextStyle下拉loading样式,仅支持dark/light
enablePullDownRefresh布尔值,是否全局开启下拉刷新
onReachBottomDistance数字类型,页面上拉触底事件触发时距页面底部距离(距离底部多少px刷新页面),单位px

以上颜色几乎都是十六进制代码。

可以拿着下面这段代码去试试:

  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fc5531",
    "navigationBarTitleText": "巧克力小猫猿",
    "navigationBarTextStyle": "white",
    "enablePullDownRefresh": true,
    "backgroundColor": "#efefef",
    "onReachBottomDistance": 20
  },

最后效果:

https://i-blog.csdnimg.cn/blog_migrate/7bf7e61bb45c1d6a58bc8ab5d2049e10.png

用于实现多页面的快速切换。

小程序中分为两类:底部tabBar,顶部tabBar,如下图所示:

https://i-blog.csdnimg.cn/blog_migrate/ba9e4d23ca9361f55ff2600dc8f010da.png

注意:

tabbar内部只能配置最少两个,最多五个tab页签;

当渲染顶部tabBar,不显示icon,只显示文本。

属性名说明
backgroundColortabBar的背景色
selectediconPath选中时的图片路径
borderStyletabBar上边框的颜色
iconPath未选中时的图片路径
selectedColortab上的文字选中时的颜色
colortab上文字的默认(未选中)颜色
list(必填)tab页签的列表(最少2个最多5个)

list中每个tab项的配置选项:

属性名说明
pagePath(必填)页面路径,页面必须在pages中预先定义
text(必填)tab上显示文字
iconPath未选中 时候的图标路径
selectedIconPath选中时 图标路径

这里有个例子,可以拿去试一下:

"tabBar": {
    "selectedColor": "#00b26a",
    "list":[
      {
        "pagePath": "pages/wcs/wcs",
        "text": "样式",
        "iconPath": "/images/1.png",
        "selectedIconPath": "/images/1.png"
      }, 
      {
        "pagePath": "pages/model/model",
        "text": "模型",
        "iconPath": "/images/2.png",
        "selectedIconPath": "/images/2.png"
      },
      {
        "pagePath": "pages/list/list",
        "text": "列表",
        "iconPath": "/images/3.png",
        "selectedIconPath": "/images/3.png"
      },
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "/images/4.png",
        "selectedIconPath": "/images/4.png"
      }
    ]
  },

需要注意的是,tabBar中的页面一定要在Page属性中的前面。

页面配置在页面的json文件中,配置内容几乎与全局配置一样。

需要注意的是,当页面配置与全局配置产生冲突时,会覆盖相同的全局配置。

还有一个注意点:一般情况下,页面不需要都配置下拉刷新,是根据需要来的。所以不建议在全局配置中配置这一项。

出于安全性考虑,小程序官方对数据接口的请求做出了如下两个限制:

只能请求Https类型的接口;

必须将接口的域名添加到信任列表中;

所以做小程序,首先还是要进行接口的一些配置:

https://i-blog.csdnimg.cn/blog_migrate/38209be7781cdce618caa465e25a5a9d.png

需求:在自己的小程序中,希望请求https://www.escook.cn域名下的接口

配置步骤:

登录微信小程序管理后台–>开发–>开发设置–>服务器域名–>修改request合法域名。

https://i-blog.csdnimg.cn/blog_migrate/86c8cb1975c55099a944da965b4c4d2c.png

服务器域名设置:

https://i-blog.csdnimg.cn/blog_migrate/6851efc293c74e07b18b5cffb78b8031.png

https://i-blog.csdnimg.cn/blog_migrate/7c788b0c02fb8e6f8009d4ea6ad78bd4.png

比如说,我们的项目想请求这个接口:https://www.escook.cn,就要把这个配置到request合法域名(填写request对应的表单即可,其他不用管)。配置完后,结果:

https://i-blog.csdnimg.cn/blog_migrate/22366d31f768988c2f9dab44f2f5ce57.png

再打开开发者工具后,就自动有相关配置,我们的小程序就可以请求这个域名下的所有接口了:

https://i-blog.csdnimg.cn/blog_migrate/0649d99fe8ac9d57d931a4e161442ecd.png

注意:域名只支持https协议,且不能使用IP地址或localhost,域名必须镜柜ICP备案,且服务器域名一个月内最多可申请5次修改。

发起get请求:比如我在index中设置一个按钮,并绑定事件getInfo,点击发起get请求:

https://i-blog.csdnimg.cn/blog_migrate/cbe004a62891b14d6792a5acd56b6c1b.png

接着我们去配置getInfo,注意,这个函数与data平级:

getInfo() {
    wx.request({
      url: 'https://www.escook.cn/api/get',
      method: 'GET',
      data: {
        name: 'zs',
        age: 20
      },
      success: (res) => {
        console.log(res.data)
      }
    })
  },

运行:

https://i-blog.csdnimg.cn/blog_migrate/dba974be48404919224afad57677ea1a.png

https://i-blog.csdnimg.cn/blog_migrate/3358c23f225bf626f1c20a968d5e60e3.png


post请求:很类似,都是调用wx.request():

  postInfo() {
    wx.request({
      url: 'https://www.escook.cn/api/post',
      method: 'POST',
      data: {
        name: 'ls',
        age: 23
      },
      success: (res) => {
        console.log(res)
      }
    })
  },

https://i-blog.csdnimg.cn/blog_migrate/eb7305e158fe218376d1baaf6c624180.png

在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据: 在onload事件中调用获取数据的函数 。

就类似于vue中的mounted生命周期函数。 onload事件是微信小程序的生命周期函数,用于监听页面的加载。

当页面一加载成功就调用get和post请求:

https://i-blog.csdnimg.cn/blog_migrate/e14c37e8c44a1df4d30189038caa4f8f.png

https://i-blog.csdnimg.cn/blog_migrate/2c6e4edc8e552a4e0444c6809ed4b662.png

如果后端程序员 仅仅提供了http协议的接口,暂时没有提供https协议的接口,该怎么办?

为了不耽误开发进度,可以在微信开发者工具中,==临时开启“开发环境不校验请求域名,TLS版本及HTTPS证书”选项,跳过request合法域名的校验。

在详情里面:

https://i-blog.csdnimg.cn/blog_migrate/051a2fae96c97627e61ad63566ec8563.png

注意哦,这个没办法上线,只供 开发与调试阶段使用。

跨域问题 只存在于 基于浏览器的web开发中,由于 小程序的宿主环境 不是浏览器,而是 微信客户端 ,所以==小程序不存在跨域问题。

另外,Ajax的核心是基于 浏览器 中的XMLHttpRequest对象,而小程序 宿主环境是微信客户端 ,所以小程序 不能叫做 发“发起Ajax请求”,而是叫做“ 发起网络数据请求 ”。

页面导航指的是页面之间的相互跳转。

浏览器中,实现页面导航的方式:a连接和location.href。

小程序中也有两种方式实现页面导航:声明式导航和编程式导航。

声明式导航:

在页面上声明一个navigator的导航组件,通过点击navigator组件实现页面跳转。

可以使用navigator组件跳转到指定的tabBar页面,需要指定url属性和open-type属性。

url:表示要跳转的页面的地址,必须以/开头;

open-type:表示跳转方式,必须为switchTab。

https://i-blog.csdnimg.cn/blog_migrate/8bbdf2e7fe84aabd8e59b1e66d636aec.png

https://i-blog.csdnimg.cn/blog_migrate/c8743bdf5e2dc8cade467022a8c47890.png

非tabBar:没有配置到tabBar的页面

创建一个新的info页面,但不配置在tabBar中:

https://i-blog.csdnimg.cn/blog_migrate/fd55e306d50471424c53fa95e81d5d8b.png

跟上面的一样,我们在首页弄个链接:

https://i-blog.csdnimg.cn/blog_migrate/9a4e26d3697d5d75d85b46e75497f31e.png

点击后就可导航到info页面。

open-type值必须是navigateBack;

delta的值必须是数字,表示要后退的层级。

https://i-blog.csdnimg.cn/blog_migrate/e4304068e13eed502d3b7e9999dab228.png

编程式导航是写代码进行跳转。

调用wx.switchTab(Object Object)方法,可以跳转到tabBar页面。其中Object参数对象的属性列表如下:

属性是否必选说明
url需要跳转的tabBar页面的路径,路径后不能带参数
sucess接口调用成功后回调
fail接口调用失败后回调
complete接口调用结束的回调函数

编程式导航示例,先在首页写个按钮:

https://i-blog.csdnimg.cn/blog_migrate/bbec11eba5b9198d810ea2ab359fcf51.png

接着写跳转的相关代码:

https://i-blog.csdnimg.cn/blog_migrate/2f7da44876087d453e6d42c9a46aaedd.png

上面这个办法只适合tabBar页面。

调用vx.navigateTo(Object, Object)方法,可以跳转非tabBar的页面,其中,Object参数对象属性列表:

属性是否必选说明
url需要跳转非tabBar页面的路径,路径后不能带参数
sucess接口调用成功后回调
fail接口调用失败后回调
complete接口调用结束的回调函数

https://i-blog.csdnimg.cn/blog_migrate/ec953d9113cd2275cf8a5dcb153b146f.png

https://i-blog.csdnimg.cn/blog_migrate/795a8b180d0d9641f06c8dae47f29b4e.png

调用navigateBack(Object, Object)方法,参数对象可选属性列表:

属性是否必选说明
delta默认值为1,返回的页面数,如果delta大于现有页面数则返回到首页
sucess接口调用成功后回调
fail接口调用失败后回调
complete接口调用结束的回调函数

navigator组件的url属性用来指定将要跳转的页面路径,同时,页面路径后面可以携带参数,规则如下:

参数与路径之间用?分割;

参数键与参数值用=项链;

不同参数用&分隔

代码示例如下:

https://i-blog.csdnimg.cn/blog_migrate/aee36525c5f5f38167720153810f461f.png

我们来看一下页面参数,点击左下角的页面路径->页面参数

https://i-blog.csdnimg.cn/blog_migrate/8f513617b51bfe639667ea6db0d1e2fe.png

即可看到:

https://i-blog.csdnimg.cn/blog_migrate/fece1f544061621321c1e411f44a0712.png

与上面一样,依旧是在url中做工作

https://i-blog.csdnimg.cn/blog_migrate/899c1453899216fc77f5975a6a0705bc.png

通过 声明式导航传参或编程式导航传参 所携带的参数,可以直接在onLoad事件中直接获取到。

比如我刚刚从首页跳转到info过程中传递参数,我在info中的onLoad中打印options:

https://i-blog.csdnimg.cn/blog_migrate/306d64d1f41546c9ec812f4fec786287.png

当我们点击导航按钮,可以在控制台看到参数:

https://i-blog.csdnimg.cn/blog_migrate/b0378f117ff4b286bc81fb73124b887a.png

一般情况下都会转存到data节点中,可以用赋值的方法,在data中设置一个query:

https://i-blog.csdnimg.cn/blog_migrate/d5097a62a6cc259d617fc2813fbafeda.png

接收参数后给query赋值:

https://i-blog.csdnimg.cn/blog_migrate/a6905ba4f2c5b9dfe967c8589f1854f5.png

页面事件类似于之前学到的按钮事件。

还有一些其他的页面事件,如下拉刷新、上拉触底。本节内容主要介绍的就是下拉刷新与上拉触底。

下拉刷新指通过手指在屏幕上的下拉滑动操作,从而重新加载页面的数据的行为。

小程序默认是没有下拉刷新这种效果的,启用下拉刷新有两种方式:

全局开启下拉刷新:

在app.json这个全局配置文件中,window节点,把enablePullDownRefresh设置为true。(不推荐)

局部开启下拉刷新。

为需要的页面,在该页面的json文件下的window节点中,将enablePullDownRefresh设置为true。

在页面的.js文件中,通过onPullDownRefresh()函数即可监听当前页面的下拉刷新事件。

https://i-blog.csdnimg.cn/blog_migrate/6d2c11143389f911eb7831fad19c748f.png

这里面一般做一些重置操作。

在完成任务后(如重置),调用wx.stopPullDowwnRefresh()可停止当前页面的下拉刷新。

上拉触底,是通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。

更多用来实现分页功能。

这个其实是默认开启的。所以我们要做的是监听这个事件,可以调用:onReachBottom()函数来监听。

在页面的js文件中有这个函数:

https://i-blog.csdnimg.cn/blog_migrate/f85cf0d5989656d0d71af26cd407c9b9.png

上拉触底距离指的是触发上拉触底事件时,滚动条距离页面底部的距离。

配置方法,在json文件中:onReachBottomDistanse,后面是数字不需要带单位。

注意,以上的所有,都要开启enablePullD··ownRefresh属性才可以有效果。

做出这样的效果:

https://i-blog.csdnimg.cn/blog_migrate/6fdb05c6c8cbb041da5adfde56e2d36a.png

可以在帮助中点开微信小程序开发文档看到很多东西。这个的话,可以在数据的请求函数中加上:

https://i-blog.csdnimg.cn/blog_migrate/b94d5ce8b6e3ecb9e39da1b9888ebca4.png

当数据请求完成手动取消,与success平级:

https://i-blog.csdnimg.cn/blog_migrate/55939858850c363c5c1b83130e5d4816.png

节流,简单介绍下,就是在执行一个事情的时候给一个冷却时间,防止一次性执行多次该任务。就类比塔方类游戏,英雄技能需要冷却后才可以使用,不能一次性使用多次。

这里有一篇文章,介绍了防抖与节流:

在刷新的时候,经常要做的就是节流处理,如何进行节流处理呢?有以下三个步骤:

->在data中定义isloading节流阀:
false表示当前没有进行任何数据请求;
true表示当前正在进行的数据请求;

->在getColors()方法中修改loading节流阀:
在刚调用getColors时将节流阀设置为true;
在网路请求的complete回调函数中,将节流阀重置为false;

->在onReachBottom中判断节流阀的值,从而对数据请求进行节流控制:
如果节流阀为true,则阻止当前你请求;
如果节流阀为false,则发起数据请求。

生命周期(Life Cycle)是指一个对象从 创建->运行->销毁 的整个阶段, 强调的是一个时间段。

小程序生命周期分为两类,分别是应用生命周期与页面生命周期:

应用生命周期,特指小程序从启动->运行->销毁的过程;

页面生命周期,特指小程序中,每个页面的加载->渲染->销毁的过程。

是由小程序框架提供的 内置函数 ,会伴随着生命周期, 自动按次序运行 。

生命周期函数:允许程序员在特点的时间点,执行某些特定的操作。例如我们在前面用到的onLoad(页面刚加载时),并且在onLoad中运行一些函数,如发起网络请求。

生命周期强调的是一个时间段,生命周期函数是某个特别的时间点发生的事情。

生命周期函数也分为两类:

应用类生命周期函数,特指小程序从启动->运行->销毁期间依次调用的那些函数

页面生命周期,特指小程序中,每个页面从加载->渲染->销毁期间一次调用的那些函数。

小程序的应用生命周期函数需要在app.js中声明。

onLaunch:小程序初始化完成,执行此函数,全局只触发一次,可以做一些初始化的工作;

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

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

这里介绍下前台和后台:当我们在小程序页面时,小程序是在运行的,可以理解为前台;接着说说后台,我们直接退出微信,小程序还没有被关闭,是在后台运行的一个状态,可以理解为后台。

且后台可以点击右上角的小点:

https://i-blog.csdnimg.cn/blog_migrate/caaf89dfeeaef43960d96040b62fd32d.png

https://i-blog.csdnimg.cn/blog_migrate/a1fd2270feffe21016cf4bc48b309549.png

小程序的页面生命周期函数有五个,需要在页面的js文件中进行声明,有以下几个:

onLoad:监听页面加载,一个页面只调用一次;(初始化数据,转存参数)

onShow:监听页面显示;

onReady:监听页面初次渲染完成,一个页面只调用一次;(修改相关样式)

onHide:监听页面隐藏;

onUnload:监听页面卸载,一个页面只调用一次。

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

应用场景:wxml中无法调用在页面.js中定义的函数,但是wxml中可以调用wxs中定义的函数,因此,小程序中的wxs的典型应用场景就是 过滤器。

语法类似javaScript,看看区别:

  1. wxs有自己的数据类型:

    number数值类型、string字符串类型、boolean布尔类型、object对象类型、function函数类型、array数组类型、date日期类型、regexp正则;

  2. wxs不支持类似于ES6及以上的语法格式:

    不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc;

    支持:var定义变量、普通function函数等类似于Es5的语法。

  3. wxs遵循CommonJS规范:

    module对象、require函数、module.exports对象

wxs代码可以编写在wxml文件中的wxs标签内,就像javascript代码可以编写在html文件中的script标签内一样。

每个wxs标签,必须提供module属性,用来指定当前的wxs的模块名称,方便再wxml中访问模块中的成员。

这里来举个例子:

给某个界面加一条数据,姓名是张三,小写的zs:

https://i-blog.csdnimg.cn/blog_migrate/6d56ed1fde0c38e7a3eabec97da12424.png

现在我们想要的是,让zs由小写变为大写呈现在页面上。我们可以在页面中(wxml)嵌入一段wxs:

https://i-blog.csdnimg.cn/blog_migrate/f1cbe697852d44492efe2d0673091104.png

在上面这段嵌入中,module是必不可少的,是模块的名称,下面必须用module.exports来暴露模块,tdUpper是模块中的函数,被暴露后外部可以调用。

既然已经定义好了,那我们现在来调用即可:

https://i-blog.csdnimg.cn/blog_migrate/7d48682ba32a75070cdc2ff990671c28.png

最后可以看到效果:

https://i-blog.csdnimg.cn/blog_migrate/2491ae9c41bbde1abd4a750b44522298.png

由上面这个例子可以看出wxs的过滤器效果。

wxs代码还可以编写在 以.wxs为后缀名的文件内 ,就像javascript代码可以编写在以.js为后缀名的文件夹中一样。

先创建一个wxs为后缀的文件,刚刚写的是大写,现在我们来写小写相关的文件:

https://i-blog.csdnimg.cn/blog_migrate/b0d1acb2bf46084aa71b00af8fbafc06.png

以上就是一个wxs文件,上面写函数并且return出去,下面把函数暴露出去。 注意,wxs中不想js一样支持对象简写,所以下面的暴露需要写完整的键值对写法。

定义完后,可以使用这个脚本。在wxml中,要引入外联的wxs脚本,也要有一个wxs标签,且标签需要由module属性和src属性。

module是用来指定模块的名称;

src用来指定要引入的脚本的路径,且必须是相对路径。

给当前页面新增一条数据:

https://i-blog.csdnimg.cn/blog_migrate/b376be71c94b1966d9108646040443fe.png

接着我们在页面上引入外联的脚本:

https://i-blog.csdnimg.cn/blog_migrate/fb3124de1859f6e93af30784f4f6036f.png

接着就可以使用啦:

https://i-blog.csdnimg.cn/blog_migrate/0786b0c02970fe64ebe0dcdb61058524.png

效果如下:

https://i-blog.csdnimg.cn/blog_migrate/4508c7fa441ed98ae5e9b8cb34c3817b.png

1.wxs与js的关系

为了降低wxs的学习成本,wxs语言在设计时借鉴了大量js的语法,但本质上, wxs与javascript是两种语言。

2.wxs不能作为组件的事件回调

wxs典型的应用场景是过滤器,配合Mustache(模板语法)使用,但是不能作为组件的回调函数!如button中的bindtap后面就不能用到这个。

3.隔离性

wxs运行环境和其他javascript代码是隔离的,体现在:

wxs不能调用js中定义的函数;

wxs不能调用小程序所提供的API;

4.性能好

在IOS设备上,小程序内的WXS会比javaScriipt代码快2-20倍但;

但是在android设备上,二者的运行效率无差异。

第一步,在项目的根目录中,鼠标右键,创建components->test文件夹

https://i-blog.csdnimg.cn/blog_migrate/be0b5802193133b68ca3ea4aaac858fd.png

第二步,在新建的components->test文件夹上,鼠标右键,点击“新建Component”

https://i-blog.csdnimg.cn/blog_migrate/765d1ab8e8cb8cd654d5e0ac31937021.png

第三步,键入组件的名称后回车,会自动生成组件对应的4个文件,后缀名分别为js、json、wxml、和wxss:

https://i-blog.csdnimg.cn/blog_migrate/2106f71f1a4e663ef7f09b755f84d731.png

引用组件有两种方式,分别是 局部引用 与 全局引用 。

在页面的json文件中,引入组件,这是局部引用。

局部引用的方式:

https://i-blog.csdnimg.cn/blog_migrate/de7e9a4d4af135296cc203cde39cb279.png

这其实就把刚刚写的组件给局部引入了。

用的时候直接以标签的形式,打个比方我要在home的页面上使用刚刚引入的组件:

https://i-blog.csdnimg.cn/blog_migrate/22ece2698e3a1df9e5b3db55a7fad4e7.png

如果仅仅是局部引用,则组件只能在引入过该组件的页面使用。

小程序的组件其实与vue组件十分类似。

在全局配置文件app.json中引入:

https://i-blog.csdnimg.cn/blog_migrate/80f31c23081e41c42bbcfa17b03d5300.png

一旦全局配置,所有的页面都可以使用该组件。

根据组件的 使用频率 和 范围 。

如果某组件在多个页面中经常被用到,建议进行”全局引用“

如果某组件只在特定的页面中被用到,建议进行”局部引用”

组件和页面都是由js,json,wxml四个文件组成的,但是,组件和页面的js与json文件有明显不同:

组件的json文件中需要声明:“component” : true 属性;

组件的js文件中调用的是Component()函数;

组件的事件处理函数需要定义到methods节点中。

默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构,样式其实是有隔离的特性的。

好处:防止外界样式影响组件内部的样式;防止组件的样式破坏外界的样式。

这里说一下组件样式隔离的注意点:

vx的wxss中的全局样式对组件没有影响。

只有class选择器会有样式隔离,id、标签等都没有隔离效果,容易造成样式冲突问题。

如何修改样式隔离:

可以在json中通过stylesolation配置:

"stylesolation": "isolated"//样式隔离
"stylesolation": "apply-shared"//页面wxss样式影响在自定义组件,但自定义组件wxss中指定的样式不会影响界面
"stylesolation": "shared"//组件和页面互相影响

在组件中定义一个data:

https://i-blog.csdnimg.cn/blog_migrate/8d3e792bfe275a01953411dd60ed8936.png

事件处理函数和自定义方法需要定义到methods节点中。

可以先设置一个按钮并给按钮绑定一个事件:

https://i-blog.csdnimg.cn/blog_migrate/9f48e756adaa45af3f64ebfa2d51de1a.png

然后再写add的回调:

https://i-blog.csdnimg.cn/blog_migrate/d027e42d49a689fbd7e8582b189bf2c6.png

在小程序组件中,properties是组件的对外属性, 用来接收外界传递到组件中的数据。

组件在接收页面传递过来的参数时,需要先对参数进行配置:

https://i-blog.csdnimg.cn/blog_migrate/7d0c183d6fae6e50a0b24e1b4444df2f.png

有了这层配置,就可从页面传参到组件中了:

https://i-blog.csdnimg.cn/blog_migrate/721a275fad475e4ef954f7585d51aedf.png

https://i-blog.csdnimg.cn/blog_migrate/d4c48ed8a2a7c0b995f02597dabcd0ba.png

在小程序中,data和properties都是可读可写的,但是data更偏向于 存储组件的私有数据 ,properties更倾向于 存储外界传递到组件中的数据。

数据监听器:用于监听和响应任何属性和数据字段的变化,从而执行特定的操作,类似于vue中的watch。

监听器:与data平级:observers。

这里来放一段代码,需求是通过监听器获取sum的值:

https://i-blog.csdnimg.cn/blog_migrate/41346582c8d3b301775c10ce367afb58.png

接着看啊可能一下组件js的写法:

  data: {
    n1: 0,
    n2: 0,
    sum: 0
  },
  observers: {
    'n1, n2': function(newn1, newn2) {
      this.setData({
        sum: newn1 + newn2
      })
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    addn1() {
      this.setData({
        n1: this.data.n1 + 1
      })
    },
    addn2() {
      this.setData({
        n2: this.data.n2 + 1
      })
    }
  }

另外说一下监听对象与监听全部:rgb对象

https://i-blog.csdnimg.cn/blog_migrate/b9428f2195a49a63b15379a7d172570d.png

监听:

https://i-blog.csdnimg.cn/blog_migrate/054bd7879efb1eda7ef1a25fe5ad7fc1.png

全部:

https://i-blog.csdnimg.cn/blog_migrate/ce636e5c3ba12467fb96cee4312f574e.png

概念:纯数据字段指的是那些 不用于界面渲染的data字段。

好处:纯数据字段有助于提升页面更新的性能。

使用:在Component构造器的options节点中,指定pureDataPattern为一个正则表达式,字段名符合正则表达式则是纯数据字段。

https://i-blog.csdnimg.cn/blog_migrate/a15a2d05d00c710f4b04bb63febbae55.png

上面这个例子,凡是下划线开头都是纯数据字段:

https://i-blog.csdnimg.cn/blog_migrate/197f68b8599791d1b59d33fd6eb0016f.png

m是纯数据字段。如果要监听可以在前面加下划线。

生命周期函数描述说明
created在组件实例刚刚被创建时执行
attached在组件实例进入页面节点树时执行
ready在组件在视图层布局完成后执行
moved在组件实例被移动到节点树另一个位置时执行
detached在组件实例被从页面节点树移除时执行
error当组件方法抛出错误时执行

常用生命周期函数:

created
组件实例刚被创建好的时候,created生命周期函数会被触发;
此时还不能调用setData;
通常在这个生命周期函数中,只应该用于给组件的this添加一些自定义的属性字段


attached
在组件完全初始化完毕,进入页面节点树后,attached生命周期函数会被触发
此时,this.data已被初始化完毕
这个生命周期很欧用,绝大多数初始化的工作可以在这个时机执行(例如发起请求初始数据)

detached
当组件离开页面节点树后,detachedsmzq函数会被触发
退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数
此时适合做一些清理性质的工作

小程序的生命周期函数可以写在Component函数中,也可也再lifetimes字段内进行声明。 这是推荐方式,优先级最高 。

https://i-blog.csdnimg.cn/blog_migrate/fb5d455ff6171b4afb6a4a112cb06968.png

自定义组件的行为依赖于页面状态的变化,此时就是需要用到组件所在页面的生命周期。

生命周期函数描述
show组件所在的页面被展示时执行
hide组件所在页面被隐藏时执行
resize组件所在页面尺寸变化时执行

用法:

需要定义在pageLifetimes节点中,接着可以调用以上三个生命周期函数。

https://i-blog.csdnimg.cn/blog_migrate/2966f7568b2fb6bc0587db8a2a3ccc86.png

自定义组件wxml中,可以提供一个slot节点,用于承载组件使用者提供的wxml结构。

用白话讲一下,就是在组件中放一个坑,在使用组件的页面中去填这个坑。

单个插槽:小程序中,默认每个自定义组件中只允许使用一个slot进行占位,这种个数上的限制叫做单个插槽。

举个例子,先在组件中设置一个坑:

https://i-blog.csdnimg.cn/blog_migrate/3077d5d7f8c21539737ec58915176f1f.png

接着在页面中填上这个坑:

https://i-blog.csdnimg.cn/blog_migrate/f931a6d6a01b4707eca86a7beef7791b.png

最后就可以展示了:

https://i-blog.csdnimg.cn/blog_migrate/4096aa5b0747b66da6e6fc34527289e3.png

在options中,配置multipleSlots为true,则可以启用多个插槽。

https://i-blog.csdnimg.cn/blog_migrate/94e35dcd08e3376316829b41b8e38790.png

插槽多的时候可用具名插槽。

https://i-blog.csdnimg.cn/blog_migrate/d03db4b1ebef3b24f2fd9f4e71b292d8.png

在页面中:

https://i-blog.csdnimg.cn/blog_migrate/d9f0601af6e546252e450350add5a166.png

效果:

https://i-blog.csdnimg.cn/blog_migrate/f4713b86916a573ce214724091043349.png

三种方式:

属性绑定:
用于父组件向子组件的指定属性设置数据,仅能设置JSON兼容的数据

事件绑定:
用于子组件向父组件传递数据,可以传递任意数据

获取组件实例:
父组件还可以通过this.selectComponent()获取子组件实例对象
这样就可以直接访问子组件任意数据和方法

属性绑定用于实现 父向子传值 ,而且只能传递普通类型的数据,无法将方法传给子组件。

在父组件中设置要传给子组件的数据:

https://i-blog.csdnimg.cn/blog_migrate/55304a806bda998c1863527da0f3300f.png

在子组件的标签中传值:

https://i-blog.csdnimg.cn/blog_migrate/6dab92bd745ae078ed03dc722d1ba101.png

子组件使用properties节点声明对应属性并使用:

https://i-blog.csdnimg.cn/blog_migrate/4ffea88b4aae6fc62d72a76681052257.png

接着就可以在子组件中使用count了:

https://i-blog.csdnimg.cn/blog_migrate/051eccbf2be8471726aea4ba22cf2bde.png

事件绑定

顾名思义就是通过绑定事件来实现。

在父组件的js中,定义一个函数。这个函数将通过自定义事件的形式,传给子组件:

https://i-blog.csdnimg.cn/blog_migrate/10776e936e846757a023d1bbe2dbae4d.png

在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件(在这一步中要看清楚自定义事件是怎么定义的,前面是bind也就是绑定的意思,sync是自定义事件的名称):

https://i-blog.csdnimg.cn/blog_migrate/2ea44f0553e667eeb16d0a21d6ccb1e1.png

在子组件的js中,通过调用this.triggerEvent(‘自定义事件名称‘,{/ 参数对象 /},触发自定义事件(第二个事件是需要穿的参数):

https://i-blog.csdnimg.cn/blog_migrate/ed0159740b96a4f633c6087dad4f7d53.png

在父组件的js中,通过e.detail获取到子组件传递过来的数据:

https://i-blog.csdnimg.cn/blog_migrate/adcaaa382d4cf0446a156e7dc8a527bd.png

最后count是可以自增的:

https://i-blog.csdnimg.cn/blog_migrate/4da7b46e16243742acf7dfb7a1f4abfc.png

下面我来给大家讲下逻辑。

我们在父向子传值的时候,父组件把count通过properties声明将值传给了子组件。在父组件中引用子组件可以得到count。

接着我们的目的是,在子组件中让count自增并把结果传给父组件。

在js中可以设置自定义事件,当自定义事件被触发时,可以传递参数,并且自定义事件触发后会有一个回调函数,回调函数会用到之前传递的参数。

结合以上我们分析,在父组件中设置一个自定义事件(注意,是给子组件设置了一个自定义的事件,给谁设置就找谁触发),所以在子组件中触发了该自定义事件,在触发的同时,传递一个参数(回调函数中会用到的参数);当自定义事件被触发后,父组件中会有一个回调函数(意思是自定义事件已经被触发),在这个回调函数中可以接收到子组件传来的参数。于是收到了子组件传来的值,从而实现子向父传值的过程。

可在父组件里调用this.selectComponent(“id或class选择器”),获取子组件的实例对象,从而直接访问子组件任意数据和方法,调用时候需要传入一个选择器。

在父组件中,给子组件添加一个类名,并且设置一个按钮,添加一个绑定事件:

https://i-blog.csdnimg.cn/blog_migrate/495f898907856671d2d0d1f3a05b7d74.png

接着编辑事件:

https://i-blog.csdnimg.cn/blog_migrate/b62f0005d317e42f3ba453a0e617d626.png

效果:

https://i-blog.csdnimg.cn/blog_migrate/bf12fbd1047c573fc3967c5b5a78c33b.png

接着就可以对子组件里的数据进行操作了:

https://i-blog.csdnimg.cn/blog_migrate/947e86dfe6eefe199fb7f5343b3135c8.png

注意这里如果对数据进行赋值的话,没办法用this,因为this代表的是当前页面或组件中的数据,这里要用接收到的child。

效果:

https://i-blog.csdnimg.cn/blog_migrate/228b12321c0a40938c786fe73e285076.png

同样,也可也调用子组件的方法。(在原型上)

behaviors是小程序中,用于实现组件间代码共享的特性。这个可以类别vue3中的hook。

如果想要复习可以看下这篇博客:

工作方式:

每个behavior可以包含一组 属性、数据、生命周期函数 和 方法 。组件引用它时,它的属性、数据和方法 会被合并到组件中。

每个组件中,可以引用多个behavior,behavior也可也引用其他behavior。

首先,在项目根目录下创建一个存放behavior的文件夹

https://i-blog.csdnimg.cn/blog_migrate/d8b3a6d42e841fb17f2f6b5f0c5ca687.png

在文件夹里创建第一个behavior:

https://i-blog.csdnimg.cn/blog_migrate/be802771dd5547662309450772a2a935.png

在这个文件里,创建一个Behavior构造函数的实例对象,内部可以有 属性、数据、生命周期函数 和 方法 :

https://i-blog.csdnimg.cn/blog_migrate/973801413d7abecf9a5cfd5d188b39cf.png

把这个模块暴露出去:

https://i-blog.csdnimg.cn/blog_migrate/362f9daefa726f491fb63308c569544d.png

现在就可以导入和使用啦,使用require导入:

https://i-blog.csdnimg.cn/blog_migrate/6ad5f65661bc9366f4755f1ea2da4b97.png

后面直接用即可:

https://i-blog.csdnimg.cn/blog_migrate/0cfea8f523f86a81cf270d343c238259.png

小程序中已经支持使用npm第三方的包,从而提高小程序的开发效率,但是,在小程序中使用npm包有以下三个限制:

不支持依赖于Nodejs内置库的包;

不支持依赖于浏览器内置对象的包;

不支持依赖于C++插件的包

横批:为数不多。

是有赞的前端团队开源的一套 小程序UI组件库 ,主力开发者快速搭建小程序应用,所使用的是MIT开源许可证协议,对商业使用比较友好。

类似于element-ui。

官方文档:

https://i-blog.csdnimg.cn/blog_migrate/4659ef06e305c666f055c818fc4ef12c.png

在小程序项目中,安装Vant组件库主要分为如下3步:

通过npm安装(建议指定版本为@1.3.3)

构建npm包

修改app.json

第一步:

我们要在终端中来使用npm命令语句,小程序的终端,在开发者工具空白处鼠标点击右键,有一个在外部终端窗口中打开:

https://i-blog.csdnimg.cn/blog_migrate/7f65f1f1fc93ea084f5fb450c51b232e.png

https://i-blog.csdnimg.cn/blog_migrate/6309a6444a3ce2a9eeab6fc21620a90f.png

先初始化:

npm init -y

注意,这个地方如果报错,极大可能是因为组件名称是中文。组件名称一定要是英文才可以正常使用。

在初始化之后,这个文件有了包管理工具:

https://i-blog.csdnimg.cn/blog_migrate/e3967e5364b762096067d8642cfb2742.png

第二步:安装vant组件库

npm i @vant/weapp -S --production

https://i-blog.csdnimg.cn/blog_migrate/17a04836f202cce5788fae3109c72b8b.png

第三步:构建npm包

打开微信中的开发者工具->本地设置->点击构建npm并勾选 使用npm模块 ,之后便可以引入组件:

但是在新版本的微信开发者工具中,本地设置中找不到构建npm包了,可在工具中找:

https://i-blog.csdnimg.cn/blog_migrate/052519bde1b2d9cef11ee422878d7bae.png

https://i-blog.csdnimg.cn/blog_migrate/8237b02d021a73a26ef3550ec1a8d249.png

第四步:

修改app.json:将app.json中的"style” : “v2"去除,小程序的 新版基础组件 强行加上了许多样式,难以去除,不关闭会造成部分样式的混乱:

https://i-blog.csdnimg.cn/blog_migrate/80f7d62f1aa1b54ccf5ff56ed747b63d.png

安装完毕。

安装完Vant组件后,可以在app.json的 usingComponents 节点中引入需要的组件,即可在wxml中直接使用组件。

比如我们想使用vant提供的button组件:

https://i-blog.csdnimg.cn/blog_migrate/bf6f20e749722576be1064a09e75e38e.png

https://i-blog.csdnimg.cn/blog_migrate/8ad271c9e69922509c290e15251df8c5.png

可以在wxml中正常使用啦:

https://i-blog.csdnimg.cn/blog_migrate/eaad49e82de974cab285953d3a6c7563.png

可以正常使用:

https://i-blog.csdnimg.cn/blog_migrate/65e9e60637f3ff4e29300e85aebd2a06.png

这里如果报错,有两种主要问题:

问题一: 路径不对,可以在新增的@vant文件夹里找到要引入的组件,右键复制相对路径,再更改路径格式;

问题二:报错,找不到相关位置,这种情况一般是因为没构建npm包的原因。如果找不到可以在工具栏中找,这一步是不可以忽略的。

Vant Weapp使用 CSS变量 来实现定制主题,可以参考官方文档的主题定制,点击链接查看:

https://i-blog.csdnimg.cn/blog_migrate/6993dd5f6f6e546e23778411714c1230.png

具体可以参考官方文档。

这里以一个例子来说明:

https://i-blog.csdnimg.cn/blog_migrate/c61ef5383df1dff4c21d040e7f523645.png

上面这个按钮,红色是不是很深,不是很好看。那么这个时候,我们可以定制主题,来修改这个红色。

在 app.wxss 中,写入CSS变量,即可对全局生效:

https://i-blog.csdnimg.cn/blog_migrate/75ee4fea29a1e4e3a9ea822809c70fe2.png

几个疑问:

1.为什么使用page节点?
--作用域问题,根节点是page节点。

2.怎么知道变量名?
--官方文档,定制主题,样式变量里面有个配置文件,点开即可。

对于第二点:

https://i-blog.csdnimg.cn/blog_migrate/4f852c4b377230b9b4a9f1700a214858.png

https://i-blog.csdnimg.cn/blog_migrate/92e83cf4388c0131262cb7268bc3b520.png

这里有一篇我之前写的Promise文章,里面详细介绍了Promise的用法及其好处:

这里不再赘述。

介绍下API Promise化,指的是 通过额外的配置 ,将官方提供的,基于回调函数的异步API,升级改造为基于Promise的异步API,从而提高代码的可读性、维护性、避免回调地狱的问题。

需要依赖于 miniprogram-api-promise 这个第三方包。

npm i --save miniprogram-api-promise@1.0.4

小程序中,每安装一个包,都要进行npm构建。因为小程序无法去读node_modules这个包

在构建时,要删除这个文件:

https://i-blog.csdnimg.cn/blog_migrate/e6e139bcefef901366230074fdddbff8.png

删除后记得保存,保存完毕后,重启,从新编译,基本没有问题。

https://i-blog.csdnimg.cn/blog_migrate/f4bd70a2f9780c90daad674fc5d664fe.png

在小程序中,实现API Promise化主要依赖于miniprogram-api-promise这个第三方的npm包,它的安装和使用步骤如下:

https://i-blog.csdnimg.cn/blog_migrate/b36f6c9f174d48af18b85f1b8f4bee4d.png

接着就可以使用request,并且夹杂async和await来发起网络请求。

返回值就是一个promise对象。

全局数据共享又叫做状态管理,是为了解决组件之间的数据共享问题。

开啊中常用的数据共享方案有Vuex、Redux、MobX。

在小程序中,可以使用mobx-minprogram来配合moby-miniprogram-bingdings实现全局数据共享,其中:

mobx-miniprogram用来 创建Stroe实例对象 ;

mobx-minprogram-bindings用来把Store中的共享数据或方法,绑定到组件或者页面中去使用。

运行如下命令:

npm i --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1

注意:MobX相关包安装完成之后,记得删除miniprogram_npm目录后,重新 构建npm。

上面这段npm命令最好带版本号。没有版本号可能会报错。

首先,在项目文件夹中创建store:

https://i-blog.csdnimg.cn/blog_migrate/95ba8f520e8088ff09d65dccc04b4a72.png

在store.js中引入相关的包,并且创建构造函数:

https://i-blog.csdnimg.cn/blog_migrate/a9c1b8dd0223fce69c3711028810b6c7.png

在这个构造函数里面,可以把共享的数据挂载进去。

https://i-blog.csdnimg.cn/blog_migrate/a71ac07f89c74df93eefc932dadc2ab5.png

需要现引入action:

https://i-blog.csdnimg.cn/blog_migrate/94c5f0ed2ceaa51dce91e7fde021d8a4.png

https://i-blog.csdnimg.cn/blog_migrate/3056467d1a064985124da9a0b505e3f8.png

分包是把 一个完整的小程序项目 ,按照需求 划分为不同的子包 ,在构建时打包成不同的分包,用户在使用时 按需加载 。

分包的好处:

可以 优化小程序首次启动的下载时间 ;

在 多团队共同开发的时候可以更好的解耦协作。

分包前后项目构成:

分包前
所有页面(tabBar页面,其他页面)+
公共资源(图片、js脚本、wxs脚本、wxss样式)

分包后
1个主包(启动页面或tabBar页面,以及分包需要用到的公共资源)+
分包(只包含和当期分包有关的页面和私有资源)

结构图:

https://i-blog.csdnimg.cn/blog_migrate/f7cbb8b5903db3b33b74f94b13b54cd6.png

在小程序启动时,默认会 下载主包 并 启动主包内页面 。

(tabBar页面一定要加载到主包里面)

当客户进入分包的某个页面时, 客户端会把对应分包下载下来 ,下载完成后再进行展示。

(非tabBar页面可以按照功能的不同,分为不同的分包,这就叫做 按需下载 )

有两个限制:

主包+分包体积不超过16M;

单个分包/主包大小不能超过2M。

否则会发布失败。

以我的为例,这是我的小程序的项目结构,其中,call,home,messages是tabBar页面,要放在主包,info是非tabBar页面,而且不占用公共资源,所以是分包:

https://i-blog.csdnimg.cn/blog_migrate/a3d3fa5e8757418ec4e17f158f8f3cd4.png

现在我在 app.json 中进行分包的配置。

先配置主包的所有页面:复习一下,主包页面包括tabBar页面以及分包用到的公共资源,这是第一层配置:

https://i-blog.csdnimg.cn/blog_migrate/24457baa88c7fe528c0222c6231cf244.png

接着是分包的配置,主包配置的节点是page,分包配置的节点是 subpackages :

https://i-blog.csdnimg.cn/blog_migrate/0f706e4176a61e3cba9ee2790262a04e.png

其中,root节点是分包的根目录;name是分包的别名;pages里面存放的是根目录下所有页面的相对存放路径。

小程序会按照subpackages的配置进行分包,subpackages之外的目录将被打包到主包中;

主包也可也有自己的pages(最外层的pages字段);

tabBar页面必须在主包内;

分包之间不能相互嵌套。

主包无法引用分包内的私有资源;

分包之间不能相互引用私有资源;

分包可以引用主包内的公共资源。

独立分包的本质是 分包 ,只不过比较特殊的是,独立分包可以独立于主包和其他分包而单独运行。

示意图:

https://i-blog.csdnimg.cn/blog_migrate/4cb9cd5bbf13776654a308ce92ddcf66.png

独立分包和主包的区别: 是否依赖于主包才能运行 :

普通分包必须依赖于主包才能运行;

独立分包可以在不下载主包的情况下,独立运行。

独立分包的应用场景:

开发者可以按需,将某些 具有一定功能独立性的页面 配置到独立分包中,原因如下:

小程序从普通的分包页面启动时,需要首先下载主包;

而独立分包 不依赖主包 即可运行,可以很大程度上提升分包页面的启动速度。

配置:

在众多节点下加一个平级的

"independent": true

引用原则

独立分包和普通分包以及主包之间,是相互隔绝的, 不能相互引用彼此的资源 :

主包无法引用独立分包内的私有资源;

独立分包之间,不能相互引用私有资源;

独立分包和普通分包之间,不能相互引用私有资源;

特别注意:独立分包不能引用主包内的公共资源。

分包预下载指的是在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。

如何配置:

预下载分包的行为, 会在进入指定的页面时触发。 配置时,在app.json中使用 preloadRule 节点定义分包的预下载规则:

preloadRule与其他对象属性平级,内部是一个键值对:

https://i-blog.csdnimg.cn/blog_migrate/473f225fb8c6f0f7ff9844ace1e37db5.png

内部配置:

https://i-blog.csdnimg.cn/blog_migrate/de9a92346eee133e8679bdf97a0b0997.png

其中,第一个地址指的是,进入该页面后进行分包预下载;

packages是必填选项,意思是下载哪个包;

network不是必选,all的意思是不论什么网络都可以分包预下载,如果改成wifi那就是只有网络面膜是是wifi才可以分包预下载。

分包预下载限制:

同一个分包中的页面享有 共同的预下载大小限额2M 。

如:

https://i-blog.csdnimg.cn/blog_migrate/0ed3d2118e4f4629dd7c4ca898da9b37.png

到此为止,小程序基础相关的知识已经呈现,我来谈一下我的学习感受。

小程序在我看来,和Vue很相似,并且很多地方也与之前接触到的前端知识吻合。经常听到有人说,小程序很简单很容易上手,真正一套学下来,发现还是很有难度的。

让我觉得学习比较困难的地方是数据共享和分包这一块。在学Vue的时候就觉得数据共享非常繁琐,在小程序中虽然原理上与Vue类似,但是配置发生了改变,所以只是走马观花似的学习;在学习分包这一块,我感到困难并不是因为本身配置有多难,而是没有接触过,所以不理解为什么要这么做。

还是一句话,单凭理论知识的学习,掌握的仅仅只是冰山一角,想要掌握,还需动手做项目,真正的实战实操。

而我之所以写这篇文章的意义,是想记录学习的过程,文章本身比文档更有逻辑性,许久没看,再回顾的时候可以拾起思路,很认真的写下这篇文章,虽然很多都是从老师的课程中拿来的,但是也有很多地方夹杂了我自己的理解,链接了我往期的知识点。所以如果觉得有用,也可也关注收藏一下。而本篇文章的篇幅很长,可能会出现问题,希望大家评论区批评指正。另外有什么这方面的想法或者疑问,也可以评论区或者私信交流。

最后要说,学习是永无止境的,互联网行业的学习,更是不能断的。在这里和大家共勉,希望都能找到好的工作,以及把工作更好的发展延续下去。

后续我还会出一些小程序的其他内容,以及前端甚至架构方面的内容,也可也关注我,我会努力带给您更好的文章!!!