小程序的执行流程
注册一个小程序(小程序的生命周期)
- 注册App时,一般会做什么
- 判断小程序的进入场景
- 监听生命周期函数,在生命周期中执行对应的业务逻辑,比如在某个生命周期函数中获取微信用户的信息。
- 因为App()实例只有一个,并且是全局共享的( 单例对象),所以我们可以将一些共享数据放在这里。
- 小程序后台存活时间:
htps://developers.weixin.qq.com/miniprogram/dev/framework/operating-mechanism.html - 小程序的打开场景较多:
- 常见的打开场景:群聊会话中打开、小程序列表中打开、微信扫一扫打开、另一个小程序打开
https://developers.weixin.qq.com/miniprogram/dev/reference/scene-list.html
- 常见的打开场景:群聊会话中打开、小程序列表中打开、微信扫一扫打开、另一个小程序打开
- 如何确定场景?
- 在onLaunch和onShow生命周期回调函数中,会有options参数,其中有scene值
onLanch
-
发请求
-
获取用户的数据
- wx.getUserInfo
- button open-type = getUserInfo
- open-data
onShow(option)
- 获取场景,根据不同的场景做对应的逻辑处理
onHide
onError
注册一个页面(页面的生命周期)
onLoad
初次加载
onShow
页面显示
onReady
初次渲染完成
onHide
onUnLoad
onShareAppMessage
监听用户点击页面内转发按钮(button 组件
open-type="share"
)右上角菜单“转发”按钮的行为,并自定义转发内容。
-
<button open-type="share">点击分享</button>
-
onShareAppMessage: function (res) { return { title: '自定义转发标题', path: '/pages' // 用户点进分享所进入的页面 } }
WXS作用以及语法
WXS(WeiXin Script)是小程序的一套脚本语言,结合
WXML
,可以构建出页面的结构。WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。
但基本是和js一样的
主要应用的场景是 时间格式化以及过滤器的使用,也可以写成js作成工具类,在我们的js文件中先使用
两种wxs的写法
-
wxml
中<wxs module="info"> const sum = () => { }; module.exports = { sum } </wxs> <view>{{info.sum}}</view>
-
.wxs
文件中<wxs src="./wxs/demo.wxs" module="info" />
自定义组件
只能使用wx:if;无法使用hidden
父子间传值和vue相似
组件和页面通信
父传子
通过属性绑定的形式将值传递给子组件
-
获取子组件并调用其方法 selectComponent
// this.selectComponent('.tab') 获取到子组件的示例对象this // setCurrentIndex 为组件的方法,可以直接setData({}) 。不推荐直接修改数据 this.selectComponent('.tab').setCurrentIndex(e.detail.index) },
子传父
通过
triggerEvent
触发事件将数据传递给父组件
-
this.triggerEvent("click", data, {})
插槽slot
在组件的wxml中可以包含
slot
节点,用于承载组件使用者提供的wxml结构。默认情况下,一个组件的wxml中只能有一个slot。需要使用多slot时,可以在组件js中声明启用。
-
多插槽的组件声明
Component({ options: { multipleSlots: true // 在组件定义时的选项中启用多slot支持 }, properties: { /* ... */ }, methods: { /* ... */ } })
-
此时,可以在这个组件的wxml中使用多个slot,以不同的
name
来区分。<!-- 组件模板 --> <view class="wrapper"> <slot name="before"></slot> <view>这里是组件的内部细节</view> <slot name="after"></slot> </view>
-
使用时,用
slot
属性来将节点插入到不同的slot上。<!-- 引用组件的页面模板 --> <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>
组件的样式
-
组件内的样式对外部样式的影响
- 组件内的class样式,只对组件wxml内的节点生效,对于引用组件的Page页面不生效。
- 组件内不能使用id选择器、属性选择器、标签选择器
-
外部样式 对组件内样式 的影响
- 外部使用class的样式,只对外部wxml的class生效,对组件内是不生效的
- 外部使用了id选择器、属性选择器不会对组件内产生影响
- 外部使用了标签选择器,会对组件内产生影响
-
组件内的class样式和组件外的class样式,默认是有一个隔离效果的;
-
为了防止样式的错乱,官方不推荐使用id、属性、标签选择器;
-
Component({ options: { styleIsolation: 'isolated' } })
- 如果这个 Component 构造器用于构造页面 ,则默认值为
shared
,且还有以下几个额外的样式隔离选项可用:page-isolated
表示在这个页面禁用 app.wxss ,同时,页面的 wxss 不会影响到其他自定义组件;page-apply-shared
表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式不会影响到其他自定义组件,但设为shared
的自定义组件会影响到页面;page-shared
表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式会影响到其他设为apply-shared
或shared
的自定义组件,也会受到设为shared
的自定义组件的影响。
- 如果这个 Component 构造器用于构造页面 ,则默认值为
-
注意:在同一个节点上使用普通样式类和外部样式类时,两个类的优先级是未定义的,因此最好避免这种情况。
-
/* 组件 custom-component.js */ Component({ externalClasses: ['my-class'] }) <!-- 组件 custom-component.wxml --> <custom-component class="my-class">这段文本的颜色由组件外的 class 决定</custom-component>
-
<!-- 页面的 WXML --> <custom-component my-class="red-text" /> <custom-component my-class="large-text" /> <!-- 以下写法需要基础库版本 2.7.1 以上 --> <custom-component my-class="red-text large-text" />
-
WX.API
网络
-
请求 (request)
-
我们一般会对
import { baseUrl } from './config.js'; export default (options) => { wx.showLoading({ title: '数据加载中', }); return new Promise((resolve, reject) => { wx.request({ url: `${baseUrl}/${options.url}`, method: options.method || 'get', data: options.data || {}, success: resolve, fail: reject, complete: (res) => { wx.hideLoading(); } }); }); }
-
对各个页面中封装请求方法
import http from './index.js'; const getHomeList = () => { return http({ url: 'home/multidata' }); } export { getHomeList }
开放接口
- 登录 (wx.login)
- 当我们不需要关心开发者服务器开发的时候,前端需要
- 调用wx.login() 获取code
- 调用wx.request发送code到服务器,返回一个登录状态的标识,比如token
- 我们使用wx.setStorageSync/setStorage,将标识token进行存储
- 这个和我们的localStorage一样
- 携带token进行请求,获取返回的数据
导航
-
navigator
// 通过url进行参数的传递 <!-- sample.wxml --> <view class="btn-area"> <navigator url="/page/navigate/navigate?title=navigate" hover-class="navigator-hover">跳转到新页面 </navigator> <navigator url="../../redirect/redirect/redirect?title=redirect" open-type="redirect" hover-class="other-navigator-hover">在当前页打开 </navigator> <navigator url="/page/index/index" open-type="switchTab" hover-class="other-navigator-hover">切换 Tab </navigator> <navigator target="miniProgram" open-type="navigate" app-id="" path="" extra-data="" version="release">打开绑定的小程序 </navigator> <navigator url="/page/index/index" open-type="navigateBack" delta="2">回退 Tab </navigator> </view>
-
接受传递过来的数据
// 在跳转到的页面中 Page({ onLoad: function(options) { //在options中拿到 console.log(options); } })
-
跳转的页面向返回的页面回传数据
- getCurrentPages()
- 获取当前栈的所有页面。数组中第一个元素为首页,最后一个元素为当前页面。
Page({ onUnload() { const pages = getCurrentPages(); // 获取首页页面对象 const home = pages[pages.length-1]; // 使用home页面中的方法修改数据 } })
一些需要注意的地方
-
因为WXML节点标签名只能是小写字母、中划线和下划线的组合,所以自定义组件的标签名也只能包含这些字符。
-
自定义组件也是可以引用自定义组件的,引用方法类似于页面引用自定义组件的方式(使用
usingComponents字段)。 -
自定义组件和页面所在项目根目录名不能以"Wx-" 为前缀,否则会报错。
-
如果在appjson的usingComponents声明某个组件,那么所有页面和组件可以直接使用该组件。
-
如何获取每个自定义组件到顶部的距离
- wx.createSelectorQuery()
- 返回一个 SelectorQuery 对象实例。在自定义组件或包含自定义组件的页面中,应使用
this.createSelectorQuery()
来代替
wx.createSelectorQuery().select('.tab').boundingClientRect((rect) => { this.setData({ tabTop: rect.top }) }).exec(); //这里必须有exec()才能执行