【微信小程序项目实战】TodoList-项目主体搭设(2)
创始人
2024-05-31 10:50:00
0

目录

      • JS 部分
        • 数据 data
        • onShow
        • 输入框双向绑定
        • 保存与读取
        • 添加新的待办事项
        • 完成待办事项
        • 删除待办事项
      • WXML
        • 顶部输入框
        • 主体
        • 回到顶部按钮
      • 完整代码
        • JS
        • WXML
        • WXSS

JS 部分

为便于分析各个组件的相互作用与原理,故先从 JS 入手,而后再完善 HTML 部分

以下所有代码(除了 import 导包语句)都写在 todo.jsPage({}) 对象内


数据 data

作为一款小而精的 todolist 小程序,我们仅需下方五个属性即可解决所有代码逻辑

  1. inputValue 双向绑定输入框内容
  2. todoList 当前的 todo 表
  3. currentUndo 当前未完成的待办事项数
  4. allComplete 事项是否全部完成
  5. isFocus 用于搜索框自动获取焦点
data: {inputValue: '',todoList: [],currentUndo: 0,allComplete: false,isFocus:false},

onShow

由于我们没有在 app.json 中设置总标题,故在每个页面打开后,最好都在 onShow 钩子里面显式指定当前页面标题

// 进入此页面时,自动设置好标题onShow: function () {wx.setNavigationBarTitle({title: 'Todo待办事项'})},

输入框双向绑定

由于微信小程序 功能太少太烂 ,特别是仅仅提供了单向绑定,而不像 vue 还有 v-model 执行双向绑定;

所有这里需要开发者自行实现双向绑定功能,具体流程即:监听输入框内容,内容发生改变触发回调函数修改对应的值,而通过单向绑定,实现值的动态变化

// 输入框双向绑定处理inputChange(e) {this.setData({// e.detail.value可视为一种固定写法,可以从input类型的组件获取其值inputValue: e.detail.value})},

保存与读取

代码不难理解,即我们需要在每次对 todo 进行增删后,都自带保存数据到本地,这样子下次开启小程序就可直接读取数据了

onLoad 回调保证页面加载时自动从内存读取 todolist 数据

// 保存todos到本地内存saveTodos() {wx.setStorageSync('todo_list', this.data.todoList)},// 加载todos列表loadTodos() {let todos = wx.getStorageSync('todo_list')if (todos) {let undo = todos.filter((item) => {return !item.complete}).lengththis.setData({todoList: todos,currentUndo: undo})}console.log(todos);},// 页面加载钩子调用loadTodosonLoad() {this.loadTodos()},

添加新的待办事项

添加新待办事项的代码逻辑

// 将新的待办事项添加到栏内addTodo() {// 如果编辑框文本为空或者仅有空格的话,不予添加if (!this.data.inputValue || !this.data.inputValue.trim()) return// 每次都需要单独取出todolist然后push新的内容进去,最后setdata,你可以将其当做固定套路let todos = this.data.todoListtodos.push({title: this.data.inputValue,complete: false})this.setData({inputValue: "",todoList: todos,currentUndo: this.data.currentUndo + 1,   // 添加新待办,未完成数+1isFocus:true  // 添加完一个待办后,自动令编辑框获得焦点,省去客户重复点击过程})// 每次修改完毕都必须保存一下!this.saveTodos()},

完成待办事项

请注意此处 complete 状态的设置:点击一次完成事项,再点击一次取消完成变为待办,此时就需要对 complete 做出判断,以动态增减 currentUndo 的数值量

// 点击完成单个事项toggleTodo(e) {let index = e.currentTarget.dataset.indexlet todos = this.data.todoListtodos[index].complete = !todos[index].completethis.setData({todoList: todos,currentUndo: this.data.currentUndo + (todos[index].complete ? -1 : 1),})this.saveTodos()},// 选中全部的待办事项toggleAllTodos() {this.data.allComplete = !this.data.allCompletelet todos = this.data.todoListtodos.forEach(i => {i.complete = this.data.allComplete})this.setData({todoList: todos,currentUndo: this.data.allComplete ? 0 : todos.length})this.saveTodos()},

删除待办事项

删除单个待办事项的方法为通过索引找到该 todo,并使用 splice 删去,之后更新数据即可

删除多个待办事项时需要配合 foreach 方法

// 删除单个待办事项removeTodo(e) {let index = e.currentTarget.dataset.indexlet todos = this.data.todoListlet remove = todos.splice(index, 1)[0]this.setData({todoList: todos,currentUndo: this.data.currentUndo - (remove.complete ? 0 : 1)})this.saveTodos()},// 删除选中项removeTodos(e) {let todos = this.data.todoListlet remain = []todos.forEach(i => {if (!i.complete) remain.push(i)})this.setData({todoList: remain})this.saveTodos()// wx自带的手机振动接口,vibrateShort表示振动15mswx.vibrateShort()},

