微信小程序知识点总结

小程序

文件结构

  • APP
    • app.js 创建App实例代码以及一些全局相关的内容
    • app.json 全局的一些配置,比如 window/tabbar
    • app.wxss 全局的一些样式配置
  • Page
    • page.js 创建Page 实例的代码, 以及页面相关内容
    • page.json 业务单独的配置,比如页面对应的 window配置,usingComponents
    • page.wxml 页面的 wxml 布局代码
    • page.wxss 页面的样式配置
  • Component
    • component.js 创建Component实例的代码,以及组件内容
    • component.json 组件内部的配置,比如当前组件使用了别的组件
    • component.wxml 组件的wxml布局代码
    • component.wxss 组件的样式配置

从0搭建项目

  • 删除项目中原有的文件(保留progect.config.js - sitemap.json)
  • 找不到app.json 所以创建一个app.json文件
  • 发现不能正确的解析
  • 在app.json 添加 { "pages ":[“home” ]} 的json配置
  • 保存上面操作后就会看到不再报错
  • 创建pages文件夹,里面创建home文件夹,将home相关的内容存放在home文件夹中
  • 修改home wxml中的代码,显示 helloworld
  • 修改样式,补齐 app.js 和 app.wxss

小程序初体验

  • 1.数据绑定
  • 2.列表渲染
  • 3.事件监听
数据绑定
  • 对标 vue中的数据绑定,在home.js 中的初始化数据 data中定义好数据
  • 在界面通过 mastach语法 引用
列表渲染
  • 对标 vue中的 v-for, 这里需要使用 wx:for="{{ students }}"
  • 跟vue不同,此处绑定后的值也需要使用双大括号语法,否则会解析为字符串
  • 然后通过 {{ item.name }} === {{ item.age }} 方式引用
事件监听
  • 首先是使用 bindtap 去绑定轻点事件,传递一个函数,不需要双大括号语法
  • 在js文件中定义这个函数,因为不同于 vue 微信小程序没有数据响应式,因此不能直接通过 this.数据 = *** 去改变页面的数据,只会更改data中数据,页面并不会同步
  • 因此小程序提供了 this.setData( { } ) 方法解决
 subCounter(){
     this.setData({
       counter: this.data.counter - 1
     })
   }

小程序的 MVVM

  • 小程序和vue 一样 使用的是 mvvm 的 设计模式
  • 编程范式也是 声明式编程,通过自身 MINA 框架 充当 viewmodel的角色使得view层和 model层建立起联系,基本和 vue 一致, 符合目前主流的MVVM开发思想
配置小程序
  • 小程序的很多开发需求被规定在配置文件中
  • 为什么这么做
    • 这样做可以更有利于我们开发的效率
    • 并且可以保证开发出来的小程序的某些风格比较一致的
    • 比如导航栏 顶部 TabBar 以及页面路由等等
  • 常见的配置文件有哪些呢?
    • project.config.json 项目配置文件,比如项目名称,appid等
    • sitemap.json 小程序搜索相关的
    • app.json 全局配置
    • page.json 页面 配置
app.json配置
project.config.json 中的配置
  • 这里面主要是配置一些版本信息,项目名称之类
sitemap.json 中配置
  • 这里主要是配置一些小程序搜索相关的
app.json 中全局配置
  • 全局配置比较多,可以查看完整的官方文档
  • pages
    • 类型 string 必填 描述:页面路径列表
  • window
    • Object 描述全局的默认窗口表现
  • tabBar
    • Object 底部 tab栏 的表现
页面配置 pages.json

每一个小程序页面也可以使用.json 文件来对本页面的窗口表现进行配置

  • 页面中配置项在当前页面会覆盖app.json 的 window中相同的配置项

小程序的双线程模型

谁是小程序的宿主环境呢? 微信客户端

  • 宿主环境为了执行小程序的各种文件 wxml文件,js文件,wxss文件
  • 提供小程序的双线程模型

双线程模型:

  • wxml模版和wxss样式运行于渲染层,渲染层使用WebView 线程渲染(一个程序有多个页面,会使用多个WebView的线程)
  • js脚本(app.js/home.js等) 运行于逻辑层,使用 JsCore运行脚本
  • 这两个线程都会经由 微信客户端 Native 进行中转交互
页面渲染过程-数据发生变化

通过setData 把 msg 数据 从 “Hello World” 编程 “GoodBay

  • 产生的JS对象对应的节点就会发生变化
  • 此时可以对比前后两个JS对象得到变化的部分
  • 然后把这个差异应用到原来的Dom树上
  • 从而达到更新UI的目的 ,这就是“数据驱动的原理”

界面渲染具体流程:

  • 1.在渲染层,宿主环境会把WXML转化为对应的JS对象
  • 2.将JS对象再次转成真实的DOM树,交由渲染层线程渲染
  • 3.数据变化时,逻辑层提供最新的变化数据,JS对象发生变化进行diff算法对比
  • 4.将最新变化的内容反映到真实的DOM树中 更新UI
