微信小程序笔记

1.JSON配置

2.WXML语法

2.1.数据绑定

WXML 中的动态数据均来自对应 Page 的 data。

数据绑定使用 Mustache 语法(双大括号)将变量包起来;

<view wx:if="{{condition}}"> </view>
<view wx:for="{{list}} " wx:for-index="index" wx:for-item="itemName">
  {{item}}
</view>

2.2.逻辑语法

2.3.条件逻辑

2.4.列表渲染

2.5.模板

template页面模板

模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的 <wxs /> 模块。

// 定义模板
<template name="msgItem" >
  <view wx:for="{{list}}">
    <text> {{item.aaa}} </text>
  </view>
</template>

// 使用模板
<template is="msgItem" data="{{list}}"/>
slot组件模板

组件模板的写法与页面模板相同。组件模板与组件数据结合后生成的节点树,将被插入到组件的引用位置上。

在组件模板中可以提供一个 <slot> 节点,用于承载组件引用时提供的子节点。

普通自定义模板:

<!-- 组件模板,文件夹命名为component-tag-name  -->
<view class="wrapper">
  <view>这里是组件的内部节点</view>
  <slot></slot>
</view>
<!-- 引用组件的页面模板 -->
<view>
  <component-tag-name>
    <!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
    <view>这里是插入到组件slot中的内容</view>
  </component-tag-name>
</view>

组件 wxml 的 slot:

比如下拉刷新组件,页面模板可能头部和底部不需要刷新,中间列表部分才需要刷新,那么在刷新组件模板里就可以在顶部写一个<slot name="header"></slot>插槽,在页面模板里的头部包一个<view slot="header">头部内容</view>,底部同理。

比如长列表滚动组件,页面模板可能头部和底部不需要滚动,中间列表部分才需要滚动,只需在组件头部和底部添加插槽即可;

<!-- 组件模板,文件夹名为component-tag-name -->
<view class="wrapper">
  <slot name="before"></slot> // 显示:这里是插入到组件slot name="before"中的内容
  <view>这里是组件的内部细节</view>
  <slot name="after"></slot> // 显示:这里是插入到组件slot name="after"中的内容
</view>
<!-- 引用组件的页面模板 -->
<!-- 需要先在json里面注册组件component-tag-name -->
<view>
  <component-tag-name>
    <!-- 这部分内容将被放置在组件 <slot name="before"> 的位置上 -->
    <view slot="before">这里是插入到组件slot name="before"中的内容</view>
    <!-- 这部分内容将被放置在组件 <slot name="after"> 的位置上 -->
    <view slot="after">这里是插入到组件slot name="after"中的内容</view>
  </component-tag-name>
</view>

2.6.共同属性

属性名类型描述注解
idString组件的唯一标识整个页面唯一
classString组件的样式类在对应的 WXSS 中定义的样式类
styleString组件的内联样式可以动态设置的内联样式
hiddenBoolean组件是否显示所有组件默认显示
data-*Any自定义属性组件上触发的事件时,会发送给事件处理函数
bind*/catch*EventHandler组件的事件

3.小程序的宿主环境

3.1.数据驱动

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

3.2.生命周期

​ 页面初次加载的时候,微信客户端就会给Page实例派发onLoad事件,Page构造器参数所定义的onLoad方法会被调用,onLoad在页面没被销毁之前只会触发1次,在onLoad的回调中,可以获取当前页面所调用的打开参数option,关于打开参数我们放在这一节的最后再展开阐述。
页面显示之后,Page构造器参数所定义的onShow方法会被调用,一般从别的页面返回到当前页面时,当前页的onShow方法都会被调用。
在页面初次渲染完成时,Page构造器参数所定义的onReady方法会被调用,onReady在页面没被销毁前只会触发1次,onReady触发时,表示页面已经准备妥当,在逻辑层就可以和视图层进行交互了。

onLoad(Object query)

页面加载时触发。一个页面只会调用一次(小程序初始化完成时触发,全局只触发一次),可以在 onLoad 的参数中获取打开当前页面路径中的参数。

参数:

