介绍,健身记录管理,完全就是一个单机应用
一、首页
index.axml
<!--textarea.axml-->
<view>
<view class="summary">
<view class="fontLarger">fitness summary</view>
<label a:for="{
{summaries}}">
<label class="item" data-index={
{index}} data-content={
{item.content}} onTap="updateNote">
<label class="item">{
{item.fitType}}</label>
<label class="item">{
{item.fitCnt}}</label>
</label>
</label>
</view>
<view class="page" a:for="{
{notes}}">
<view class="card" data-index={
{index}} data-content={
{item.content}} onTap="updateNote">
<view class=""><label>fitness type: </label>{
{item.fitType}}</view>
<view class=""><label>fitness count: </label>{
{item.fitCnt}}</view>
<view class=""><label>fitness time: </label>{
{item.fitTime}}</view>
</view>
</view>
<modal show="{
{showSearchModal}}" height='30%' onCancel="searchModalCancel" onSubmit='searchModalSubmit'>
<view class="remind_del"><image mode="scaleToFill" src="/page/image/remind_del.png"/></view>
</modal>
<view><button class="btn" onTap="toPage13">增加</button></view>
<view><button style="bottom:30px;background-color:red;" class="btn" onTap="deleteAll">删除</button></view>
</view>
index.acss
.page {
font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif;
padding: 8rpx;
flex: 1;
}
.content{
font-size: x-large;
color: black;
font-weight: bolder;
}
.item{
font-size: small;
margin-right: 5px;
color: black;
}
.card{
width: 80%;
margin-left: auto;
margin-right: auto;
border: 1px solid rgb(216, 10, 206);
border-radius: 15px;
padding: 5px;
margin-top: 5px;
font-size: small;
}
.fontLarger{
font-size: larger;
font-weight: bolder;
}
.summary{
width: 80%;
margin-left: auto;
margin-right: auto;
}
.btn_img{
z-index: 9;
position: fixed;
background: url('/page/image/del.png');
margin-top: -50px;
margin-left: 280px;
width: 50px;
height: 50px;
}
.remind_del{
margin: 0 auto;
width:300px;
height:60px;
}
.btn {
z-index: 10;
width: 50px;
height: 50px;
color: cornsilk;
font-family: 黑体,宋体,Arieal;
font-weight: bold;
background-color: gray;
border-radius: 50%;
border: 1px solid black;
right: 30px;
bottom: 100px;
position: fixed;
}
index.js
Page({
data: {
notes: [],
summaries: [],
array: ['仰卧起坐','俯卧撑','引体向上','自重深蹲','俯身W抬头','窄距俯卧撑','屈腿两头起','5kg哑铃','站立扭腰','单车推拉','反转上杠','跳绳','跑步','游泳','平板支撑','握力器'],
showSearchModal: false,
},
compare(prop,align){
return function(a,b){
var value1=a[prop];
var value2=b[prop];
if(align=="positive"){
//正序
return new Date(value1)-new Date(value2);
}else if(align=="inverted"){
//倒序
return new Date(value2)-new Date(value1);
}
}
},
onShow(){
dd.getStorage({
key: 'fitness_record',
success: (res) => {
if(res.data!==null){
const notes = res.data;
console.log('notes',notes)
//对数据进行排序
notes.sort(this.compare('fitTime','inverted'));
console.log("倒叙排列",notes)
let groups={
};
notes.forEach(c=>{
let value=c['fitType'];
groups[value]=groups[value]||[];
groups[value].push(c);
});
console.log('groups',groups)
var summaries = []
for(var key in groups){
var cnt = 0;
for(var item of groups[key]){
cnt += parseInt(item.fitCnt);
}
var summ = {
}
summ['fitType']= key;
summ['fitCnt']=cnt;
summaries.push(summ);
}
console.log('summaries',summaries)
this.setData({
notes})
this.setData({
summaries})
}
},
fail: function(res){
dd.alert({
content: res.errorMessage});
}
});
},
toPage13(){
dd.redirectTo({
url:'/page/page13_1/index'});
},
updateNote(event){
const content= event.target.dataset.content;
const index= event.target.dataset.index;
dd.redirectTo({
url:'/page/page13_1/index?content='+content+'&index='+index});
},
del(event){
const index= event.target.dataset.index;
console.log(index);
//设置data,设置缓存
const notes = this.data.notes;
notes.splice(index,1);
this.setData({
notes});
//写入缓存
dd.setStorage({
key: 'notes',
data: notes,
success: function() {
dd.alert({
content: '删除成功'});
}
});
},
deleteAll(){
this.setData({
showSearchModal: true})
},
searchModalCancel(){
this.setData({
showSearchModal: false,
});
},
searchModalSubmit(){
this.setData({
showSearchModal: false,
});
var _this = this;
dd.removeStorage({
key: 'fitness_record',
success: function(){
dd.alert({
content: '删除成功'});
_this.setData({
notes: []})
}
});
},
});
index.json
{
"defaultTitle": "fitness management",
"usingComponents": {
"modal": "/page/component/modal/modal"
}
}
第二页
index.axml
<!--textarea.axml-->
<view class="page">
<view class="page-section">
<form onSubmit="bindFormSubmit">
<picker onChange="bindPickerChange" value="{
{index}}" range="{
{array}}">
<view class="row">
<view class="row-extra"><label>fitness Type:</label>{
{array[index]}}</view>
</view>
</picker>
<view class="row">
</view>
<label>fitness count:</label><input name="fitCnt" type="number" value="{
{record.fitCnt}}"/>
<view class="page-section-btns">
<button onTap="back" size="mini" type="primary">返回</button>
<button form-type="submit" size="mini" type="primary">提交</button>
</view>
</form>
</view>
</view>
index.js
Page({
data: {
index:0,
array: ['仰卧起坐','俯卧撑','引体向上','自重深蹲','俯身W抬头','窄距俯卧撑','屈腿两头起','5kg哑铃','站立扭腰','单车推拉','反转上杠','跳绳','跑步','游泳','平板支撑','握力器'],
record: {
}
},
bindPickerChange(e) {
console.log('picker发送选择改变,携带值为', e.detail.value);
this.setData({
index: e.detail.value,
});
},
onLoad(options){
console.log('进入')
},
onShow(){
},
bindButtonTap() {
this.onFocus();
},
onFocus() {
this.setData({
focus: true,
});
},
onBlur() {
this.setData({
focus: false,
});
},
bindTextAreaBlur(e) {
console.log(e.detail.value);
},
bindFormSubmit(e) {
console.log('e.detail.value.fitCnt',e.detail.value.fitCnt)
if(e.detail.value.fitCnt===""){
console.alert("提交失败,内容为空!");
return;
}
var tempNotes;
//先读出缓存数据
dd.getStorage({
key: 'fitness_record',
success: (res) => {
console.log("缓存数据:",res.data);
if(res.data===null){
tempNotes = [];
}else{
tempNotes = res.data;
}
const record = {
fitType: this.data.array[this.data.index],
fitCnt: e.detail.value.fitCnt,
fitTime: new Date().toLocaleDateString()+' '+new Date().toLocaleTimeString(),
}
console.log('record',record)
const index = this.data.record.index;
if(index){
tempNotes[index] = record;
}else{
tempNotes.push(record);
}
console.log("写入缓存数据",tempNotes)
//写入缓存
dd.setStorage({
key: 'fitness_record',
data: tempNotes,
success: function() {
dd.alert({
content: '写入成功'});
}
});
},
fail: function(res){
dd.alert({
content: res.errorMessage});
}
});
},
back(){
dd.redirectTo({
url:'/page/page13/index'});
}
});
index.json
{
"defaultTitle": "fitness management"
}
自定义组件
page/component/modal
modal.axml
<view class='mask' a:if='{
{show}}' onTap='clickMask'>
<view class='modal-content' style='height:{
{
height}}'>
<scroll-view scroll-y class='main-content'>
<slot></slot>
</scroll-view>
<view class='modal-btn-wrapper'>
<view class='cancel-btn' style='color:rgba(7,17,27,0.6)' onTap='cancel'>取消</view>
<view class='confirm-btn' style='color:#13b5f5' onTap='submit'>确定</view>
</view>
</view>
</view>
modal.acss
.mask{
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0,0,0,0.4);
z-index: 9999;
}
.modal-content{
flex-direction: column;
width: 90%;
/* height: 80%; */
position: fixed;
top: 10%;
left: 5%;
background-color: #fff;
border-radius: 10rpx;
}
.modal-btn-wrapper{
display: flex;
flex-direction: row;
height: 100rpx;
line-height: 100rpx;
background-color: #fff;
border-radius: 10rpx;
border-top: 2rpx solid rgba(7,17,27,0.1);
}
.cancel-btn, .confirm-btn{
flex: 1;
height: 100rpx;
line-height: 100rpx;
text-align: center;
font-size: 32rpx;
}
.cancel-btn{
border-right: 2rpx solid rgba(7,17,27,0.1);
}
.main-content{
flex: 1;
height: 100%;
overflow-y: hidden;
}
modal.js
/**
* 自定义modal浮层
* 使用方法:
* <modal show="{
{showModal}}" height='80%' onCancel="modalCancel" onSubmit='modalSubmit'>
<view>你自己需要展示的内容</view>
</modal>
属性说明:
show: 控制modal显示与隐藏
height:modal的高度
onCancel:点击取消按钮的回调函数
onSubmit:点击确定按钮的回调函数
*/
Component({
/**
* 组件的属性列表
*/
props: {
// modal的默认高度
height: '60%',
//是否显示modal
show: false,
// submit()
onSubmit:(data) => console.log(data),
// onCancel()
onCancel:(data) => console.log(data),
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
clickMask() {
// this.setData({show: false})
},
cancel(e) {
// this.setData({ show: false });
this.props.onCancel(e);
},
submit(e) {
// this.setData({ show: false });
this.props.onSubmit(e);
}
}
})
modal.json
{
"component": true,
"usingComponents": {
}
}