小程序的启动流程
  • 1.下载小程序包
  • 2.启动小程序
  • 3.加载解析 app.json
  • 4.注册 App() -----> 执行App生命周期函数
  • 5.加载自定义组件代码,注册自定义组件
    • 加载解析page.json
    • 渲染层加载渲染 page.wxml / wxss
    • 逻辑层注册Page( ) ------> 执行Page生命周期函数
注册小程序 - 参数解析

每个小程序都需要在 app.js中调用App方法注册小程序实例

  • 在注册时,可以绑定对应的生命周期函数,在生命周期函数中,执行对应的代码
  • onLaunch 生命周期回调 ---- 监听小程序初始化,初始化后执行
  • onShow 生命周期回调----监听小程序启动或者切前台, ui显示时调用
  • onHide 生命周期回调 ------ 监听小程序切后台,关闭小程序时候执行
  • onError 错误监听函数,当发生错误时候执行
  • onPageNotFound 页面不存监听函数
  • 其他 开发者可以添加任意函数或者数据变量到Object 中 用 this可以访问
获取用户信息 - 保存全局变量(getUserInfo)

获取微信用户的基本信息的方式

  • 1.wx.getUserInfo 即将废弃的接口
  • 2.button组件 - 将open-type 改成 getUserInfo 并且绑定 bindgetuserinfo事件去获取
  • 3.使用open-data 组件展示用户信息
// 1.使用 wx.getUserInfo

//注意:此处通过this.setData修改值才能使得ui界面通过
//使用wx.getUserInfo({}) 传入一个对象,对象中传入成功  success的回调
// 因为下面需要拿到home这个this对象,在不使用第三方变量存储,bind,aplly,call 方法的情况下,使用  es6 箭头函数,保证this指针不变
 onReady: function() {
    wx.getUserInfo({
      success: res => {
        const avatarUrl = res.userInfo.avatarUrl
        const city = res.userInfo.city
        const nickName = res.userInfo.nickName
        // this.data.name = nickName
        this.setData({
          name: nickName,
          imgUrl: avatarUrl
        })
      }
    })

  }

//2.使用button按钮  修改open-type = "getUserInfo"  绑定事件bindgetuserinfo
<button bindgetuserinfo="getUserInfo"  size="mini" open-type="getUserInfo">获取信息</button>

getUserInfo(event){
    console.log(event.detail.userInfo)
  }

// 使用 open-data  展示用户信息   仅仅用于展示
<open-data type="userNickName"></open-data>
<open-data type="userAvatarUrl"></open-data>

保存全局变量

//  app.js中定义全局变量 globalData:{}
globalData:{
   name:"alger",
   age: 999
 }


// 组件里面使用  const app = getApp()方法得到这个实例,再通过 app.globalData.name  拿到全局变量
// pages/home/home.js
const app = getApp()
const name = app.globalData.name
const age = app.globalData.age

知识点开始-------------

注册App时 做什么呢?

我们来思考 : 注册App时,我们一般会做什么呢?

  • 1.判断小程序的进入场景
  • 2.监听生命周期函数,在生命周期执行对应的业务逻辑,比如某个生命周期函数中获取用户的信息
  • 3.因为App()实例只有一个,并且是全局共享的(单例对象) 所以我们可以将一些共享数据放在这里
注册page时做什么呢?

我们来思考 : 注册一个Page页面时 ,我们一般需要做什么呢?

  • 1.在生命周期函数中发送网络请求,从服务器获取数据
  • 2.初始化一些数据,以方便被wxml引用展示
  • 3.监听wxml中的事件,绑定对应的事件函数
  • 4.其他一些监听 (比如页面滚动 、上拉刷新、下拉加载更多等)
属性类型说明
dataObject页面的初始数据
onLoadfunction生命周期回调—监听页面加载
onShowfunction生命周期回调—监听页面显示
onReady
onHidefunction生命周期回调—监听页面隐藏
onUnloadfunction生命周期回调—监听页面卸载
onPullDownRefreshfunction监听用户下拉动作
onReachBottomfunction页面上拉触底事件的处理函数
onShareAppMessagefunction用户点击右上角转发
onPageScrollfunction页面滚动触发事件的处理函数
onResizefunction页面尺寸改变时触发,在手机上启用屏幕旋转支持
onTabItemTapfunction当前是 tab 页时,点击 tab 时触发
其他any开发者可以添加任意的函数或数据到 Object 参数中,在页面的函数中用 this 可以访问

Git 打tag ,切换回之前tag

git add .
git commit -m 05_小程序注册和页面
git tag 05_小程序注册和页面

git log 
git reset --hard 03231f6e3b66deb7

// 回到05_小程序注册和页面  tag的话
git checkout 05_小程序注册和页面

//回到主分支,离开这个tag
git checkout master

小程序中的组件

  • 默认情况下text的文本长按是不能被选中的, 需要的话 就添加 selectable 属性
  • space 属性 决定文本空格大小 emsp半个中文字符大小 ensp 一个中文字符大小,nbsp是默认值
  • decode属性 决定是否解码文本 需要的话 就添加 decode
text
<!-- 1. 基本使用 -->
<text>HelloWorld\n</text>
<text>你好小程序\n</text>