名称类型说明
queryObject打开当前页面路径中的参数
onShow()

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

onReady()

页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。

注意:对界面内容进行设置的 API 如wx.setNavigationBarTitle,请在onReady之后进行。详见生命周期

onHide()

页面隐藏/切入后台时触发。 如 wx.navigateTo 或底部 tab 切换到其他页面,小程序切入后台等。

onUnload()

页面卸载时触发。如wx.redirectTowx.navigateBack到其他页面时。

3.3.事件

常见的事件类型:前面加bind

类型触发条件
touchstart手指触摸动作开始
touchmove手指触摸后移动
touchcancel手指触摸动作被打断,如来电提醒,弹窗
touchend手指触摸动作结束
tap手指触摸后马上离开
longpress手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
longtap手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
transitionend会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart会在一个 WXSS animation 动画开始时触发
animationiteration会在一个 WXSS animation 一次迭代结束时触发
animationend会在一个 WXSS animation 动画完成时触发

4.JS语法

4.1.自定义组件

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

定义段类型是否必填描述最低版本
propertiesObject Map组件的对外属性,是属性名到属性设置的映射表
dataObject组件的内部数据,和 properties 一同用于组件的模板渲染
observersObject组件数据字段监听器,用于监听 properties 和 data 的变化,参见 数据监听器2.6.1
methodsObject组件的方法,包括事件响应函数和任意的自定义方法,关于事件响应函数的使用,参见 组件间通信与事件

properties里定义的是组件对外要开发的属性,在data里定义的是在组件里自己使用的私有的数据。

4.2.事件

1.什么是事件
  1. 事件是视图层到逻辑层的通讯方式。
  2. 事件可以将用户的行为反馈到逻辑层进行处理。
  3. 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  4. 事件对象可以携带额外信息,如 id, dataset, touches。
2.bindtap和catchtap的区别
  1. 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
  2. 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

一般采用bandtap或者是catchtap进行事件绑定,

bindtap是冒泡事件,catchtap是非冒泡事件

3.事件携带的参数

currentTarget

事件绑定的当前组件。

属性类型说明
idString当前组件的id
datasetObject当前组件上由data-开头的自定义属性组成的集合

例子:(还包含了自定义data-属性)

<view class="service-item" catchtap="toService" data-url="/pages/setting/list/index" data-status="123">
        <view class="service-item-title">
          <sc-icon name="setting" class="icon-left" size="34rpx" color="#2A2B2F"></sc-icon>
          <label>设置</label>
        </view>
        <sc-icon name="circle-right" color="#A8A8A8" size="28rpx"></sc-icon>
      </view>
toService(event) {
    const { url,status } = event.currentTarget.dataset;
    if (url) {
      // 跳转路径
      wx.navigateTo({
        url: url,
      })
      // 跳转并携带参数
      wx.navigateTo({
        url: `/pages/order/list/index?status=${status}`
      })
    }
  },

dataset

在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。在 WXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接。

detail

自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。点击事件的detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。

4.4.常用事件

WXML的冒泡事件列表:

类型触发条件最低版本
touchstart手指触摸动作开始
touchmove手指触摸后移动
touchcancel手指触摸动作被打断,如来电提醒,弹窗
touchend手指触摸动作结束
tap手指触摸后马上离开

5.项目

5.1.目录

1.common:api文件里是各部分的api接口的url

2.components:公共组件,在pages里各文件的json里引入就能用了。有些在公共的app.json里已经引过了。

3.models:js文件,pages里各部分的接口调用在这个里面

4.pages:各部分的界面代码

5.template:所有的template模板都写在这

6.utils:request的封装,cache数据的缓存,计算方法等

7.app.js: App()里是公共的方法(例如登录方法),在其他页面使用getApp()可以调用app.js里的公共方法,

pages各部分:

js:调接口时,接口url和封装在models里面的对应js里和common里面的api文件里,

json:组件引用时,在页面的json文件里引入要用到的组件

5.2.标签(Vant Weapp组件)

block:并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

5.3.样式

0.要修改组件的样式需要加!important

