前言
- 最近正在学习微信小程序开发,便合作仿了个京东购物微信小程序,我负责的主要是我的界面,这里分享一下我的学习过程,欢迎一起交流。

开发准备
总体架构
| -components 自定义组件
| -dialogDate 选择出生日期
| -dialogGender 选择性别
| -dialogImg 更换头像
| -dialogName 修改昵称
| -config 数据
| -config.js
| -images 图标
| -my
| -pages
| -my 我的界面页
| -set 账户设置界面页
| -person 个人信息界面页
项目效果
我的界面

- 这里我的界面需要自定义顶部样式,只需在my.json中添加一行代码就可以了
"navigationStyle": "custom"
头部导航栏渐变

- 界面头部导航栏有个下拉渐变的效果,我是通过改变头部导航栏背景的透明度
opacity
来实现的
<view class="page_nav">
<view class="nav" style="opacity: {{ num }}"></view>
<view class="title">我的</view>
</view>
onPageScroll(e){
this.setData({
num: (200 - e.scrollTop) / 200
})
},
- onPageScroll监听用户滑动页面事件,参数对象crollTop表示页面在垂直方向已滚动的距离,js数据绑定来改变opacity的值,从而实现页面下拉头部导航栏渐变效果。
.page_nav {
height: 11vh;
width: 100%;
position: fixed;
background-color: #fff;
}
- 因为当页面下拉到一定距离时,头部导航栏背景是白色的而不是纯透明的,所以别忘了设置背景颜色。
页面数据
- 页面的数据放在config.js里,在模块里写好模块接口,
module.exports
提供了暴露接口的方法。然后再js中require
导出数据。


<view class="order-box">
<view class="order-list" wx:for="{{order}}" wx:key="id">
<view class="order-column" data-id="{{item.id}}">
<image mode="aspectFill" class="order-imgbox" src="{{item.icon}}"/>
<view class="order-title">{{item.name}}</view>
</view>
</view>
<view class="border">
<image class="border" src="../../images/my/border.png"></image>
</view>
<view class="viewticket">查看发票</view>
</view>
- 页面的主体部分样式差不多,都是用wx:for循环来写。采用了弹性布局,其中
flex-wrap: wrap;
让弹性盒元素在必要的时候拆行。
账户设置界面

页面布局
- 账户设置界面页采用了WeUI组件中的cell组件,很快就写出了页面。
<mp-cells>
<mp-cell link>
<view>我的收货地址</view>
<view class="footer" slot="footer">管理我的地址</view>
</mp-cell>
<mp-cell link>
<view>发票抬头管理</view>
<view class="footer" slot="footer">管理增票资质</view>
</mp-cell>
</mp-cells>
个人信息界面

组件声明
- 页面使用WeUI组件、Vant组件和自定义组件均要声明。其中van-toast文字提示组件是点击用户名的提示,而wx.showToast提示的文字超过一定数量就换行了。
"usingComponents": {
"mp-cells": "../../miniprogram_npm/weui-miniprogram/cells/cells",
"mp-cell": "../../miniprogram_npm/weui-miniprogram/cell/cell",
"dialogName": "../../components/dialogName/dialogName",
"dialogImg": "../../components/dialogImg/dialogImg",
"dialogDate": "../../components/dialogDate/dialogDate",
"dialogGender": "../../components/dialogGender/dialogGender",
"van-toast": "@vant/weapp/toast/index"
}
自定义组件
dialogImg
- 这里不足之处是还只能实现简单的更换头像,没有把头像传到云端保存。
changeimage() {
var _this = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
_this.setData({
pic: res.tempFilePaths
})
}
})
this.triggerEvent('ImgEvent', this.data.pic);
},
ImgEvent(e) {
console.log(e.detail);
this.setData({
pic : e.detail
})
},
- 父组件通过
this.triggerEvent()
获得子组件传递过来的值pic,后面几个组件均是如此。this.triggerEvent('',{},{})的第一个参数是自定义事件名称,这个名称是在页面调用组件时bind的名称,第二个对象就是想要的状态和值。
dialogName
getInputValue(e){
this.setData({
name: e.detail
})
},
_cancelEventName(){
this.triggerEvent("cancelEvent")
},
_confirmEventName(){
this.triggerEvent("confirmEvent");
this.triggerEvent('myevent', this.data.name);
console.log(this.data.name, '----');
}
- bindinput='getInputValue'获取输入框内容,打印的结果如下,e.detail.value为输入的值,e.detail.cursor则是输入的字符长度。输入的值通过点击确认按钮传到父组件,然后显示出来,建议多使用console.log()跟进一下数据传递。
myevent(e) {
console.log(e.detail);
if (e.detail.cursor < 3 ) {
Toast({
message: '不符合昵称要求,请重新输入',
duration: 2000
})
} else {
this.setData({
name : e.detail.value
})
app.globalData.name = this.data.name;
}
},
onShow: function () {
this.setData({
name: app.globalData.name
})
},
- 多个页面共用同一个数据昵称,并修改昵称后,各页面同步更新昵称。因为小程序里globalData存储的是全局对象,所以多个页面使用到的数据就放到globalData里可实现同步。