<!-- 2.默认情况下text的文本长按是不能被选中的 -->
<!--    将 selectable: true 即可被选中 -->
<text selectable="{{true}}">Hello CodeWang\n</text>

<!-- 3. space  决定文本空格大小 -->
<text>Hello World\n</text>
<text space="nbsp">Hello World\n</text>
<text space="emsp">Hello World\n</text>
<text space="ensp">Hello World\n</text>
 
 <!-- 4. decode  属性:是否解码文本 -->
 <text decode="{{!false}}">5 &gt; 3</text>
button
<!-- 1.基本使用 -->
<button>按钮</button>

<!-- 2.size属性 -->
<button size="mini">按钮1</button>
<button size="mini">按钮2</button>
<button></button>

<!-- 3.type 属性 -->
<button size="mini" type="primary">按钮1</button>
<button size="mini" type="default">按钮2</button>
<button size="mini" type="warn">按钮3</button>
<button></button>
 
 <!-- 4. plain 镂空效果 -->
<button plain size="mini">按钮一</button>

<!-- 5.disabled  不可用按钮 -->
<button disabled size="mini">按钮二</button>

<!-- 6.loading  小圆圈转 -->
<button loading="{{isLoading}}" size="mini" bindtap="getData">按钮二</button>

<!-- 7.hover-class -->
<button hover-class="pressed">按钮</button>

<!-- 8. open-type的取值 -->
<!-- 获取用户一些特殊的权限,可以绑定一些特殊的事件  -->
view组件(相当于前端的div)

view组件也是块级元素

  • hover-class 点击切换class属性
  • hover-start-time 点击变化开始时间
  • hover-stay-time 点击变化持续时间
  • hover-stop-propagation 阻止祖先元素的点击态
<!-- 1.基本使用  是个容器组件 -->
<view>
  <text>Hello World</text>
  <button>按钮</button>
  你好小程序
</view>

<!-- 2. hover-class属性  类似button 用户按下去时候显示的样式 -->
<!--   hover-start-time点击后开始变化时间 hover-stay-time点击后变化持续时间  -->
<view hover-class="hover-box1" class="box1" > 你好 我是view组件</view>

<!-- 3. hover-stop-propagation 阻止点击冒泡-->
<view class="box2" hover-class="hover-box2">
  <view hover-class="hover-box1" class="box1" hover-stop-propagation> 你好 我是view组件</view>
</view>
imge组件

重点:

​ 1.image 组件可以写成单标签,也可以修改成 双标签 (单标签必须以 / 结尾)

​ 2. image 组件默认有自己的大小 320 * 240

​ 3.image 是一个行内块元素 (inline-block)

  • src 下可以放远程地址或者是本地地址,本地地址可以使相对路径也可以是绝对路径
<image src="https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg"></image>
<image src="../../assets/timg.jpg" />
  • 如果我们想通过调用 本地的相册,照相机获取图片则 需要一个按钮触发一个点击事件,在点击事件方法中调用 wx.chooseImage({ success: res => { } })方法
属性类型默认值必填说明最低版本
srcstring图片资源地址1.0.0
modestringscaleToFill图片裁剪、缩放的模式1.0.0
webpbooleanfalse默认不解析 webP 格式,只支持网络资源2.9.0
lazy-loadbooleanfalse图片懒加载,在即将进入一定范围(上下三屏)时才开始加载1.5.0
show-menu-by-longpressbooleanfalse开启长按图片显示识别小程序码菜单2.7.0
binderroreventhandle当错误发生时触发,event.detail = {errMsg}1.0.0
bindloadeventhandle当图片载入完毕时触发,event.detail = {height, width}1.0.0
mode一些值:
说明最低版本
scaleToFill缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
aspectFit缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
aspectFill缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
widthFix缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
input组件
属性类型默认值必填说明最低版本
valuestring输入框的初始内容1.0.0
typestringtextinput 的类型1.0.0
passwordbooleanfalse是否是密码类型1.0.0
placeholderstring输入框为空时占位符1.0.0
placeholder-stylestring指定 placeholder 的样式1.0.0
placeholder-classstringinput-placeholder指定 placeholder 的样式类1.0.0
disabledbooleanfalse是否禁用1.0.0
maxlengthnumber140最大输入长度,设置为 -1 的时候不限制最大长度1.0.0
cursor-spacingnumber0指定光标与键盘的距离,取 input 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离1.0.0
focusbooleanfalse获取焦点1.0.0
confirm-typestringdone设置键盘右下角按钮的文字,仅在type='text’时生效1.1.0
confirm-holdbooleanfalse点击键盘右下角按钮时是否保持键盘不收起1.1.0
cursornumber指定focus时的光标位置1.5.0
selection-startnumber-1光标起始位置,自动聚集时有效,需与selection-end搭配使用1.9.0
selection-endnumber-1光标结束位置,自动聚集时有效,需与selection-start搭配使用1.9.0
adjust-positionbooleantrue键盘弹起时,是否自动上推页面1.9.90
hold-keyboardbooleanfalsefocus时,点击页面的时候不收起键盘2.8.2
bindinputeventhandle键盘输入时触发,event.detail = {value, cursor, keyCode},keyCode 为键值,2.1.0 起支持,处理函数可以直接 return 一个字符串,将替换输入框的内容。1.0.0
bindfocuseventhandle输入框聚焦时触发,event.detail = { value, height },height 为键盘高度,在基础库 1.9.90 起支持1.0.0
bindblureventhandle输入框失去焦点时触发,event.detail = {value: value}1.0.0
bindconfirmeventhandle点击完成按钮时触发,event.detail = {value: value}1.0.0
bindkeyboardheightchangeeventhandle键盘高度发生变化的时候触发此事件,event.detail = {height: height, duration: duration}2.7.0
auto-focusbooleanfalse(即将废弃,请直接使用 focus )自动聚焦,拉起键盘1.0.0
scroll-view 局部滚动组件
  • 事件监听 bindscrolltoupper bindscrolltolower bindscroll