1.flex 是 flex-grow、flex-shrink、flex-basis的缩写。

flex:1;相当于flex-grow: 1;

多个弹性元素,不设置的默认为flex-grow: 0;

设置flex-grow: 1;的元素会将父元素剩余的空间撑满,

2.均匀分布:

display: flex; // 设有该属性的元素,子元素若有固定宽度的,不固定宽度的则默认占满剩余宽度,不用额外设置 justify-content: 属性;
justify-content: space-between; // 弹性盒对象的子元素各项周围留有空白;
align-items: center; // 子元素各自都居中对齐,不设置的话子元素都顶对齐,
align-items: baseline; //元素位于容器的基线上。比如都底对齐,
flex-direction: column; // 垂直居中
height:100%;// 垂直居中又均匀分布时须设置高度

3.长文本:

overflow: hidden;//超过指定的宽度和高度也隐藏
white-space: nowrap; 所有的文本都显示在这一行
text-overflow: ellipsis; 多余的文本用省略号显示
min-width:0; // 父元素须设置宽度,

4.居右下:

position: absolute;
right: 0;
bottom: 0;
// 别忘了父级元素设置相对定位;
// 元素布局覆盖,可用绝对定位,再调上下左右距离;

5.display:grid; // 网络布局

display:grid;   // 网络布局
grid-template-columns:30% 30% 40%;  // 三三四 三列分
grid-template-rows:auto; // 行高度,例100rpx
// grid-row-gap: 20rpx; // 行间距
// grid-column-gap: 20rpx; // 列间距
// child 间的分隔样式
.item:not(:last-child):before {
  border-right: 1px dashed #A8A8A8;
  content: " ";
  height: 100%;
  width: 1px;
  right: 0;
  position: absolute;
}

