小程序项目学习--第四章:组件化-插槽-混入-生命周期-系统API-登录
创始人
2024-05-22 11:08:51
0

第四章:组件化-插槽-混入-生命周期-系统API-登录

01_(理解)组件化-页面中直接调用子组件的方法

image-20230119143817967

可在父组件里调用 this.selectComponent ,获取子组件的实例对象 --1.获取对应的组件实例对象–通过定义的class获取

页面直接调用组件方法—必须给组件定义一个class类便于获取组件

子组件方法  
test(index) {console.log("tab control test function exec");this.setData({currentIndex: index})}父组件
必须给组件定义一个class类便于获取组件

{digitalTitles}}"bind:indexchange="onTabIndexChange"
/>

父组件在方法中调用子组件onExecTCMethod() {// 1.获取对应的组件实例对象--通过定义的class获取const tabControl = this.selectComponent(".tab-control")// 2.调用组件实例的方法tabControl.test(2)}

02_(掌握)组件化-插槽-单个插槽的使用和默认值

image-20230119193449005

image-20230119193458303

要点:小程序中slot插槽不支持默认值

通过css实现插值默认值,通过兄弟选择器

哈哈哈哈.default {display: none;
}.content:empty + .default {display: block;
}

代码实现

my-slot


Header默认值Footer
/* components/my-slot/my-slot.wxss */
.my-slot {margin: 20px 0;  
}.default {display: none;
}.content:empty + .default {display: block;
}

08_learn_slot

{"usingComponents": {"my-slot": "/components/my-slot/my-slot"}
}





03_(掌握)组件化-插槽-多个插槽的使用和配置

image-20230119195634091

-多个插槽的使用需要给插槽命名(具名插槽)和在Component实例中设置options:{multipleSlots:true}

1.使用多个插槽需要在Component实例中设置options:{multipleSlots:true}

2.给插槽命名具名插槽

3.给组件设置样式

4.在页面中json中注册组件usingComponents

5.使用组件–给标签添加slot属性并指定查找名

1.// components/mul-slot/mul-slot.js
Component({options: {multipleSlots: true}
})
2.



3.
/* components/mul-slot/mul-slot.wxss */
.mul-slot {display: flex;text-align: center;
}.left, .right {width: 160rpx;
}.center {flex: 1;
}
4.
{"usingComponents": {"mul-slot": "/components/mul-slot/mul-slot"}
}
5.


哈哈哈

04_(理解)组件化-组件的代码复用-Behaviors

image-20230119201529330

behaviors 是用于组件间代码共享的特性,类似于一些编程语言中的 “mixins”。

混入的实现步骤

1.注册组件、使用组件

2.定义混入的js文件

3.在组件中·使用混入,导入、注册、使用

 1. 
"c-behavior": "/components/c-behavior/c-behavior"
2.
export const counterBehavior = Behavior({data: {counter: 100},methods: {increment() {this.setData({ counter: this.data.counter + 1 })},decrement() {this.setData({ counter: this.data.counter - 1 })}}
})3.
// components/c-behavior/c-behavior.js
// 使用类似mixins的behaviors的混入的步骤
// 1.导入
import { counterBehavior } from "../../behaviors/counter"
// 2.注册
Component({behaviors: [counterBehavior]
})

当前计数: {{counter}}

05_(理解)组件化-组件的生命周期函数

image-20230119203809951

image-20230119203820671

  1. 组件生命周期的针对于本组件,页面的生命周期针对于本页面
  2. 注册、使用
1.
c-lifetime组件// components/c-lifetime/c-lifetime.js
Component({// 组件生命周期的书写位置lifetimes: {created() {console.log("组件被创建created");},attached() {console.log("组件被添加到组件树中attached");},detached() {console.log("组件从组件树中被移除detached");}},// 页面的生命周期pageLifetimes: {show() {console.log("page show");},hide() {console.log("page hide");}}
})
2."c-lifetime": "/components/c-lifetime/c-lifetime"

{isShowLiftTime}}"/>// pages/08_learn_slot/index.js
Page({data: {isShowLiftTime: true},onChangeTap() {this.setData({ isShowLiftTime: !this.data.isShowLiftTime })}
})

06_(掌握)组件化-Component函数可以传入的选项

image-20230119204619753

image-20230119204627351

第四章:小程序系统API调用

image-20230119204718260

07_(了解)API-常见API的内容介绍

image-20230119204955490

08_(掌握)API-网络请求API的基本使用

image-20230119212810365

image-20230119212820465

1.在onload中发起网络请求wx,request({})传入参数

2.在wxml中展示数据

1.
// pages/09_learn_api/index.jsPage({data: {allCities: {},houselist: [],},onLoad() {// 1.网络请求基本使用// wx.request({//   url: "http://123.207.32.32:1888/api/city/all",//   success: (res) => {//     const data = res.data.data//     console.log(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) => {const data = res.data.dataconsole.log(data);this.setData({ houselist: data })}})}
})
2.