属性类型默认值必填说明最低版本
scroll-xbooleanfalse允许横向滚动1.0.0
scroll-ybooleanfalse允许纵向滚动1.0.0
lower-thresholdnumber/string50距底部/右边多远时,触发 scrolltolower 事件1.0.0
scroll-topnumber/string设置竖向滚动条位置1.0.0
scroll-leftnumber/string设置横向滚动条位置1.0.0
upper-thresholdnumber/string50距顶部/左边多远时,触发 scrolltoupper 事件1.0.0
scroll-into-viewstring值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素1.0.0
scroll-with-animationbooleanfalse在设置滚动条位置时使用动画过渡1.0.0
enable-back-to-topbooleanfalseiOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向1.0.0
enable-flexbooleanfalse启用 flexbox 布局。开启后,当前节点声明了 display: flex 就会成为 flex container,并作用于其孩子节点。2.7.3
scroll-anchoringbooleanfalse开启 scroll anchoring 特性,即控制滚动位置不随内容变化而抖动,仅在 iOS 下生效,安卓下可参考 CSS overflow-anchor 属性。2.8.2
bindscrolltouppereventhandle滚动到顶部/左边时触发1.0.0
bindscrolltolowereventhandle滚动到底部/右边时触发1.0.0
bindscrolleventhandle滚动时触发,event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}1.0.0
共同组件
属性类型描述注解最低版本
idString组件唯一标识整个页面唯一
classString组件的样式类在对应的wxss中定义的样式类
hiddenBoolean组件是否显示所有组件默认显示
data-*Any自定义属性组件上触发事件时,会发送给事件处理函数

​ style String 组件的内联样式 可以动态设置内联样式

bind*/catch EventHandler 组件事件

wxss样式的三种书写方式

  • 1.内联样式,style="",里面以键值对形式,以分号结束
  • 2.页内样式
  • 3.全局样式
<view style="font-size:18px; color:green;">HelloWorld</view>
<view class="box">HelloWorld</view>
<view class="container">HelloWorld</view>

优先级: 行内 > 页内 > 全局

WXSS的扩展-尺寸单位

尺寸单位

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

WXSS的扩展 - 样式导入

为什么使用样式导入?

  • 在某些情况下,我们可能会将样式分在多个wxss文件中,方便对样式的管理
  • 这个时候,我们就可以使用样式导入,来让单独的wxss生效

我们可以在一个wxss中导入另一个wxss文件

  • 1.使用**@import**进行导入
  • 2.@import 后跟需要进行导入的外联样式表的相对路径(或者绝对路径也可以),用; 表示语句结束

导入的位置在哪里?

  • 可以在app.wxss中导入这个样式
  • 也可以在page.wxss导入这个样式

官方样式库

  • 为了减少开发者样式的开发的工作量,小程序官方提供了WeUI.wxss基本样式库

Mustache语法

类似vue中的 mustache语法

wx:if 与 hidden公共属性的区别

  • hidden : 将一个组件隐藏起来时,该组件依然是存在{ display:none}
  • wx:if : 将一个组件隐藏起来,该组件根本不存在(压根没有创建)
  • 选择:
    • 如果现实和隐藏切换的频率非常高,选择使用hidden
    • 如果现实和隐藏切换的频率非常低,那么选择 wx: if

block标签

什么是block标签?

  • 某些情况下,我们需要使用wx:if 或者 wx:for时 ,可能需要包裹一组组件标签
  • 我们希望对这一组组件标签进行整体的操作,这个时候怎么办呢?
    • 使用block包裹,优点: 性能更高,代码更易阅读

列表渲染 -item / index 名称(wx:for)

默认情况下,item-index的名字是固定的

  • 但是某些情况下,我们可能想使用其他名称
  • 或者当出现多层遍历的时候,名字会重复

这个时候,我们可以指定item和index的名称

<block wx:for="{{movies}}" wx:for-item="moviesItem">
  <block wx:for="{{moviesItem}}">
    <view> {{item}}</view>
  </block>
</block>

列表渲染 -key作用

我们看到,使用wx:for时 ,会报一个警告

  • 这个提示告诉我们可以添加一个key来提高性能

