项目场景:
在做项目中,当我们写到一些共用的js代码时,为了去耦合实现模块化,会把共用js代码提取出来封装好,哪里需要使用到的引用一下就好了。同理的,在小程序开发中,为了精简化项目,我们可以把共用的一部分代码(比如说登录弹窗、活动状态弹窗等)提取出来,写成组件,需要用到的页面引入一下就好了。
Demo演示:
为了方便演示父页与子组件间的数据传输,我写了个简化版的全局登录弹窗,具体可以看下面的GIF
代码部分:
项目结构: 我们先看下目录的具体结构,一般情况下创建的组件都会放到components 文件夹下,需要注意的是创建组件时右键点击的是新建Component ,别点错了不是Page。
① page(父页)
index.json: 当我们创建好组件后,想要引入它,那么需要在父页的json文件里引入它,需要注意一下文件夹路径
{
"usingComponents": {
"login": "../../components/login/login"
},
"navigationBarTitleText": "全局登录"
}
index.wxml:引入之后,我们就可以以标签的形式去使用了,text: 为自定义的组件属性,用于演示把父页的参数传到组件中;updateUserData: 当登录成功想要把数据从子组件传回父页的,就需要用bind绑定一个函数来接收参数
<view class="body">
<view class="row">名字:{{userData.name}}</view>
<view class="row">爱好:{{userData.hobby}}</view>
<button bindtap="clickLogin" type="primary">点击登录</button>
</view>
<login id="login" text="222" bind:updateUserData="updateUserData"></login>
index.js:接着来看下js部分,当点击登录按钮时,需要调用子组件的方法把弹窗打开,那么就需要用到selectComponent() 来指定组件,之后用. 的形式调用子组件的方法就行了。要更新父页的参数,只需要在绑定的函数(updateUserData)的形参里接收一下更新就好
Page({
data: {
userData: {}
},
onLoad: function (options) {
},
clickLogin() {
this.selectComponent("#login").openLoginWin("111")
},
updateUserData(e) {
console.log("子组件函数传过来的值:" + JSON.stringify(e.detail.userData))
this.setData({
userData: e.detail.userData
})
},
})
index.wxss:
.body{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.row{
margin-bottom: 40rpx;
}
② component(子组件)
login.json:
{
"component": true,
"usingComponents": {}
}
login.wxml:弹窗的图片自己下载一下,重命名放到images文件夹就好
<view class="mask-layer" wx:if="{{isShowLoginWin}}" bindtap='closeLoginWin'></view>
<view class='login-block' wx:if="{{isShowLoginWin}}" animation='{{animationTranslateY}}'>
<view class="container">
<image bindtap='closeLoginWin' class="close" src="../../images/close.png"></image>
<button bindtap="getUserData" class="btn">
<image class="logo" src="../../images/wx.png"></image>
微信快速登录
</button>
</view>
</view>
login.js:接着来看下组件的js,properties 属性列表就是用来存放父页中子标签传过来的值,需要注意的是每一个属性都需定义类型,之后就可以在子组件中直接使用了;接着有个专门用来放方法的地方methods ,当父页调用开启弹窗的方法(openLoginWin)后,就可以在形参里获取到父页穿过来的值,同样的也可以直接使用组件的属性值,弹窗的上下滑动动画可以忽略;最后当用户点击确认获取到数据后,使用triggerEvent("函数名","参数") 方法就可以调用父页的函数把参数传回去了。
Component({
properties: {
text: {
type: String,
value: ''
},
},
data: {
isShowLoginWin: false
},
methods: {
openLoginWin: function (e) {
console.log("父页函数传过来的值:" + e)
console.log("父页中子标签绑定的值:" + this.properties.text)
let animation = wx.createAnimation({
duration: 300,
timingFunction: 'linear'
})
animation.translateY(300).step()
this.setData({
animationTranslateY: animation.export(),
isShowLoginWin: true
})
setTimeout(() => {
animation.translateY(0).step()
this.setData({
animationTranslateY: animation.export(),
})
}, 100)
},
closeLoginWin: function () {
var animation = wx.createAnimation({
duration: 300,
timingFunction: 'linear'
})
this.animation = animation
animation.translateY(500).step()
this.setData({
animationTranslateY: animation.export(),
})
setTimeout(() => {
animation.translateY(0).step()
this.setData({
animationTranslateY: animation.export(),
isShowLoginWin: false
})
}, 300)
},
getUserData(e) {
let userData = {
name: 'weianl',
hobby: '睡大觉'
}
this.setData({
isShowLoginWin: false,
})
this.triggerEvent('updateUserData', {
userData: userData
})
wx.showToast({
title: '登录成功!',
})
}
}
})
login.wxss:
.mask-layer {
z-index: 9998;
position: fixed;
top: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0.5;
}
.login-block {
z-index: 9999;
position: fixed;
bottom: 0;
width: 100%;
height: 240rpx;
background-color: #fff;
border-radius: 40rpx 40rpx 0 0;
}
.login-block .container {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: #fff;
border-radius: 40rpx 40rpx 0 0;
}
.login-block .container .close {
position: absolute;
top: 0;
left: 50%;
margin-left: -45rpx;
margin-top: -135rpx;
width: 90rpx;
height: 90rpx;
}
.login-block .container .btn {
display: flex;
justify-content: center;
align-items: center;
width: 540rpx !important;
height: 100rpx !important;
background-color: #46BB36;
color: white;
border-radius: 100rpx;
}
.login-block .btn .logo {
width: 50rpx;
height: 50rpx;
margin-right: 15rpx;
}
over~
|