dialogGender

<!-- wxml -->
<van-popup show="{{isShow}}" round position="bottom" custom-style="height:50%"
bind:click-overlay="_cancelEventGender">
<view class="container">
<view class="header">
<view class="title">性别</view>
<image class="x" src="../../images/my/dialog-cancle.png" bindtap="_cancelEventGender"/>
</view>
<view class="content">
<van-picker show-toolbar="{{false}}"
columns="{{ columns }}"
default-index="{{ 2 }}"
bind:change="onChange"
></van-picker>
</view>
<view class="footer">
<button class="btn1" catchtap="_cancelEventGender" style="width:350rpx">取消</button>
<button class="btn2" catchtap="_confirmEventGender" style="width:350rpx">确认</button>
</view>
</view>
</van-popup>
// .js
data: {
isShow: false,
columns: [
'男','女','保密'
],
value: ''
},
onChange(e) {
console.log(e.detail)
this.setData({
value: e.detail.value
})
},
dialogDate

<van-datetime-picker
type="date"
value="{{ currentDate }}"
item-height="46"
min-date="{{ minDate }}"
max-date="{{ maxDate }}"
bind:input="onInput"
formatter="{{ formatter }}"
show-toolbar="{{ false }}"
visible-item-count="5"
/>
- van-datetime-picker 日期组件设置选择日期范围时,并不是直接date里minDate到maxDate,小程序显示的范围实际都往后推一个月。这里的组件范围是1900年01月01日到2030 年12月28日。onInput是当值发生变化时触发,获取选择的日期。
- new Date()获取时间,getFullYear()从date对象以四位数字返回年份,getMonth()从date对象返回月份 (0 ~ 11),getDate()从date对象返回一个月中的某一天 (1 ~ 31)。
data: {
isShow: false,
minDate: new Date(1900, 0, 1).getTime(),
maxDate: new Date(2030, 11, 28).getTime(),
currentDate: new Date().getTime(),
formatter(type, value) {
if (type === 'year') {
return `${value}年`;
}
if (type === 'month') {
return `${value}月`;
}
return `${value}日`;
},
},
methods: {
onInput(event) {
var time = event.detail
var date = new Date(time)
let year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
console.log(year, month, day);
if (month >= 1 && month <= 9) { month = `0${month}` }
if (day >= 1 && day <= 9) { day = `0${day}` }
this.currentDate = `${year}年${month}月${day}日`
this.setData({
currentDate: event.detail,
});
},
hideDialog(){
this.setData({
isShow: false
})
},
showDialog(){
this.setData({
isShow: true
})
},
_cancelEventDate() {
this.triggerEvent("cancelEvent")
},
_confirmEventDate() {
this.triggerEvent("confirmEvent");
this.triggerEvent("dateEvent", this.currentDate);
console.log(this.currentDate, '---------');
}
}
源码
本项目源码
结语
- 如果你觉得看完对你有些许帮助,就不妨点个👍吧!如果文章有哪里不对的地方,欢迎指正交流。
