小程序项目学习--第四章:组件化-插槽-混入-生命周期-系统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
  • 登录流程

  • 登录代码演练

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...