目录
1.小程序的自定义组件
微信提供了很多内置组件用于搭建小程序的页面,但是在编写页面的过程中依然会遇到很多可以复用的结构。小程序提供一套自定义组件的标准,允许程序员自定义组件,将这些拥有类似功能、`UI`的部分封装起来,方便复用。
假设,自定义一个按钮组件如下:
<my-button title="按钮上的文字"
color="按钮的颜色"
round
bind:doubletap="doubleTap"></my-button>
doubleTap(){
console.log('......')
}
自定义组件的步骤
1. 在`miniprogram/components`目录下,新建`mybutton`文件夹作为组件目录。
2. 右键该文件夹,选择新建`Component`组件,起名字:`index`,在该目录中出现自定义组件四件套。
3. 在`index.wxml` `index.wxss`中定义自定义组件的基本结构、外观。
4. **使用自定义组件:**
1. 在页面中如果需要使用自定义组件,则需要在`页面.json`文件中引入自定义组件:
"usingComponents": {
"my-button": "/components/mybutton/index"
}
2.那么 `my-button` 即是组件的标签名称。使用方法如下:
<my-button></my-button>
<my-button title="按钮上的文字"
color="按钮的颜色"
round
bind:doubletap="doubleTap"></my-button>
doubleTap(){
console.log('......')
}
2.为组件自定义属性
希望通过title属性,控制按钮的文字:
`<my-button title="按钮上的文字" ></my-button>`
**实现步骤**
1. 在组件`index.js`中的`properties`中声明`title`属性:
properties: {
title: { // 一个自定义属性
type: String, // 数据类型:String
value: '默认按钮' // 默认值:默认按钮
}
},
2.在组件`index.wxml`中,可以通过`{{}}`来引用该属性的值:
<view class="btn">
{{title}}
</view>
绑定点击事件
<view
bindtap="tapView"
class="btn {{round?'round':''}}"
style="color:{{color}}; border-color:{{color}}; background-color: {{color}}2;">
{{title}}
</view>
3.为组件自定义事件
在定义子组件的过程中,可以为子组件设计自定义事件(当满足某些条件后,主动触发该事件,父组件即可捕获该事件)。
子组件先定义新的事件类型:例如:`doubletap`,双击时触发,当子组件发现满足了双击的条件时,主动触发该事件。
tapView(){
if(满足了双击的条件){
this.triggerEvent('doubletap', {a:1})
}
}
index.js
methods: { /**组件的方法列表 */
// 监听组件被点击
// 再次需要判断当前点击是否达到了双击的标准
// 如果是,需要通知父组件:有人双击了我
tapView(){
console.log('点击了子组件...')
let now = Date.now() // 当前时间戳
let last = this.data.last //上次点击时间戳
if(now - last < 350){ // 判断 满足了双击事件产生的条件
// 主动通知父组件,触发doubleTap类型的自定义事件
this.triggerEvent('doubletap',{a:1, b:2})
this.data.last = 0
}
this.data.last = now
}
me.js
// 捕获到my-button被双击后触发,并执行该方法
doubleTap(){
console.log(' 双击么么哒!! ')
},
me.wxml
`doubletap`是自定义的类型名称。`triggerEvent`方法将会把该类型的事件通知给父组件,父组件可以通过`bind:doubletap`的方式绑定该事件,并处理:
<my-button bind:doubletap="事件处理函数名"></my-button>
时间处理函数名(e){
处理doubletap事件
e.detail.xxx 获取子组件传来的参数
}
实现效果:
4.`Vant`小程序组件库
下载并配置`vant`组件库
进入`miniprogram`目录下,执行`npm`命令,下载`vant`组件库。
# cd miniprogram
npm init -y
npm i @vant/weapp -S --production
* 下载完成后,将会自动生成`node_modules`文件夹,其中就有`vant`源码。
* 修改`app.json`,删除`style:v2`。防止样式冲突。
* 点击小程序菜单栏中的 **工具** -- **构建`npm`**。 小程序开发工具将会自动带着`vant`源码一起编译生成小程序代码包。构建完毕后,将会在`miniprogram`目录下生成:`miniprogram_npm` 目录。把`vant`的源码编译进该目录中,小程序将会自动带着该目录一起生成小程序安装包。
* 配置完毕。
注意事项: 装完vant 需要清缓存,否则不生效
使用`Vant`组件
1. 在页面的.`json`配置文件中,配置需要引入的组件。
"usingComponents": {
"van-button": "@vant/weapp/button/index",
"van-circle": "@vant/weapp/circle/index"
}
2.页面中直接使用即可:
<van-button type="default">默认按钮</van-button>
<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>
5.搭建项目页面结构:我的模块
5.1实现微信登录
1. 页面中给出一个按钮,点击启动微信登录。
* 页面的初始数据
*/
data: {
userInfo: {
avatarUrl: '',
nickName: '点击登录'
}
},
tapLogin() { // 点击登录
wx.getUserProfile({
desc: '获取用户微信数据,维护会员权益',
success: (res) => {
console.log('获取微信数据', res)
this.setData({
userInfo : res.userInfo
})
}
})
},
<text bindtap="tapLogin">{{userInfo.nickName}}</text>
2. 弹窗提示用户,是否允许使用微信信息:
1. 否:登录失败
2. 是:获取用户信息,将昵称与头像显示出来。
wx.getUserProfile() 该方法可以获取用户的微信信息
现阶段实现的微信登录业务仅仅是从微信服务器中访问昵称与头像并显示而已。并没有将这些信息存到自己家数据库中。所以无法实现:修改头像、修改昵称、记录用户其它信息等功能。
所以说真正的微信登录,不仅是要获取微信用户的基本数据,还要想方设法将数据维护到自己家数据库中,例如:
可以基于小程序云数据库实现**真正的微信登录**:
1. 点击登录,弹出授权窗口,是否允许获取微信信息,选择是。
2. 获取到微信返回的`userInfo`信息后,查询自己家数据库,看一下这个人以前是否登录过,是否在自己家数据库中保存过用户记录:
1. 该用户原来没有登录过(自己家数据库找不到记录),执行注册业务。
2. 该用户原来登录过(自己家数据库找到了记录),执行查询操作,获取用户的最新信息,更新`UI`。
/** 查询当前用户是否存在于自己家数据库中:云数据库users集合 */
queryCurrentUser(){
let db = wx.cloud.database()
db.collection('users').get().then(res=>{
console.log('查询当前用户', res)
// 判断是否查到当前用户
if(res.data.length == 0){ // 没查到,执行注册
this.regist()
}else { // 查到了,获取最新数据,更新userInfo
this.setData({
userInfo : res.data[0]
})
}
})
},
/** 注册,将this.data.userInfo添加到users集合中 */
regist(){
let db = wx.cloud.database()
db.collection('users').add({
data: this.data.userInfo,
success: (res)=>{
console.log('注册成功', res)
}
})
},
修改微信信息 昵称 nickname
**实现思路:**
1. 在云数据库中准备一个新的集合:users,用于保存所有用户数据。
2. 当用户登录后,查询该集合中是否有当前登录用户信息,执行分支业务逻辑。
1. 该用户原来没有登录过(自己家数据库找不到记录),执行注册业务。
2. 该用户原来登录过(自己家数据库找到了记录),执行查询操作,获取用户的最新信息,更新`UI`。
5.2修改头像
**业务分析**
当用户登录成功后,点击用户头像,可以跳转到选择图片界面,选择一张图片后返回上一页,将选中的图片设置到`image`的`src`属性,从而更新头像。(要求持久化保存)
小程序提供了选择图片的相关`API`:
wx.chooseMedia() 选择媒体文件
**实现步骤**
1. 为头像组件绑定点击事件。
2. 点击后选择图片。
3. 图片选择完毕后,动态更新`data.userInfo.avatarUrl`。实现本地化头像更新。如果重新登录,头像还是以前的,并没有持久化保存。
/** 点击头像,选择图片 */
tapAvatar(){
if(!this.data.logined) return;
// 选择头像图片
wx.chooseMedia({
count: 1,
mediaType: ['image'],
success: (res)=>{
console.log('选择了头像', res)
let path = res.tempFiles[0].tempFilePath
// 将path,更新到 data.userInfo.avatarUrl
let userInfo = this.data.userInfo
userInfo.avatarUrl = path
this.setData({ userInfo })
}
})
},
数据更新
tapLogin() { // 点击登录
if( this.data.logined ){ return; }
wx.getUserProfile({
@@ -37,10 +55,12 @@ Page({
if(res.data.length == 0){ // 没查到,执行注册
this.regist()
}else { // 查到了,获取最新数据,更新userInfo
}
this.setData({
userInfo: res.data[0]
})
绑定事件 触发更改头像方法
bindtap="tapAvatar"
5.3修改头像后持久化保存
需求实现思路:当图片选择完毕后,需要立即将该图片上传至图片服务器,并且获取访问该图片的访问链接(以后访问该链接即可看到该图片)。将该访问链接也更新到云数据库中,这样以后再登录时就可以直接获取当前用户的最新头像,从而实现头像的持久化保存。
云存储
类似云盘,可以接收并保存小程序客户端上传上来的各种文件,并且返回访问链接。
如何将图片文件上传至云存储?
wx.cloud.uploadFile()
fileID
**头像持久化保存实现步骤**
1. 当头像选择完毕后,将选中的头像图片上传至云存储。
2. 上传完毕后,将会获取一个访问路径。
3. 将该访问路径更新到云数据库当前用户的`avatarUrl`即可。
/** 上传头像至云存储空间 */
uploadAvatar(path){
// 本地文件路径:path: wxfile://xxx/aa/bb/cccc.jpg
// 保存到云存储时定义的文件路径:cPath 随机生成
let houzhui = path.substring(
path.lastIndexOf('.'))
let cPath = 'img_'+Math.random()+houzhui
wx.cloud.uploadFile({
filePath: path,
cloudPath: cPath,
success: (res)=>{
console.log('上传文件', res)
let fileID = res.fileID // 返回的图片访问链接
// 更新fileID到数据库avatarUrl
this.updateUserAvatar(fileID)
}
})
},
/** 将fileID更新掉当前用户的avatarUrl */
updateUserAvatar(fileID){
let db = wx.cloud.database()
let _id = this.data.userInfo._id
db.collection('users').doc(_id).update({
data: {
avatarUrl: fileID
}
}).then(res=>{
console.log('修改数据库头像路径', res)
wx.showToast({
title: '头像修改完成'
})
}).catch(err=>{
console.log(err)
})
},
项目整体效果:
电影页
影院页
我的页(个人页面)
至此整个项目大体完成,还有许多功能还可以继续完善,后续在进行
感谢小明老师,江湖再见