6.背景线性渐变:background: linear-gradient(0deg, #F63731 0%, #FFD7A7 100%)

5.4.事件

1.this.selectComponent(“”)获取子组件的实例对象

在父组件里调用 this.selectComponent("#id"),可以获取子组件的实例对象,这样就可以直接访问子组件的任意数据和方法。

2.this.triggerEvent()自定义组件触发事件

在对组件进行封装时,在当前页面(父)想要获取组件(子)中的某一状态,需要使用到this.triggerEvent(’ ',{}), 第一个参数是自定义事件名称,这个名称是在页面调用组件时bind的名称,第二个对象就可以拿到想要的属性。

<!-- 在父组件中 -->
<view class="plus-cart-view">
  <sc-stepper value="{{ cartMap[item.mallGoodsId] }}" bind:plus="plus" item="{{ item }}" bind:minus="minus" ></sc-stepper>
</view>
// 父组件方法
plus(event) { // 获取到自定义组件触发事件时提供的detail对象
  this.onPlus(event.detail)
},
minus(event) {
  this.onMinus(event.detail)
}
<!-- 在自定义组件中 -->
<view class="sc-stepper">
  <view class="sc-stepper-minus" catchtap="minusClick">
  </view>
  <view class="sc-stepper-value">{{currentValue}}</view>
  <view class="sc-stepper-plus" catchtap="plusClick"></view>
</view>
// 子组件(点击minusClick这个按钮将触发“minus”事件)
minusClick(event) {
  this.triggerEvent('minus', event)
},
plusClick(event) {
  this.triggerEvent('plus', event)
},
3.组件间通信

组件间的基本通信方式有以下几种。

  • WXML 数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据(自基础库版本 2.0.9 开始,还可以在数据中包含函数)。具体在 组件模板和样式 章节中介绍。

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

  • 如果以上两种方式不足以满足需要,父组件还可以通过 this.selectComponent 方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法。

    例子:

 // 父组件  
 // 修改
  handleEdit(event) {
    const { item } = event.currentTarget.dataset;  // 组件上由`data-`开头的自定义属性组成的集合,携带的参数
    wx.navigateTo({
      url: '/pages/address/edit/index',
      events: {
        // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
        acceptDataToEditPage: function(data) {
          console.log(data) // 被打开页面传送到当前页面的数据
        },
        someEvent: function(data) { // 其他事件
          console.log(data)
        }
  	  },
      success: function (res) {
        // 通过eventChannel向被打开页面传送数据data
        res.eventChannel.emit('acceptDataToEditPage', { data: item })
      }
    })
  },
  // 子组件
  onShow() {
    const that = this;
    const eventChannel = this.getOpenerEventChannel()
    // 监听acceptDataToEditPage事件,获取上一页面通过eventChannel传送到当前页面的数据
    if (eventChannel && eventChannel.on) {
      eventChannel.on('acceptDataToEditPage', function (data) {
        // data是从上一个页面传递过来的数据
        const newData = data.data
        that.setData({
          ...newData,
          sex: newData.nameLabel,
          addressInfo: newData
        })
      })
    }
  },
4.页面间事件通信通道的方法:
[EventChannel.emit(string eventName, any args)]

// 触发一个事件(方法名,参数)

[EventChannel.on(string eventName, EventCallback fn)]

// 持续监听一个事件

[EventChannel.once(string eventName, EventCallback fn)]

// 监听一个事件一次,触发后失效

[EventChannel.off(string eventName, EventCallback fn)]

// 取消监听一个事件。给出第二个参数时,只取消给出的监听函数,否则取消所有监听函数

6.防抖

如果短时间内大量触发同一事件,只会执行一次函数。

function debounce(fn,delay){
    let timer = null //借助闭包
    return function() {
        if(timer){
            clearTimeout(timer) 
        }
        timer = setTimeout(fn,delay) // 简化写法
    }
}
// fn函数
function showTop  () {
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
  console.log('滚动条位置:' + scrollTop);
}
window.onscroll = debounce(showTop,1000)

对于短时间内连续触发的事件(上面的滚动事件),防抖的含义就是让某个时间期限(如上面的1000毫秒)内,事件处理函数只执行一次。

节流:

如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。

5.this.setData

简介:setData函数主要用于将逻辑层数据发送到视图层,同时对应的改变this.data.x的值。

注意:

1.不能直接修改this.data,而不调用this.setData(),是无法改变当前页面的状态的,会导致数据不一致

2.仅支持可以JSON化的数据

3.单次设置的数据不能超过1024KB,尽量避免一次设置过多的数据

4.不要把data中的任何一项的value设为undefined,否则这一项将不能被设置,可能会有潜在的问题

8.wxs文件

每个 wxs 模块均有一个内置的 module 对象。

exports: 通过该属性,可以对外共享本模块的私有变量与函数

// /pages/tools.wxs

var foo = "'hello world' from tools.wxs";
var bar = function (d) {
  return d;
}
module.exports = {
  FOO: foo,
  bar: bar,
};
<!-- page/index/index.wxml -->
<wxs src="./../tools.wxs" module="tools" />
<view> {{tools.bar(tools.FOO)}} </view>

9.页面跳转

 wx.navigateTo(OBJECT)

//保留当前页面,跳转到应用内的某个页面

 wx.redirectTo(OBJECT)

// 关闭当前页面,跳转到应用内的某个页面

 wx.switchTab(OBJECT)

// 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
// (注意这种方法不能在链接后直接携带参数)

 wx.reLaunch(OBJECT)

// 关闭所有页面,打开到应用内的某个页面
wx.navigateTo跳转状态下,页面A和页面B的生命周期逻辑

1、进入A页面:A执行onLoad()>onShow()>onReady()2A页面navigateTo B页面:A执行onHide()B执行onLoad()>onShow()>onReady()3B页面返回A页面:B执行onUnload()A执行onShow()4、退出A页面:A执行onUnload()

10.本地存储和globalData的区别

一、缓存(StorageSync)本地存储

1、小程序中的本地存储有同步功能,可用于保存用户信息(用户登录后的一些基本信息)

2、缓存的更新需要使用setStorageSync方法。

二、全局变量(globalData)

1、保存一些可能涉及安全类的数据,例如资源类,每次需要很准确的,就建议用全局变量。

2、全局变量每次关闭小程序重新打开的时候,都会进行初始化更新。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值