WXML

顶部输入框

这里涉及到的 t-input 配置项可以自行前往官网查询 API,这里不做过多解释
bind:change、bind:blur、bind:enter 分别表示 内容改变、是否获取焦点、按下回车键 后的回调函数

对于 t-button,如果他在 t-input 内部,则需使用 slot="suffix" 指定插槽来安放该 button


{inputValue}}"style="border-radius: 12rpx;"clearableplaceholder="请输入事项名称"confirm-type="done"bind:change="inputChange"bind:blur="isFocus=!isFocus"bind:enter="addTodo"focus="{{isFocus}}">{inputValue}}"slot="suffix"theme="light"size="small"bindtap="addTodo">添加


主体

block 配以 wx:if,实现状态页显示:当待办事项列表为空时,动态判断并显示 404 页面


{todoList.length}}">{currentUndo}}">待完成任务 {{currentUndo}}{todoList.length>currentUndo}}">{item.complete?'comp':''}}"wx:for="{{todoList}}"wx:key="index"data-index="{{index}}"bindtap="toggleTodo">{ item.complete ? 'success' : 'circle' }}">{{ item.title }}{index}} "/>

当前还没有待办事项哦~


回到顶部按钮



{todoList.length>6}}" icon="arrow-up" bind:click="fabBack2Top" />

CSS 部分由于不方便表述,故留到文末以源码的形式展现给大家


完整代码

JS

import Message from "tdesign-miniprogram/message/index";// pages/todo/todo.js
Page({data: {inputValue: "",todoList: [],currentUndo: 0,allComplete: false,isFocus: false,},// 进入此页面时,自动设置好标题onShow: function () {wx.setNavigationBarTitle({title: "Todo待办事项",});},// 输入框双向绑定处理inputChange(e) {this.setData({inputValue: e.detail.value,});},// 保存todos到本地内存saveTodos() {wx.setStorageSync("todo_list", this.data.todoList);},// 加载todos列表loadTodos() {let todos = wx.getStorageSync("todo_list");if (todos) {let undo = todos.filter((item) => {return !item.complete;}).length;this.setData({todoList: todos,currentUndo: undo,});}console.log(todos);},// 页面加载钩子调用loadTodosonLoad() {this.loadTodos();},// 将新的待办事项添加到栏内addTodo() {if (!this.data.inputValue || !this.data.inputValue.trim()) return;let todos = this.data.todoList;todos.push({title: this.data.inputValue,complete: false,});this.setData({inputValue: "",todoList: todos,currentUndo: this.data.currentUndo + 1,isFocus: true,});this.saveTodos();},// 悬浮按钮回到顶部fabBack2Top() {wx.pageScrollTo({duration: 500,scrollTop: 0,});},// 点击完成单个事项toggleTodo(e) {let index = e.currentTarget.dataset.index;let todos = this.data.todoList;todos[index].complete = !todos[index].complete;this.setData({todoList: todos,currentUndo: this.data.currentUndo + (todos[index].complete ? -1 : 1),});this.saveTodos();},// 选中全部的待办事项toggleAllTodos() {this.data.allComplete = !this.data.allComplete;let todos = this.data.todoList;todos.forEach((i) => {i.complete = this.data.allComplete;});this.setData({todoList: todos,currentUndo: this.data.allComplete ? 0 : todos.length,});this.saveTodos();},// 删除单个待办事项removeTodo(e) {let index = e.currentTarget.dataset.index;let todos = this.data.todoList;let remove = todos.splice(index, 1)[0];this.setData({todoList: todos,currentUndo: this.data.currentUndo - (remove.complete ? 0 : 1),});this.saveTodos();},// 删除选中项removeTodos(e) {let todos = this.data.todoList;let remain = [];todos.forEach((i) => {if (!i.complete) remain.push(i);});this.setData({todoList: remain,});if (this.data.currentUndo === 0) {Message.success({context: this,content: "完成所有任务,休息一下吧!",duration: 2000,offset: [20, 32],closeBtn: true,});}this.saveTodos();wx.vibrateShort();},
});

WXML

{inputValue}}"style="border-radius: 12rpx;"clearableplaceholder="请输入事项名称"confirm-type="done"bind:change="inputChange"bind:blur="isFocus=!isFocus"bind:enter="addTodo"focus="{{isFocus}}">{inputValue}}"slot="suffix"theme="light"size="small"bindtap="addTodo">添加{todoList.length}}">{currentUndo}}">待完成任务 {{currentUndo}}{todoList.length>currentUndo}}">{item.complete?'comp':''}}"wx:for="{{todoList}}"wx:key="index"data-index="{{index}}"bindtap="toggleTodo">{ item.complete ? 'success' : 'circle' }}">{{ item.title }}{index}} "/>当前还没有待办事项哦~{todoList.length>6}}"icon="arrow-up"bind:click="fabBack2Top"/>


WXSS