{houselist}}" wx:key="{{item.data.houseId}}">{item.data.image.url}}">{{item.data.houseName}}

09_(理解)API-网络请求域名的后台配置

image-20230119213501856

10_(掌握)API-网络请求的函数封装和使用

网络请求封装成函数实现步骤

1.在service文件夹中创建index.js文件,通过解构和promise封装

1-2.引入service文件夹中的index.js文件

2.使用封装的函数 promise有点并行的感觉,第一个请求的结果没出来之前也会发送第二个请求

3.await/async 同步 第一个请求的结果没出来之前不会发送第二个请求,容易堵塞,不过可以放到单独的方法中

4.将请求封装到一个单独函数中(推荐),异步方法不会阻塞。方法单独定义,在onLoad调用就行

5.下拉加载更多

1.
// 封装成函数
export function hyRequest(options) {return new Promise((resolve, reject) => {wx.request({ ...options, success: (res) => {resolve(res.data)},fail: reject})})
}
1-2
// pages/09_learn_api/index.js
import { hyRequest, hyReqInstance } from "../../service/index"Page({data: {allCities: {},houselist: [],currentPage: 1},async onLoad() {// 1.网络请求基本使用// wx.request({//   url: "http://codercba.com: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://codercba.com:1888/api/home/houselist',//   data: {//     page: 1//   },//   success: (res) => {//     const data = res.data.data//     this.setData({ houselist: data })//   }// })
2.// 2.使用封装的函数 promise有点并行的感觉,第一个请求的结果没出来之前也会发送第二个请求,// hyRequest({ //   url: "http://codercba.com:1888/api/city/all" // }).then(res => {//   this.setData({ allCities: res.data })// })// hyRequest({//   url: "http://codercba.com:1888/api/home/houselist",//   data: {//     page: 1//   }// }).then(res => {//   this.setData({ houselist: res.data })// })
3.// 3.await/async 同步 第一个请求的结果没出来之前不会发送第二个请求,容易堵塞,不过可以放到单独的方法中// const cityRes = await hyRequest({ //   url: "http://codercba.com:1888/api/city/all" // })// this.setData({ allCities: cityRes.data })// const houseRes = await hyRequest({//   url: "http://codercba.com:1888/api/home/houselist",//   data: { page: 1 }// })// this.setData({ houselist: houseRes.data })
4.// 4.将请求封装到一个单独函数中(推荐),异步方法不会阻塞this.getCityData()this.getHouselistData()// 5.使用类的实例发送请求hyReqInstance.get({url: "/city/all"}).then(res => {console.log(res);})},
5.async getCityData() {const cityRes = await hyRequest({ url: "http://codercba.com:1888/api/city/all" })this.setData({ allCities: cityRes.data })},async getHouselistData() {const houseRes = await hyRequest({url: "http://codercba.com:1888/api/home/houselist",data: { page: this.data.currentPage }})const finalHouseList = [...this.data.houselist, ...houseRes.data]this.setData({ houselist: finalHouseList })// 思考: 为什么这里不需要setData?因为页面不需要刷新this.data.currentPage++},
5.  // 下拉加载更多onReachBottom() {this.getHouselistData()}
})

可不可以怎么写

   一个测试
hyRequest({ url: "http://codercba.com:1888/api/city/all" }).then(res => {this.setData({ allCities: res.data })},err=>{console.log("err");})

11_(掌握)API-网络请求的类封装和使用过程

image-20230119223725723

1.先封装class的网络请求–封装成类

2.引入class

3.使用类的实例发送request请求

  1.
// 封装成类 -> 实例
class HYRequest {constructor(baseURL) {this.baseURL = baseURL}request(options) {const { url } = optionsreturn new Promise((resolve, reject) => {wx.request({...options,url: this.baseURL + url,success: (res) => {resolve(res.data)},fail: (err) => {console.log("err:", err);}})})}get(options) {return this.request({ ...options, method: "get" })}post(options) {return this.request({ ...options, method: "post" })}
}export const hyReqInstance = new HYRequest("http://codercba.com:1888/api")2.
import { hyRequest, hyReqInstance } from "../../service/index"3.// 5.使用类的实例发送请求hyReqInstance.get({url: "/city/all"}).then(res => {console.log(res);})// 6.使用类的实例发送request请求// hyReqInstance.request({//   url: "/home/houselist?page=1"// }).then(res => {//   this.setData({ houselist: res.data })// })

12_(了解)API-小程序中的弹窗相关API

image-20230120100033263




// pages/10_learn_api/index.js
Page({// 1.弹窗相关的APIonShowToast() {wx.showToast({title: '购买失败!',icon: "error",duration: 1000,//蒙版:在未消失的时候可不可以点击后面的操作mask: true,success: (res) => {console.log("res:", res);},fail: (err) => {console.log("err:", err);}})// wx.showLoading({//   title: "加载中ing"// })},onShowModal() {wx.showModal({title: "确定购买吗?",content: "确定购买的话, 请确定您的微信有钱!",confirmColor: "#f00",cancelColor: "#0f0",success: (res) => {if (res.cancel) {console.log("用户点击取消");} else if (res.confirm) {console.log("用户点击了确定");}}})},onShowAction() {wx.showActionSheet({itemList: ["衣服", "裤子", "鞋子"],success: (res) => {console.log(res.tapIndex);},fail: (err) => {console.log("err:", err);}})},}  	

13_(理解)API-小程序的分享API回调函数

image-20230120101122298

// 2.分享功能onShareAppMessage() {return {title: "旅途的内容",path: "/pages/favor/favor",imageUrl: "/assets/nhlt.jpg"}},

14_(掌握)API-小程序的设备信息和位置信息

image-20230120101324354

image-20230120102556422

对于用户的关键信息,需要获取用户的授权后才能获得:

app.json中配置
"permission": {"scope.userLocation": {"desc": "需要获取您的位置信息"}},
// 3.获取用户的设备信息onGetSystemInfo() {// 1.获取手机的基本信息// wx.getSystemInfo({//   success: (res) => {//     console.log(res);//   }// })// 2.获取当前的位置信息wx.getLocation({success: (res) => {console.log("res:", res);}})},      

15_(掌握)API-本地存储Storage的API使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y12gk531-1675304800111)(null)]


// 4.本地存储方式onLocalStorage() {// 同步操作,执行完上一行,才可以执行下一行// 1.存储一些键值对// wx.setStorageSync('name', "why")// wx.setStorageSync('age', 18)// wx.setStorageSync('friends', ["abc", "cba", "nba"])// 2.获取storage中内容// const name = wx.getStorageSync('name')// const age = wx.getStorageSync('age')// const friends = wx.getStorageSync('friends')// console.log(name, age, friends);// 3.删除storage中内容// wx.removeStorageSync('name')// 4.清空storage中内容// wx.clearStorageSync()// 异步操作 ,执行的时候不会阻塞下一行代码的执行wx.setStorage({key: "books",data: "哈哈哈",// 加密但是有版本限制--2.21.3encrypt: true,success: (res) => {wx.getStorage({// 获取key: "books",encrypt: true,success: (res) => {console.log(res);}})}})console.log("-------");}

16_(了解)API-页面跳转-跳转不同的方法

页面跳转存在页面栈–会记录页面跳转的记录,以下方法记录跳转的不同方法

image-20230120110656051

17_(掌握)API-页面的跳转和页面的返回

image-20230120112039188

页面跳转wx.navigateTo({})

// pages/11_learn_nav/index.js
Page({data: {name: "kobe",age: 30,},onNavTap() {const name = this.data.nameconst age = this.data.age// 页面导航操作wx.navigateTo({// 跳转的过程, 传递一些参数过去url: `/pages2/detail/detail?name=${name}&age=${age}`,})}
})跳转过后的页面
// pages2/detail/detail.js
Page({data: {name: "",age: 0},onLoad(options) {// options里面就是跳转时携带的参数console.log(options);const name = options.nameconst age = options.agethis.setData({ name, age })},
})

image-20230120112558104

onBackTap() {// 1.返回导航wx.navigateBack({// 默认值是1.跳转上级页面目录delta:2})}

18_(掌握)API-页面的返回数据传递方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-voZBEjeV-1675304800287)(null)]

image-20230120114240862

{{message}}message: "哈哈哈"detail    onBackTap() {// 1.返回导航wx.navigateBack()// 2.方式一: 给上一级的页面传递数据// 2.1. 获取到上一个页面的实例// const pages = getCurrentPages()// // console.log(pages);通过打印看当前页面和上一个页面的位置,通过pages[pages.length-2]获取到上一个页面// const prePage = pages[pages.length-2]// // 2.2.通过setData给上一个页面设置数据// prePage.setData({ message: "呵呵呵" })},//  页面卸载的生命周期,只用在这里写,就都可以实现了onUnload() {// 2.1. 获取到上一个页面的实例const pages = getCurrentPages()const prePage = pages[pages.length-2]// 2.2.通过setData给上一个页面设置数据prePage.setData({ message: "呵呵呵" })}

19_(掌握)API-页面的返回数据传递方式二

image-20230120115739876

// pages/11_learn_nav/index.js
Page({data: {name: "kobe",age: 30,message: "哈哈哈"},onNavTap() {const name = this.data.nameconst age = this.data.age3.   const that = this// 页面导航操作wx.navigateTo({// 跳转的过程, 传递一些参数过去url: `/pages2/detail/detail?name=${name}&age=${age}`,// 方式二,通过 events:回调函数接受数据
2.      events: {backEvent(data) {console.log("back:", data);const names = data.name
3.          // 修改值携带进来that.setData({name:names})},coderwhy(data) {console.log("why:", data);}}})}
})onBackTap() {// 1.返回导航wx.navigateBack()// 2.方式一: 给上一级的页面传递数据// 2.1. 获取到上一个页面的实例// const pages = getCurrentPages()// // console.log(pages);通过打印看当前页面和上一个页面的位置,通过pages[pages.length-2]获取到上一个页面// const prePage = pages[pages.length-2]// // 2.2.通过setData给上一个页面设置数据// prePage.setData({ message: "呵呵呵" })2.    // 3.方式二: 回调events的函数// 3.1. 拿到eventChannelconst eventChannel = this.getOpenerEventChannel()// 3.2. 通过eventChannel回调函数eventChannel.emit("backEvent", { name: "back", age: 111 })eventChannel.emit("coderwhy", { name: "why", age: 10 })},

20_(了解)API-navigator组件的跳转和返回

image-20230120121732362

返回跳转

21_(理解)登录流程-登录中身份标识的验证

image-20230120121917021

image-20230120121930698

image-20230120122400861

小程序登录不用登录账号和密码,因为直接在微信上登录

image-20230120123956851

image-20230120124758824

小程序通过openid来验证身份

如果账号注册公众号可以获取unionid

22_(掌握)登录流程-登录流程的解析和代码演练

image-20230120125451671

image-20230120130847916

实现步骤登录逻辑

1.方式一:通过原生方法

import { hyLoginReqInstance } from "../../service/index"
// pages/12_learn_login/index.js
Page({// onLoad登录的流程async onLoad() {// 1.获取token, 判断token是否有值const token = wx.getStorageSync('token') || ""// 2.发起请求--判断token是否过期const res = await hyLoginReqInstance.post({url: "/auth",header: {token: token}})// console.log(res);// 2.如果token有值和无值的情况if (token && res.message === "已登录") {console.log("请求其他的数据");} else {this.handleLogin()}},// 第一种写法// handleLogin() {//   // 1.获取code//   wx.login({//     success: (res) => {//       const code = 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)//         }//       })//     }//   })// }
})

2.方式二:通过promise–

1.封装login的promise方法

2.封装成类的请求方法

3.onLoad登录的流程

3.1.获取token, 判断token是否有值

3.2.判断token是否过期

3.3如果token有值和无值的情况

4.第二种写法 --获取login接口处理函数获取token

login.js
export function getCode(){return new Promise((resolve,reject)=>{wx.login({success:(res)=>{resolve(res.code)}})})
}
export const hyLoginReqInstance = new HYRequest("http://123.207.32.32:3000")import { getCode } from "../../service/login";
import { hyLoginReqInstance } from "../../service/index"// pages/12_learn_login/index.js
Page({// onLoad登录的流程async onLoad() {// 1.获取token, 判断token是否有值const token = wx.getStorageSync('token') || ""// 2.发起请求--判断token是否过期--判断token是否正确const res = await hyLoginReqInstance.post({url: "/auth",header: {token: token}})// console.log(res);// 2.如果token有值和无值的情况if (token && res.message === "已登录") {console.log("请求其他的数据");} else {this.handleLogin()}},// 第二种写法 --获取login接口处理函数获取tokenasync handleLogin() {// 1.获取codeconst code = await getCode()// 2.使用code换取tokenconst res = await hyLoginReqInstance.post({url: "/login",data: { code }})// 3.保存tokenwx.setStorageSync('token', res.token)}})

23_(理解)内容回顾和作业布置

第四章:内容回顾

一. 组件化开发

1.1. 直接调用子组件的方法

1.2. 插槽的使用

  • 单个插槽
    • 默认值
  • 多个插槽

1.3. Behaviors混入

1.4. 生命周期函数

  • 组件的生命周期函数
  • 页面的生命周期函数

1.5. Component选项

二. 系统API调用

2.1. 网络请求API

  • 基本使用
  • 域名配置
  • 工具封装:
    • 函数封装
    • 类封装

2.2. 弹窗和分享

  • showToast
  • showModal
  • showActionSheet
  • onShareAppMessage

2.3. 设备和位置信息

  • wx.getSystemInfo
  • wx.getLocation()
    • app.json配置

2.4. Storage的存储

2.5. 页面跳转和数据传递

  • navigateTo
  • navigateBack

数据传递:

  • ?queryString
  • getCurrentPages -> prePage.setData
  • events -> eventChannel

组件跳转

  • navigator组件

2.6. 登录流程

  • 登录的身份的标题

    • openid
  • 登录流程

  • 登录代码演练

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...