目录
7、条件判断:(类似v-if ,当条件为false时,view 组件不会被渲染出来)
2、event 中 currentTarget 和target 的区别:
6、当捕获到某个事件就停止进行向下传递时,可以使用capture-catch
一、基本概念
1、app.json
pages: 所有页面都必须在pages 里面注册
2、MVVM框架
DOM isteners: ViewModel 层可以将DOM的监听绑定到Model 层
Data Bindings:ViewModel 层可以将数据的变量,响应式的反应到view层
MVVM 框架可以从命令式编程转移到声明式编程
3、小程序的双线程模型
- WXML模块和WXSS样式运行于渲染层,渲染层使用WebView线程渲染(一个程序有多个页面,会使用多个WebView的线程)
- JS脚本运行于逻辑层,逻辑层使用JsCore运行JS脚本
- 这两个线程都会经由微信客户端(Native)进行中转交互
4、小程序的配置文件
1、app.json:
- pages:页面路径列表,用于指定小程序的组成页面,每一项都对应一个页面的路径信息,小程序的所有页面都必须在pages 中进行注册
- window:全局的默认窗口展示,
2、app.js:
在app.js调用App函数,注册小程序实例
作用一:如何判断小程序被打开的场景:在onLaunch和onShow的生命周期回调函数中,会有options参数,其中有scene值,可以判断进入小程序的方式
// app.js
App({
onLaunch(options) {
console.log(options)
},
onShow(options) {
console.log(options)
},
onHide(options) {
console.log(options)
}
})
作用二:在页面中获取app定义的全局数据
// app.js
App({
globalData: {
token: 'coder'
}
})
// /pages/home/home.js
page({
data: {
userInfo: {}
},
onLoad() {
// 获取共享的数据:App实例中的数据
// 1.获取app 实例对象
const app = getApp()
// 2. 从app 实例对象中获取数据
const token = app.globalData.token
console.log(token)
// 3. 将数据展示到界面上
this.setData({
userInfo: token
})
}
})
作用三:定义生命周期函数
onLaunch:
1. 进行用户登陆
2. 读取本地保存的数据
3. 发送网络请求
二、语法:
1、Page 函数
// pages/home/home.js
Page({
// 作用二:定义数据,在wxml 中使用
data: {
banners: [],
btns: ['red', 'green']
},
// 作用一:在生命周期函数中,发送网络请求,请求数据
onLoad() {
// 发送网络请求
wx.request({
url: "...",
success: (res) => {
console.log(res)
const data = res.data
this.setData({
banners: data.banners
})
},
})
},
作用三:绑定wxml 中产生事件后的回调函数
onBtnClick() {
console.log("btnClick")
},
onBtnsClick(event) {
console.log("btnsClick", event.target.dataset.btns)
}
作用四:其他事件的监听(页面滚动、下拉刷新、上拉加载)
onPullDownRefresh() {
console.log("下拉刷新")
},
onReachBottom() {
console.log("到达底部,上拉加载")
},
onPageScroll(event) {
console.log("页面滚动", event)
},
// 生命周期函数
onLoad() {},
onShow() {},
onReady() {},
onHide() {},
onUnload() {}
})
// pages/home/home.wxml
<view class="banner">
<swiper>
<block wx:for="{{banners}}" wx:key="id">
<swiper-item>
<image mode="widthFix" src="{{item.image}}"></image>
</swiper-item>
</block>
</swiper>
</view>
<view>
<button bindtap="onBtnClick">按钮</button>
<block wx:for="{{btns}}" wx:key="*this">
<button
style="backgroundColor: {{item}};"
bindtap="onBtnsClick"
data-btn="{{item}}"
>
按钮
</button>
</block>
</view>
// pages/home/home.json
{
"usingComponents": {},
开启下拉刷新
"enablePullDownRefresh": true
}
2、组件:
// 固定宽度,自适应高度
<image src="/assets/zznv.png" mode="widthFix"/>
3、选择本地图片:
// index.js
onChooseImage() {
wx.chooseMedia({
mediaType: "image"
}).then((res) => {
console.log(res)
const imagePath = res.tempFilesp[0].tempFilePath
this.setData({ chooseImageUrl: imagePath })
})
}
// index.wxml
<button bindtap="onChooseImage">选择图片</button>
<image src="{{chooseImageUrl}}"/>
4、scroll-view
// 给scroll-view 设置一个固定的高度或者宽度
// 内容的高度或者宽度超出scroll-view 则滚动
// enable-flex 使scroll-view 开启flex 布局
// 使flex 不压缩 flex-shrink: 0;
<scroll-view class="scroll-view-x" scroll-x enable-flex>
<view></view>
</scroll-view>
// 监听scroll-view 的滚动
<scroll-view
class="scroll-view-x"
scroll-x
enable-flex
bindscrolltoupper="onScrollToUpper"
bindscrolltolower="onScrollToLower"
bindScroll="onScroll"
>
<view></view>
</scroll-view>
onScrollToUpper() {
console.log("滚动到最顶部/左边")
}
onScrollToLower() {
console.log("滚动到最底部/右边")
}
onScroll(event) {
console.log("监听滚动", event)
}
5、input 的双向数据绑定:
<input type="text" model:value="{{message}}"/>
6、wxss:
以iphone6为标准: 1px = 2rpx
7、条件判断:(类似v-if ,当条件为false时,view 组件不会被渲染出来)
<view wx:if="{{ score > 90}}">A</view>
<view wx:elif="{{ score > 60}}">B</view>
<view wx:else>C</view>
8、hidden 属性:为true 时,组件被隐藏;为false 时,组件显示出来 (类似v-show,依然存在于组件树中,本质为display:none)
<view hidden>隐藏</view>
<view hidden="{{isHidden}}">隐藏</view>
9、列表的展示:
1. 遍历数组
<view wx:for="{{ books }}" wx:key="name">
{{ index }} - {{ item.name }} - {{ item.price }}
</view>
2. 遍历数字
*this 指 item
<view wx:for="{{ 10 }}" wx:key="*this">{{item}}</view>
3. 遍历字符串
<view wx:for="coder" wx:key="*this">
{{ item }}
</view>
10、block 标签:
<block wx:for="{{ books }}" wx:key="name">
<view>{{ item.name }}</view>
</block>
默认情况下wx:for 遍历后的每一项为 item, 索引为index,不需要声明,可以直接使用;
对item 和 index 重命名:
<block wx:for="{{ books }}" wx:key="name"
wx:for-item="book"
wx:for-index="i"
>
<view>{{ i }} - {{ book.name }}</view>
</block>
wx:key 的值以及两种形式:
- 字符串,代表在for 循环的array 中item 的某个property,该property 的值需要是列表中唯一的字符串或数字,且不能动态改变
- 保留关键字*this, 代表在for 循环中的item 本身,这种表示需要item 本身是一个唯一字符串或数字
11、wxs 的基本使用:
// utils/format.wxs
function formatPrice(price) {
return "¥" + price
}
// 必须导出后才能被其他地方调用:必须使用CommonJS导出
module.exports = {
formatPrice: formatPrice
}
// pages/home/home.wxml
<wxs module="format" src="/utils/format.wxs"></wxs>
<block wx:for="{{ books }}" wx:key="name" >
<view>{{ format.formatPrice(item.price) }}</view>
</block>
12、案例:
1、给数字加单位:
// utils/format.wxs
// 对count 进行格式化
function formatCount(count) {
var numCount =parseInt(count)
if(numCount) >= 100000000 {
return (numCount / 1000000000).toFixed(1) + '亿'
} else if (numCount > = 10000) {
return (numCount / 10000).toFixed(1) + '万'
} else {
return numCount
}
}
// 必须导出后才能被其他地方调用:必须使用CommonJS导出
module.exports = {
formatCount: formatCount
}
// pages/home/home.wxml
<wxs module="format" src="/utils/format.wxs"></wxs>
<view>{{ format.formatCount(playCount)}}
2、对时间格式化:
function padLeft(time) {
if((time + '').length >= 2) return time
return '0' + time
}
function padLeft(time) {
time = time + ''
return ('00' + time).slice(time.length)
}
function formatTime(time) {
var minute = Math.floor(time / 60)
var second = Math.floor(time) % 60
return padLeft(minute) + ':' + padLeft(second)
}
module.exports = {
formatTime: formatTime
}
13、小程序的事件处理:
// index.wxml
<button bindtap="onBtnTap">按钮</button>
<view bindtap=""onViewTap">按钮</view>
// index.js
Page({
// 绑定事件监听函数
onBtnTap(event) {
console.log(event)
}
})
14、组件的公共事件:
- touchstart:手指触摸动作开始
- touchmove:手指触摸后移动
- touchcancle:手指触摸动作被打断,比如来电提醒、弹窗
- touchend:手指触摸动作结束
- tap:手指触摸后马上离开
- longpress:手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
某些组件的特有事件:
- input:bindinput、bindblur、bindfocus等
- scroll-view:bindscrolltoupper、bindscrolltolower等
15、事件对象event:
1、事件对象event 的属性:
- type:事件类型
- timeStamp:事件生成时的时间戳
- target:触发事件的组件的一些属性值集合(触发事件的元素)
- currentTarget:当前组件的一些属性值集合(处理事件的元素)
- mark:事件标记数据
2、event 中 currentTarget 和target 的区别:
// index.wxml
<view class="outer" data-name="why" bindtap="onOuterTap">
<view class="inner"></view>
</view>
// index.js
Page({
当点击inner 组件时,会通过事件冒泡的方式,调用outer 的onOuterTap
此时event.target(即:触发事件的对象)是inner 组件
event.currentTarger(即:处理事件的对象)是outer 组件
onOuterTap(event) {
console.log(event)
console.log(event.target)
console.log(event.currentTarget)
获取outer 组件中的自定义属性中的name 属性:
const name = event.currentTarget.dataset.name
console.log(name)
}
})
3、事件参数的传递:
视图层的数据传递到逻辑层,通过自定义属性
// event 的参数传递
// index.wxml
<view
class="arguments"
bindtap="onArgTap"
data-name="why"
data-age="18"
></view>
// index.js
Page({
onArgTap(event) {
console.log(event)
const {name, age} = event.currentTarget.dataset
console.log(name, age)
}
})
4、传递参数的案例:
// index.wxml
<view>
<block wx:for="{{titles}}" wx:key="*this">
<view
class="item {{ index === currentIndex ? "active" : '' }}"
bindtap="onItemTap"
data-index="{{index}}"
>{{item}}</view>
</block>
</view>
// index.js
Page({
data: {
titles: ["手机","电脑","pad"],
currentIndex: 0
},
onItemTap(events) {
const {index} = event.currentTarget.dataset.index
this.setData({ currentIndex: index })
}
})
5、事件冒泡和事件捕获:
事件的传递过程:当触发某个事件时,会先经过事件捕获(从外向内的传递),达到处理事件的元素进行处理,再经过事件冒泡(从内向外的传递)
<view
class="view1"
capture-bind:tap="onView1CaptureTap"
bindtap="onView1Tap">
<view
class="view2"
capture-bind:tap="onView2CaptureTap"
bindtap="onView2Tap">
</view>
</view>
onView1CaptureTap() {
console.log("view1Capture")
}
onView2CaptureTap() {
console.log("view2Capture")
}
onView1Tap() {
console.log("view1Tap")
}
onView2Tap() {
console.log("view2Tap")
}
// view1Capture -> view2Capture -> view2Tap -> view1Tap
6、当捕获到某个事件就停止进行向下传递时,可以使用capture-catch
<view
class="view1"
capture-catch:tap="onView1CaptureTap"
bindtap="onView1Tap">
<view
class="view2"
capture-bind:tap="onView2CaptureTap"
bindtap="onView2Tap">
</view>
</view>
onView1CaptureTap() {
console.log("view1Capture")
}
onView2CaptureTap() {
console.log("view2Capture")
}
onView1Tap() {
console.log("view1Tap")
}
onView2Tap() {
console.log("view2Tap")
}
// view1Capture
7、传递参数的另一种方式:mark
<view
bindtap="onMarkTap"
mark:name="kobe"
>
<view mark:age="18"></view>
</view>
onMarkTap(event) {
const mark = event.mark
console.log("mark", mark) // { name: kobe, age: 18 }
}
三、组件化开发:
1、组件的样式:
组件内的样式对外部样式的影响:
- 组件内的class 样式,只对组件内的节点生效,对引用组件的page 页面不生效
- 组件内不能使用id 选择器、属性选择器、标签选择器
外部样式对组件内样式的影响:
- 外部使用class 的样式,只对外部wxml 的class 生效,对组件内是不生效的
- 外部使用了id 选择器、属性选择器不会对组件内产生影响
- 外部使用了标签选择器,会对组件内产生影响
如何让class 可以相互影响:在Component 对象中,可以传入一个options 属性,其中options 属性中有一个styleIsolation(隔离) 属性
styleIsolation 有三个取值:
Component({
options: {
styleIsolation: isolated
}
})
- isolated:表示启用样式隔离,在自定义组件内外,使用class 指定的样式将不会相互影响(默认去值)
- apply-shared: 表示页面wxss 样式将影响到自定义组件,但自定义组件wxss 中指定的样式不会影响页面
- shared:表示页面wxss 样式将影响到自定义组件,自定义组件wxss 中指定的样式也会影响页面和其他设置
2、组件的通信:
1、父传子 自定义属性
// index.wxml
<selection-info title="父传子的title"/>
// selection.wxml
<view>{{ title }}</view>
// selection-info.js
Components({
properties: {
title: {
type: String,
value: "默认标题"
}
}
})
2、子传父:自定义事件
// selection-info.wxml
<button bindTap="onTitleTap">按钮点击</button>
// selection-info.js
Components({
methods: {
onTitleTap() {
console.log("子组件的title 被点击")
this.triggerEvent("titleClick", "abc")
}
}
})
// index.wxml
<selection-info
bind:titleClick="onTitleClick"
/>
// index.js
Page({
onTitleClick(event) {
console.log("点击", event.detail)
}
})
3、案例:
// sonComps.wxml
<view>
<block wx:for="{{ titles }}" wx:key="*this">
<view
class="item {{ index === currentIndex ? 'active': ''}}"
bindTap="onItemTap"
mark:index="{{ index }}"
>
<text class="title">{{ item }}</text>
</view>
</block>
</view>
// sonComps.js
Components({
properties: {
titles: {
type: Array,
value: []
}
},
data: {
currentIndex: 0
}
methods: {
onItemTap(event) {
const index = event.mark.index
this.setData({ currentIndex: index })
this.triggerEvent("tabChange", index)
}
}
})
// index.wxml
<son-comps titles="{{ titles }}" bind:tabChange="onTabChange"/>
// index.js
Page({
data: {
titles: ['abc', 'cba', 'nba']
},
onTabChange(event) {
const index = event.detail
console.log(this.data.titles[index])
}
})
5、父组件直接调用子组件的方法:
// index.wxml
<tab-control
class="tab-control"
/>
<button bindtap="onExecTCMethod">调用子组件的方法</button>
// index.js
Page({
onExecTCMethod() {
// 1. 获取组件的实例对象
const tabControl = this.selectComponent(".tab-control")
// 2. 调用组件实例的方法
tabControl.test(2)
}
})
// tab-control.js
Component({
data: {
currentIndex: 0
}
methods: {
test(index) {
console.log("调用子组件的方法")
this.setData({
currentIndex: index
})
}
}
})
3、插槽的使用
1、小程序中的插槽不支持默认值
// index.wxml
<my-slot>
<button>按钮</button>
</my-slot>
// my-slot.wxml
<view>
// 小程序中不支持默认值
// <slot>哈哈哈</slot>
<slot></slot>
</view>
2、实现小程序中插槽的默认值
// index.wxml
<my-slot>
<button>按钮</button>
</my-slot>
<my-slot></mt-slot>
// my-slot.wxml
<view class="content">
<slot></slot>
</view>
<view class="default">哈哈哈</view>
// mt-slot.wxss
.default {
display: none
}
.content:empt + .default {
display: block
}
3、多个插槽的使用:
// index.wxml
<mul-slot>
<button slot="left" size="mini">left</button>
<view slot="center">哈哈哈</view>
<button slot="right" size="mini">right</button>
</mul-slot>
// mul-slot.wxml
<view class="mul-slot">
<view class="left">
<slot name="left"></slot>
</view>
<view class="center">
<slot name="center"></slot>
</view>
<view class="right">
<slot name="right"></slot>
</view>
</view>
// mul-slot.js
Component({
options: {
multipleSlot: true
}
})
4、组件的混入:
// /behaviors/counter.js
export const counterBehavior = Behavior({
data: {
counter: 100
},
methods: {
increment() {
this.setData({
counter: this.data.counter + 1
})
}
}
})
// c-behavior.wxml
<view>
<button bindtap="increment">+1</button>
</view>
// c-behavior.js
import { counterBehavior } from "../../behaviors/conter"
Component({
behaviors: [counterBehavior]
})
5、组件本身的常用的生命周期:
1、created、attached、detached
- created:在组件实例刚刚被创建时执行
- attached:在组件实例进入页面节点树时执行
- ready:在组件在视图层布局完成后执行
- moved:在组件实例被移动到节点树另一个位置时执行
- detached:在组件实例从页面节点树移除时执行
- error:在组件方法抛出错误时执行
// c-lifetime.js
Component({
lifetimes: {
created() {
console.log("组件被创建")
},
attached() {
console.log("组件被添加到组件树中")
},
detached() {
console.log("组件从组件树中被移除")
}
}
})
2、组件所在页面的生命周期:
// c-lifetime.js
Component({
lifetimes: {
created() {
console.log("组件被创建")
},
attached() {
console.log("组件被添加到组件树中")
},
detached() {
console.log("组件从组件树中被移除")
}
},
pageLifetimes: {
show() {
console.log("页面显示")
},
hide() {
console.log("页面隐藏")
},
resize() {
console.log("组件所在页面尺寸变化时执行")
}
}
})
3、属性和数据的监听:
Component({
observes: {
title: function(newVal, oldVal) {
console.log(newVal, oldVal)
},
"info.name": function(newVal, oldVal) {
console.log(newVal)
},
"movies[0]": function(newVal, oldVal) {
console.log(newVal)
}
}
})
四、网络请求:
1、API参数
- url:接口地址(必传)
- data:请求参数
- header:设置请求的header,header中不能设置Referer,content-type默认为application/json
- timeout:超时时间,单位为毫秒,默认为60000
- method:HTTP请求方法(默认为GET)
- dataType:返回的数据格式(默认为JSON)
- responseType:响应的数据类型(默认为text)
// index.js
Page({
data: {
allCities: {}
},
onLoad() {
// 1.网络请求基本使用
wx.request({
url: "http://123.207.32.32:1888/api.city/all",
success: (res) => {
const data = res.data.data
this.setData({ allCities: data })
},
fail: (err) => {
console.log("err", err)
}
})
wx.request({
url: "http://123.207.32.32:1888/api/home/houselist",
data: {
page: 1
},
success: (res) => {
console.log("res", res)
},
fail: (err) => {
console.log("err", err)
}
})
}
})
2、网络请求的封装
// 一. 封装成函数
function request(options) {
return new Promise((resolve, reject) => {
wx.request({
...options,
success: (res) => {
resolve(res.data)
},
fail: reject
})
})
}
// 1.页面中调用
request({
url: 'http://codercba.com:1888/api/city/all'
}).then(res => {
this.setData({ allCities: res.data })
})
// 2. await/async(和下拉加载更多)
onLoad() {
this.getCityData(1)
}
async getCityData(param) {
const res = await request({
url: 'http://codercba.com:1888/api/home/houselist',
data: { page: param }
})
const finalHostList = [ ...this.data.houselist, ...res.data ]
this.setData({ houselist: finalHostList })
// setData 的目的是改变数据的时候,页面同时更新
}
// 下拉加载更多
onReachBottom() {
this.getCityData(2)
}
// 二、封装成类 -> 实例
class HYRequest {
constructor(baseURL) {
this.baseURL = baseURL
}
request(options) {
const { url } = options
return new Promise((resolve, reject) => {
wx.request({
...options,
url: this.baseURL + url,
success: (res) => {
resolve(res.data)
},
fail: reject
})
})
}
get(options) {
return this.request({ ...options, method: "get" })
}
post(options) {
return this.request({ ...options, method: "post" })
}
}
export const reqInstance = new HyRequest("http://codercba")
reqInstance.request()
reqInstance.get({
url: "/city/all"
}).then(res => {
console.log("res", res)
})
reqInstance.post()
五、小程序相关的API
1、提示框
// index.wxml
<view>
<button bindtap="onShowToast">showToast</button>
<button bindtap="onShowModal">showModal</button>
<button bindtap="onShowAction">showAction</button?
</view>
// index.js
Page({
// 1. 弹窗功能
onShowToast() {
wx.showToast({
title: '成功',
icon: 'loading',
duration: 3000,
' mask: true,
success: (res) => {
console.log("res", res)
},
fail: (err) => {
console.log("err", err)
}
})
},
onShowLoading() {
// 显示loading 提示框后,需要主动调用wx.hideLoading 才能关闭提示框
wx.showLoading({
title: '成功',
' mask: true,
success: (res) => {
console.log("res", res)
},
fail: (err) => {
console.log("err", err)
}
})
},
onShowModal() {
wx.showModal({
title: '标题',
content: '内容',
success: (res) => {
console.log("res", res)
if(res.cancle) {
console.log("用户点击了取消按钮")
} else if (res.confirm) {
console.log("用户点击了确定按钮")
}
}
})
},
onShowAction() {
wx.showActionSheet({
itemList: ["cba", "abc"],
success: (res) => {
console.log(res.tabIndex)
},
fail: (err) => {
console.log("点击了取消")
}
})
},
// 2. 分享功能
onShareAppMessage() {
return {
title: "旅途",
path: "/pages/favor/favor",
imageUrl: "/assets/the.jpg"
}
},
// 3. 获取设备信息
onGetSystemInfo() {
// 1. 获取用户手机的基本信息
wx.getSystemInfo({
success: (res) => {
console.log(res)
}
})
// 2. 获取当前的位置信息
wx.getLocation({
success: (res) => {
console.log(res)
}
})
}
})
// 获取用户当前位置信息时,需要做的配置
// 在 app.json 中
"permisstion": {
"scope.userLocation": {
"desc": "需要获取位置信息"
}
}
2、storage 存储
Page({
onLocalStorage() {
// 1. 同步方法
// a. 设置值
wx.setStorageSync("name", "why")
// b. 获取值
const name = wx.getStorageSync("name")
console.log(name)
// c. 删除值
wx.removeStorageSync('name')
// d. 清空值
wx.clearStorageSync()
// 2. 异步方法
// a. 设置值
wx.setStorage({
key: "books",
data: ["abc", "cba"],
// 存的时候加密
encrypt: true
success: (res) => {
wx.getStorage({
key: "books",
// 取的时候解密
encrypt: true,
success: (res) => {
console.log("res", res)
}
})
}
})
// b. 获取值
wx.getStorage({
key: "books",
success: (res) => {
console.log("res")
}
})
// c. 删除值
wx.removeStorage({
key: "books",
success: (res) => {
console.log("res")
}
})
// d. 清空值
wx.clearStorage({
success: (res) => {
console.log("res")
}
})
}
})
3、页面跳转的方式:
- wx.navigateTo:保留当前页面,跳转到应用内的某个页面
- wx.nabigateBack: 关闭当前页面,返回上一页面或多级页面
- wx.switchTab: 跳转到tabBar页面,并关闭其他所有非tabBar页面
- wx.reLunch:关闭所有页面,打开到应用内的某个页面
- wx.redirectTo:关闭当前页面,跳转到应用内的某个页面
4、早期页面跳转传递参数的方式:
1. 页面的跳转(wx.navigateTo)
// index.js
Page({
onNavTap() {
wx.navigateTo({
url: "/page/detail/detail?name=cba&age=18",
})
}
})
// detail.js
Page({
onLoad(options) {
console.log(options) // {name: cba, age: 18}
}
})
2. 页面的返回(wx.navigateBack) 并给上一级页面传递数据
Page({
// 一、早起给上一级页面传递数据的方式
onBackTap() {
wx.navigateBack({
// 1. 返回导航,返回的层级,默认为1
delta: 2,
})
},
// 在unload 中进行操作,可以对页面顶部的返回按钮进行监听
onUnload() {
// 2. 给上一级的页面传递数据
// 2.1 获取到上一个页面的实例
const pages = getCurrentPages()
const prePage = pages[pages.length -2]
// 2.2 通过setData 给上一个页面设置数据
prePage.setData({ message: 'abc'})
}
})
5、目前页面跳转传递参数的方式:
// index.js
Page({
onBindTip() {
wx.navigateTo({
url: 'page/detail/detail',
events: {
backEvent(data) {
console.log("data",data)
},
coderEvent(data) {
console.log("data",data)
}
}
})
}
})
// detail.js
Page({
onPassBack() {
// 1. 拿到eventChannel
const eventChannel = this.getOpenerEventChannel()
// 2. 传递数据给上一个页面
eventChannel.emit("backEvent", { name:'abc', age: 18 })
eventChannel.emit("coderEvent", { name:'cba', age: 18 })
}
})
使用navigator 组件进行跳转
// index.wxml
<navigator url="/pages/detail/detail?name=why&age=18">跳转</navigator>
// detail.wxml
<navigator open-type="navigateBack">返回</navigator>
6、小程序登陆流程解析
Page({
// onLoad 登陆的流程
onLoad() {
// 1. 获取本地的token,判断token 是否有值
const token = wx.setStorageSync('token')
// 2. 如果token 有值
if(token) {
console.log("请求其他数据")
} else {
this.handleLogin()
}
}
handleLogin() {
// 1. 获取code
wx.login({
success: (res) => {
const res = res.code
// 2. 将这个code 发送给后端
wx.request({
url: 'http://123.207.32.32:3000/login',
data: {
code
},
method: "post",
success: (res) => {
const token = res.data.token
wx.setStorageSync('token', token)
}
})
}
})
}
})