为什么需要这个key属性呢

  • 这个其实和小程序也使用了虚拟DOM有关系,类似于Vue React

当某一层有很多相同的节点时,也就是列表节点时,我们希望插入一个新的节点

  • 我们希望可以在B和C之间加一个F,Diff算法默认执行起来时这样的
  • 即把C更新成F , D更新成C , E更新成D,最后再插入E 是不是很没有效率

所以我们需要使用key来给每个节点做一个唯一的标识

  • Diff算法就可以正确的识别此节点
  • 找到正确的位置区插入新的节点

因此key 的作用主要是为了高效的更新虚拟DOM

个人理解:相当于有一堆苹果我找来了一堆盒子来装他们,我把盒子排成一排,每一个盒子装一个苹果,装完后你又掏出一个特别大的苹果给我,我想把这个大苹果放在这一排盒子的最前面,当没有key的时候,就相当于我不带脑子,把第一个盒子里的苹果拿出来放在第二个,第二个盒子苹果拿出来放第三个,以此类推,然后将这个最大苹果放在第一个盒子里,最后一个苹果没有盒子装,我又拿了个盒子装上他 放在最后一个。 此时会发现我把所有的苹果都拿出来了一次。 如果有key 就相当于,我直接拿来一个盒子装上这个大苹果,然后将他排在第一个位置

模板template用法

wxml提供模板,可以在模板中定义代码片段,在不同的地方调用,是一种wxml代码的复用机制

  • 使用 name属性,作为模板的名字,然后在<template/> 内定义代码片段
  • 定义的使用使用name 使用的时候通过 is 属性,在data属性中定义需要用到的变量,因为是变量因此需要用胡子语法包裹

wxml的导入方式有两种方法

import 导入:

  • 1.主要是导入template
  • 2.特点:不能进行递归导入

include引入:

  • 1.将公共的wxml的组件抽取到一个文件中
  • 2.特点:不能导入 template/wxs, 可以进行递归导入

WXS模块

WXS是小程序的一套脚本语言,结合wxml,可以构建出页面的结构

为什么要设计WXS语言呢?

  • 在WXML中是不能直接调用Page/Component中定义的函数的
  • 但是某些情况,我们可以希望使用函数来处理WXML中的数据(类似vue中的过滤器),这个时候就使用WXS了

wxs使用的限制和特点

  • WXS的运行环境和其他JavaScript代码是个例的,wxs中不能调用其他JavaScript文件中定义的函数,也不能调用小程序提供的API
  • WXS函数不能作为组件的事件回调
  • 由于运行环境的差异,在IOS设备上小程序内的WXS比Javascript快2-20倍,Android设备两者无差异

外部wxs文件定义

 var message = 'Hello World';
 var name = 'CoderWang';
 var sum = function(num1, num2) {
   return num1 + num2
 };
// console.log(sum(1,6))
 module.exports = {
   message: message,
   name: name,
   sum:sum
 }

内部引用

<wxs src="./wxs.wxs" module="info" />  
    <view>
      {{info.message}}===
      {{info.name}}====
      {{info.sum(1,2)}}
    </view>
 

注意: 此处路径只能是相对路径,且必须由module属性给这个wxs对象命名,这个是wxs抽取出去的写法

内部写法是直接一个双标签,定义module属性,内部使用wxs去操作,wxml中 通过 module定义的名字 点的方式去拿到定义i的数据,方法等

事件处理

某些组件会有自己特性的事件类型,大家可以在使用组件时候查看 具体的文档

  • 比如inputbindinput / bindblur / bindfocus
  • 比如scroll-viewbindscrolltowpper / bindscrolltotower

这里我们讨论几个组件都有的,并且也是比较常见的事件类型

touchstart / touchmove / touchend / touchcancel / tap / longpress / longtap(推荐使用 longpress事件代替)

两个注意点:

  • Tochcancle 在某些特定场景下才会触发(比如来电打断)
  • tap事件 和 longpress 事件通常只触发其中一个

事件对象的介绍

属性类型说明基础库版本
typeString事件类型
timeStampInteger事件生成时的时间戳
targetObject触发事件的组件的一些属性值集合
currentTargetObject当前组件的一些属性值集合
markObject事件标记数据
touches 和 changedTouches 区别
  • 1.在touchend中不同
  • 2.多手指触摸时不同

touches 记录着屏幕多少点正在被触摸

changedTouches 记录屏幕哪些点发生了改变

因此当第一次点上去的不离开,两者相等,一旦离开则 touches 为空,changedTouches 为还有一个对象。 当开始一个手指点上去则两者相同,后来又触发一次事件,又有两个手指点上去 此时 touches 有三个对象, 而changedTouches 只有两个,因为只有后来多了两个点,也就是变化的点

currentTarget 和 target 区别
  • currentTarget 记录的是触发事件的 view (outer)
    • 冒泡到的地方
  • target 记录的是产生事件的view (inner)
    • 点击的地方
在事件处理函数中拿到index和 item
  • 绑定事件的通过 可以绑定属性 data-index=“index” 、 data-item=“item”