.todo-container {margin: 0;padding: 0;width: 100vw;min-height: 100vh;background-color: #ededed;display: flex;flex-direction: column;position: relative;
}.todo-input {margin: 12rpx 32rpx;display: flex;flex-direction: row;justify-content: space-between;
}.todo-empty {display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100%;
}
.todo-empty image {width: 450rpx;height: 450rpx;
}/* 悬浮按钮 */
.fab {position: absolute;right: 0;bottom: 0;
}/* 多选操纵栏 */
.todo-control {display: flex;flex-direction: row;justify-content: space-between;align-items: center;height: 80rpx;margin: 12rpx 32rpx;
}
.todo-control image {height: 70rpx;width: 70rpx;
}/* todo项目展示 */
.todo-items {border-radius: 8rpx;height: 120rpx;background-color: white;margin: 10rpx 32rpx;display: flex;flex-direction: row;justify-content: space-between;align-items: center;
}
.comp {background-color: lightgray;
}
.todo-items .checkbox {margin-left: 24rpx;
}
.todo-items .title {min-width: 70%;max-width: 70%;text-overflow: ellipsis;overflow: hidden;white-space: nowrap;
}
.todo-items .remove {margin-right: 24rpx;
}

相关内容

热门资讯

纺织工业汇聚品牌星河 在刚刚落幕的第九届亚洲冬季运动会上,国产服装大放光彩。无论是科技感十足的运动服,还是庄重又雅致的领奖...
杨婧茹 “苔花”翻盘 闪耀赛... 转自:黑龙江日报 杨婧茹在江原道冬青奥会领奖台上。资料片 □本报记者 赵宇清 哈...
上海部署首个高校国产化Deep... 转自:上观新闻2月17日开学第一天,上海交通大学推出国内高校首个全国产化、全系列本地部署的“满血版”...
甘孜企业有了“电保姆” 本报讯 近日,康定市藏家人菌类生产加工农民专业合作社里,国网甘孜供电公司员工洛绒降泽和鲁林对该企业配...
云南民族村将送上“三多节”福利   本报讯 记者杨官荣报道 云南民族村将于3月推出“三多节”优惠活动,活动期间女性游客入园门票优惠价...
“零距离”感受四川发展强劲动能 □四川日报全媒体记者 刘佳  2月17日至19日,省人大常委会组织部分在川全国人大代表深入成都市、资...
春肥下摆有序推进 转自:黑龙江日报 本报讯(熊剑飞 记者姜斌)庄稼一枝花,全靠肥当家。连日来,一辆辆满载肥料的...
情暖寒假 我省团组织开展活动服...   本报讯 记者孙潇报道 近日,记者从共青团云南省委获悉,为帮助广大儿童度过一个安全、健康、充实、快...
陈琦伟 通过冰雪产业带动其他... 转自:黑龙江日报 □文/本报记者 董盈 摄/本报记者 姜轶东 参加亚布力中国企业家论坛...
上海本周大回暖,最高温增幅10... 转自:上观新闻晴雨“打太极”,上海本周天气频繁变换。好消息是,湿冷天气即将收尾,大回暖就要来了。上海...
坚持守正创新 推进法治建设 □陈韵好 王伦刚  坚持守正创新是习近平新时代中国特色社会主义思想的世界观与方法论的主要内容之一,坚...
乡村给郑重的灵魂注入了什么? 转自:上观新闻“我就是一个农民。”这是郑重老人常说的一句话。他乡音未改,“农民”,他说出来,音“能民...
理论专刊|以数字技术创造冰雪旅... 转自:黑龙江日报 丁正良 丁正良 于冠一 习近平总书记指出:“要统筹生态环境保护...
第112届全国糖酒会首设AI设... 本报讯(向鹤玲 四川日报全媒体记者 王型芳)日前,记者从第112届全国糖酒商品交易会组委会获悉,本届...
昆明1月环境空气质量排名省会城...   本报讯 记者董宇虹报道 日前,生态环境部发布2025年1月全国环境空气质量状况,“昆明蓝”再刷新...
民营经济发展大有可为 转自:贵州日报 张川川 2月17日,习近平总书记出席民营企业座谈会并发表重要讲话,强调“...
成都都市圈油服“金三角”该如何... □川观智库研究员 燕巧 张红霞看全国  ●“十四五”以来,全国油气勘探开发投入大幅增加,年均投资规模...
普阳农场 把好良种试验关 转自:黑龙江日报 本报讯(崔岩 记者姜斌)农以种为先。做好种子发芽试验是确保农业生产用种安全...
乌克兰危机升级三年 多方博弈仍...   乌克兰危机升级已三年。这场冲突剧烈冲击地区安全、经济、社会等诸多领域,同时深刻影响全球,阻碍世界...
王曼昱首夺亚洲杯冠军 转自:黑龙江日报 本报综合报道 2月23日晚,在广东深圳举行的第34届国际乒联-亚乒联盟亚...