这篇博客给刚接触微信小程序的新手们,说说微信小程序里面的自定义组件的封装与使用 ,代码如下:
首先咱们要在miniprogram的文件夹里新建一个componets文件夹,然后在里面新建一个自定义的组件文件夹,里面要包含index.js,index.json,index.wxml,index.wxss四个文件
父组件:
index.wxml:
<view wx:if="{{!nickname }}" class="username" bind:tap="toSetting">点击授权登录</view>
<cloud-tip-modal bindmyevent="myevent" showUploadTipProps="{{showUploadTip}}" />
index.js:
const {
envList
} = require('../../envList');
const db = wx.cloud.database();
const app = getApp();
// pages/me/index.js
Page({
/**
* 页面的初始数据
*/
data: {
openId: '',
showUploadTip: false,
nickname: '',
avatar: ''
},
toSetting() {
this.setData({
showUploadTip: true
})
},
myTask() {
wx.navigateTo({
url: `/pages/task/index`,
});
},
async myevent(e) {
const {
avatar,
nickname
} = e.detail;
let cloudPath = "nickimg/" + new Date().getTime() + "-" + Math.floor(Math.random() * 1000) + '.png';
const avatarUrl = await this.uploadFile(cloudPath, avatar);
let userInfo = {
avatar: avatarUrl.fileID,
nickname: nickname
}
db.collection('users').where({
_openid: app.globalData.openid
}).update({
data: {
...userInfo
}
})
console.log("users表更新成功");
app.globalData.nickname = nickname;
app.globalData.avatar = avatarUrl.fileID;
this.setData({
nickname: nickname,
avatar: avatarUrl.fileID
})
}
});
子组件:
index.html:
<!--miniprogram/components/cloudTipModal/index.wxml-->
<view class="install_tip" wx:if="{{showUploadTip}}">
<view class="install_tip_back"></view>
<view class="install_tip_detail" bindmyevent="myevent">
<button class="avatar-wrapper " open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
<image class="avatar" src="{{avatar}}"></image>
</button>
<input type="nickname" class="weui-input" placeholder="点击获取昵称" bindblur="bindblur" value="{{nickname}}" />
<view class="choose">
<button class="no" bind:tap="no">取消</button>
<button class="yes" bind:tap="yes">确定</button>
</view>
</view>
</view>
index.wxss:
.avatar{
margin-bottom: 10px;
/* border: solid; */
width: 100px;
height: 100px;
}
.weui-input{
/* border: solid; */
display: flex;
width: 25%;
margin-left: 125px;
height: 30px;
}
.choose{
width: 100%;
display: flex;
}
.yes{
flex: 1;
width: 30%;
height: 30px;
}
.no{
flex: 1;
width: 30%;
height: 30px;
}
.install_tip_back {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.4);
z-index: 1;
}
.install_tip_detail {
position: fixed;
display: flex;
text-align: center;
/* justify-content: center; */
flex-direction: column;
background-color: white;
right: 0;
bottom: 0;
left: 0;
top: 60%;
border-radius: 40rpx 40rpx 0 0;
padding: 50rpx;
z-index: 9;
}
.install_tip_detail_title {
font-weight: 400;
font-size: 40rpx;
text-align: center;
}
.install_tip_detail_tip {
font-size: 25rpx;
color: rgba(0,0,0,0.4);
margin-top: 20rpx;
text-align: center;
}
.install_tip_detail_shell {
margin: 70rpx 0;
display: flex;
justify-content: center;
}
.install_tip_detail_copy {
color: #546488;
margin-left: 10rpx;
}
.install_tip_detail_button {
color: #07C160;
font-weight: 500;
background-color: rgba(0,0,0,0.1);
width: 60%;
text-align: center;
height: 90rpx;
line-height: 90rpx;
border-radius: 10rpx;
margin: 0 auto;
}
index.js:
// miniprogram/components/cloudTipModal/index.js
const { isMac } = require('../../envList.js');
Component({
/**
* 页面的初始数据
*/
data: {
showUploadTip: false,
tipText: isMac ? 'sh ./uploadCloudFunction.sh' : './uploadCloudFunction.bat',
avatar:'../../images/icons/avatar.png',
nickname:'',
nicknameError:false,
},
properties: {
showUploadTipProps: Boolean
},
observers: {
showUploadTipProps: function(showUploadTipProps) {
this.setData({
showUploadTip: showUploadTipProps
});
}
},
methods: {
onChooseAvatar(e) {
const { avatarUrl } = e.detail;
this.setData({
avatar: avatarUrl
})
},
bindblur(res){
const value = res.detail.value;
this.data.nickname = value;
},
onInput(e) {
// console.log("nickname=="+e.detail.value);
let value = e.detail.value;
if (value.length>10) {
value = value.slice(0,10);
this.setData({
nickname: e.detail.value,
nicknameError:true
});
}else{
this.setData({
nickname: value,
nicknameError:false
});
}
},
no(){
this.setData({
showUploadTip: false
});
},
yes(){
const {avatar,nickname} = this.data;
this.triggerEvent('myevent',{
avatar,
nickname
});
this.setData({
showUploadTip: false
});
},
onChangeShowUploadTip() {
this.setData({
showUploadTip: !this.data.showUploadTip
});
},
copyShell() {
wx.setClipboardData({
data: this.data.tipText,
});
},
}
});
index.json:
{
"usingComponents": {},
"component": true
}
能看懂代码的兄弟,直接把代码拿走就好,稍有疑惑的兄弟,我来解释一下这个逻辑和注意点
这里主要展示的是一个登录功能:
首先,我们在父组件里点击授权登录就会触发toSetting()函数,把showUploadTip的值从false改成true,那么通过showUploadTipProps就可以把对应的showUploadTip值传到子组件里,
observers: {
showUploadTipProps: function(showUploadTipProps) {
this.setData({
showUploadTip: showUploadTipProps
});
}
},
子组件里的这段代码接收到showUploadTipProps的值并且赋值给showUploadTip,<view class="install_tip" wx:if="{{showUploadTip}}">那么对应的组件页面就会展现出来,
yes(){
const {avatar,nickname} = this.data;
this.triggerEvent('myevent',{
avatar,
nickname
});
this.setData({
showUploadTip: false
});
},
然后点击触发yes()函数的话,通过触发事件绑定myevent,通过<view class="install_tip_detail" bindmyevent="myevent">把对应的值传到父组件的myevent,
async myevent(e) {
const {
avatar,
nickname
} = e.detail;
let cloudPath = "nickimg/" + new Date().getTime() + "-" + Math.floor(Math.random() * 1000) + '.png';
const avatarUrl = await this.uploadFile(cloudPath, avatar);
let userInfo = {
avatar: avatarUrl.fileID,
nickname: nickname
}
db.collection('users').where({
_openid: app.globalData.openid
}).update({
data: {
...userInfo
}
})
console.log("users表更新成功");
app.globalData.nickname = nickname;
app.globalData.avatar = avatarUrl.fileID;
this.setData({
nickname: nickname,
avatar: avatarUrl.fileID
})
},
然后把对应的传过来的参数值进行操作即可。这里面的部分代码可能有些冗余,大家理解之后删除即可。
希望这些对你有所帮助,如果你也觉得有用的话,欢迎点赞收藏呦,方便下次查阅