事件冒泡和事件捕获

当界面产生一个事件时,事件分为捕获阶段和冒泡阶段

事件捕获

  • 外到内依次捕获

事件冒泡

  • 内到外 依次冒泡

bind 和 catch区别:

  • bind:一层层传递 , catch阻止事件的进一步传递

1.捕获阶段触发事件 使用 capture-bind:tap 的方式 注意需要使用: 不然无法捕获

2.当点击触发一个事件的时候,内部是先从最外层进行事件捕获,一层一层捕获到最内层,然后从最内层一层一层冒泡到最外层,这是一条顺序链,期间任何一处 使用 catch触发,而不用bind则会阻止事件进一步捕获或者是冒泡

组件化开发

类似于页面,自定义组件也是有 json wxml wxss js4个文件组成

  • 按照好的编程习惯,我们会先在根目录下创建一个文件夹components,里面存放我们之后自定义的公共组件
  • 常见一个自定义组件my-cpn : 包含对应的四个文件

自定义组件的步骤:

  • 首先需要在json文件中进行自定义组件声明(将component字段设为 true 才会是这一组文件为自定义组件)
  • 在WXML中编写属于我们组件自己的模板
  • 在wxss中编写属于我们组件自己的相关样式
  • 在js文件中可以定义数据或组件内部的相关逻辑

自定义组件使用的步骤

  • 在使用的页面的json文件中进行一个声明

  • {
     "usingComponents": {
        "my-cpn":"/components/my-cpn/my-cpn"
      }
    }
    
  • 以键值对形式传入 到usingComponents中 键是 之后使用组件的标签名,值是路径 , 可以相对路径,也可以绝对路径

一些注意点

  • 标签名只能是小写字母中划线下划线的组合
  • 自定义组件也是可以引用自定义组件的,引用方法类似于页面引用自定义组件的方式(使用usingComponents字段)
  • 自定义组件和页面所在项目根目录不能以 'wx-'为前缀,否则容易出错
  • 如果在app.json的usingComponents声明某个组件,那么所有页面和 组件可以直接使用该组件
组件的样式细节

组件内的样式对外部样式的影响

  • 结论一:组件内的class样式,只对组件wxml内的节点生效,对于引用组件的Page页面不生效
  • 结论二:组件内不能使用id选择器,属性选择器,标签选择器

外部样式对组件内样式的影响

  • 结论一:外部使用class的样式,只对外部wxml的class生效,对组件内是不生效的
  • 结论二:外部使用了id选择器,属性选择器不会对组件内产生影响
  • 结论三:外部使用了标签选择器,会对组件内产生影响

整体结论:

  • 组件内的class样式和组件外的class样式,默认是有一个隔离效果的
  • 为了防止样式的错乱,官方不推荐使用id,属性,标签选择器
样式的相互影响

如何让class可以相互影响

  • 在Component对象中,可以传入一个option属性,其中options属性中有一个stylesolation(隔离)属性,stylesolation有三个取值
    • isolate表示启用样式隔离,在自定义组件内外,使用class指定的样式将不会相互影响(默认)
    • apply-shared 表示页面wxss样式将影响到自定义组件,但自定义组件wxss中指定的样式不会影响页面
    • shared表示wxss样式将影响到自定义组件,自定义组件wxss中指定的样式也影响页面的其他设置

组件和页面通信

很多情况下,组件内展示的内容(数据,样式,标签),并不是在组件内写死的,而且可以由使用者来决定

页面 --------> 组件

  • 数据:properties 样式:externalClasses 标签: slot
想组件传递数据- properties

参考vue的 props

给组件传递数据:

  • 大部分情况下,组件只负责布局和样式,内容是由使用组件的对象决定的
  • 所以,我们经常需要从外部传递数据给我们的组件,让我们的组件进行展示,如何传递呢
  • 使用properties属性

支持的类型

  • String Number Boolean
  • Object Array null (不限制类型)
// 组件内
 properties: {
    title:{
      type:String,
      value:'HELLO'
    }
  }

// 页面内
<my-properties title="{{message}}" />
<my-properties title="你好呀" />
<my-properties title="helloWorld" />
向组件传递样式-externalClasses

给组件传递样式

  • 有时候我们不希望将样式在组件内固定不变,而是外部可以决定样式

  • 这个时候我们可以使用externalClasses属性

    1.在Component对象中,定义externalClasses属性

    2.在组件内的wxml中使用externalClasses属性中的class

    3.在页面中传入对应的class,并且给这个class设置样式

组件使用 externalClasses 【与properties同级】, 他对应一个数组,数组的值就是页面传入的属性名,并且这个属性名要在组件页面上添加到对应的元素的class上,页面添加该属性,传入一个定义好的class类名,即可将这个class类名的样式传递给了这个组件响应的class上

/* 组件内使用这个类名 */
<view class="title boxstyle">{{title}}</view>

/* 组件内注册添加 externalClasses  他对应一个数组 */
externalClasses:[
    'boxstyle'
  ]

/* 页面内使用externalClasses 注册的名字做属性名,接收一个自己定义好的样式类 */
<my-cpn boxstyle="border" />

/*页面样式中给这个样式类添加好样式*/
.border{
  color: yellow!important;
  background-color: #ccc;
  border:2px solid #eee;
}
组件向外传递事件-自定义事件

1.组件内监听事件,需要页面做出相应的操作,则组件内事件触发的时候需要通知都页面,因此需要发射一个事件,类似vue中的this.$emit( )

2.组件内发射事件使用 this.triggerEvent( ‘发射的事件名’, ‘需要传递过去的参数’,[option])

3.页面中通过 bind:‘事件名’ = 操作函数 绑定事件,并且对应触发一个方法

4.此时这个方法中就可以操作 页面中的数据了,并且函数触发,说明组件内的事件触发了,当然组件传递的参数,这个存在这个方法的 event参数中,在event.detail中

页面直接调用组件修改数据/方法

页面通过this.selectComponent()方法去拿到这个组件对象 ,括号内可以使class选择器或者 id选择器 类似 querySelecter()

  • 拿到对象后虽然后通过对象 . setData方法直接修改组件内数据,但是不建议这么做,修改对应组件的数据还是需要在对象组件内去处理
  • 因此我们在组件定义一个想修改数据的方法,然后通过调用这个方法去修改数据
插槽

slot翻译为插槽

  • 在生活中很多地方都有插槽,电脑的usb插槽,插板当中的电源插槽
  • 插槽的目的是让我们远离的设备具备更多的扩展性

插槽用法类似于vue中 slot

一般使用

  • 直接组件中使用一堆 slot标签占位
  • 页面中在组件标签内添加内容标签就会匹配到这个slot标签中

多slot使用

  • 首先组件内的slot需要给一个 name属性,用于后续页面中通过slot="***" 去匹配这个slot
  • 虽然上面一步完成,但是还是不能匹配,因为我们还需要在组件的json配置中添加上multipleSlots:true
组件Component

传入对象,对象中可传参数:

  • properties 定义传入的属性
  • data 定义内部的属性
  • methods 定义方法
  • options 额外配置
    • styleIsolation : “shared” 【是否隔离组件内样式跟页面的样式】
    • multipleSlots : true 【多插槽使用的时候需要设置为true】
  • externalClasses 引入外部样式
    • 跟properties相似,页面通过属性传值,值是页面的一个样式类,组件在externalClasses中接收,并将这个接收的属性作为class类绑定到组件的元素上
  • observers 属性和数据监听
    • 类似vue的 watch,对象中传入函数,函数默认传参 newValue 注意组件内这个属性没有 oldValue
  • pageLifetimes 页面生命周期
    • 可以监听所在页面的生命周期
    • show() 页面显示执行
    • hode() 页面隐藏执行
    • resize() 页面尺寸发生变化执行
  • lifetimes 组件生命周期
    • created 组件被创建执行
    • attached 组件被添加到页面中执行
    • moved 组件被移动到节点树另一个位置时候执行
    • detached 组件被移除时候执行

系统API(网络请求)

网络请求-基本使用

微信提供了专属的API接口,用于网络请求:wx.request(Object object)

属性类型默认值必填说明最低版本
urlstring开发者服务器接口地址
datastring/object/ArrayBuffer请求的参数
headerObject设置请求的 header,header 中不能设置 Referer。 content-type 默认为 application/json
timeoutnumber超时时间,单位为毫秒2.10.0
methodstringGETHTTP 请求方法
dataTypestringjson返回的数据格式
responseTypestringtext响应的数据类型1.7.0
successfunction接口调用成功的回调函数
failfunction接口调用失败的回调函数
completefunction接口调用结束的回调函数(调用成功、失败都会执行)
展示弹窗

主要有 showToast showModel showLoading showActionSheet

属性类型默认值必填说明最低版本
titlestring提示的内容
iconstring‘success’图标
imagestring自定义图标的本地路径,image 的优先级高于 icon1.1.0
durationnumber1500提示的延迟时间
maskbooleanfalse是否显示透明蒙层,防止触摸穿透
successfunction接口调用成功的回调函数
failfunction接口调用失败的回调函数
completefunction接口调用结束的回调函数(调用成功、失败都会执行)

object.icon 的合法值

说明最低版本
success显示成功图标,此时 title 文本最多显示 7 个汉字长度
loading显示加载图标,此时 title 文本最多显示 7 个汉字长度
none不显示图标,此时 title 文本最多可显示两行,1.9.0及以上版本支持
示例代码
wx.showToast({
  title: '成功',
  icon: 'success',
  duration: 2000
})
注意
  • wx.showLoading 和 wx.showToast 同时只能显示一个
  • wx.showToast 应与 wx.hideToast 配对使用
页面分享

分享是小程序扩散的一种重要方式,小程序中又两种风险方式:

  • 点击右上角菜单按钮,之后点击转发
  • 点击摸一个按钮直接转发

当我们转发给好友一个小程序时,通常小程序中会显示一些信息

  • 如何决定这些信息的展示呢 通过 onShareAppMessage

每个页面都有各种 生命周期函数,data等,包括onShareAppMessage(){ }

这里面

onShareAppMessage(Object object)

监听用户点击页面内转发按钮(button 组件 open-type="share")或右上角菜单“转发”按钮的行为,并自定义转发内容。

注意:只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮

onShareAppMessage(){ }函数需要返回一个 对象

对象中的参数:

  • title 转发界面的标题
  • path 别人点击转发内容进入的路径
  • imageUrl 转发界面的图片
小程序的登录流程
  • 1.调用wx.login 获取code
  • 2.调用wx.request发送code到我们自己的服务器(我们自己的服务器会返回一个登录态的标识比如token)
  • 3.将登录态的标识token进行存储,一边下次使用
  • 4.请求需要登录态标识的接口时,携带token

演练接口 http://123.207.32.32:3000/login

页面跳转

页面的跳转有两种方式,通过navgator 组件和通过wx的API跳转

navigator 组件主要就是用于界面的跳转

<navigator url="/pages/detail/detail">跳转</navigator>
属性类型默认值必填说明最低版本
targetstringself在哪个目标上发生跳转,默认当前小程序
urlstring当前小程序内的跳转链接
open-typestringnavigate跳转方式
deltanumber1当 open-type 为 ‘navigateBack’ 时有效,表示回退的层数
app-idstringtarget="miniProgram"时有效,要打开的小程序 appId
pathstringtarget="miniProgram"时有效,打开的页面路径,如果为空则打开首页
extra-dataobjecttarget="miniProgram"时有效,需要传递给目标小程序的数据,目标小程序可在 App.onLaunch()App.onShow() 中获取到这份数据。详情
versionstringreleasetarget="miniProgram"时有效,要打开的小程序版本
hover-classstringnavigator-hover指定点击时的样式类,当hover-class="none"时,没有点击态效果
hover-stop-propagationbooleanfalse指定是否阻止本节点的祖先节点出现点击态
hover-start-timenumber50按住后多久出现点击态,单位毫秒
hover-stay-timenumber600手指松开后点击态保留时间,单位毫秒
bindsuccessstringtarget="miniProgram"时有效,跳转小程序成功
bindfailstringtarget="miniProgram"时有效,跳转小程序失败
bindcompletestringtarget="miniProgram"时有效,跳转小程序完成
navigator组件的 open-type的取值
说明最低版本
navigate对应 wx.navigateTowx.navigateToMiniProgram 的功能
redirect对应 wx.redirectTo 的功能
switchTab对应 wx.switchTab 的功能
reLaunch对应 wx.reLaunch 的功能
navigateBack对应 wx.navigateBack 的功能
exit退出小程序,target="miniProgram"时生效
  • redirect:关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到tabbar页面,并且 不能返回(不是一个压栈)
  • switchTab: 跳转到tabBar页面,并关闭其他所有非tabBar页面(需要在tabbar中定义)
  • reLaunch: 关闭所有页面,打开应用中某个页面(直接展示某个页面,并且可以跳转到tabbar页面)
总结:
  • 使用 navigator 组件 , 给一个url地址就可以跳转了,默认 open-type 为 navigate ,这个只是用新的页面层叠旧页面,原来的页面还在,此时可以左上角返回,或者 创建navigator 组件,定义open-type 为 navigateBack 就可以返回了
  • 当使用redirect 时候,效果跟 navigate 一样,但是不是层叠旧页面 而是直接销毁其他页面,进入新页面,因此无法返回,使用 navigateBack 也不行
  • 当使用 switchTab 相当于模拟了 点击tabbar操作,并且,无法返回
  • 当使用 reLaunch 则是关闭所有页面,然后打开应用中的某个页面,跟redirect 不同的是 redirect是关闭当前页面,而reLaunch是 关闭所有页面
  • 当然 open-type 属性中的navigateBack 中的delta 设置跳回哪一层, 1是返回上一层,2是返回上上层
  • 当路由定义在了 tabBar中时候,不能通过 navigate 跳转 只能通过 switchTab去跳转
跳转过程中的数据传递

正向传递 使用 query字段

  • 直接在url 后面拼接,进行传递
  • 在对应onLoad中的 参数 option 中就会有传递的数据

点击返回,反向传递(没有直接的方法)

  • 可以在生命函数 onUnload 中传递数据
    • onUnload函数是页面关闭的时候触发
    • 在这个函数中调用 getCurrentPage( )可以拿到活跃的页面对象,
    • 如果想拿到上一页的page对象,只需要使用 getCurrentPage( )[getCurrentPage( )-2]即可
    • 然后就可以调用page对象的 setData({ }) 方法去更改对象中的数据了
在js中定义跳转

方法基本和组件的方式相似

  • navigateTo
  • redirectTo
  • 返回的时候 则是 navigateBack
总结
  • 使用 按钮等定义事件,用户触发事件后调用定义好的函数,定义函数中设置navigateTo, redirectTo ,参数传入一个对象,对象中传入跳转的 url
  • 返回的话 使用 navigateBack 参数对象中 添加属性 delta 可以设置返回上几层
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值