开源小程序 您所在的位置:网站首页 todolistjs原生代码 开源小程序

开源小程序

2024-01-26 21:45| 来源: 网络整理| 查看: 265

项目简介

此项目基于小程序云开发,你不需要自己搭建服务器环境。产品原型参考自Microsoft To-Do(微软待办)

项目界面

待办小程序:包含了待办首页、待办列表、待办详情、重要事项、待办列表,包含了待办小程序的所有基础功能。

待办首页:

点击右上角菜单可以呼出重要事项和代办列表入口:

待办详情

重要事项

待办列表

代码分析 前端代码亮点

可以看到以上三个页面:待办首页、重要待办、待办列表都是很多布局都是重复的,所以在这里作者采用了把相同布局封装成自定义组件的方式。

待办首页:

我的一天 {{currentDate}}

重要事项:

待办列表

自定义组件的好处有以下两点,在看看封装的自定义组件。

可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用; 可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。

todolist wxml

{{emptyText}}

wxss

/* components/todolist/todolist.wxss */ .todo-lsit-wrapper{ padding:0 20rpx; margin-top: 20rpx; } .no-data{ color: #fff; text-align: center; font-size: 12px; }

js

// components/todolist/todolist.js Component({ /** * 组件的属性列表 */ properties: { todoList: { type: Array, value: [] }, loading: { type: Boolean, value: true }, emptyText: { type: String, value: '数据是空的~' } }, /** * 组件的初始数据 */ data: { }, /** * 组件的方法列表 */ methods: { checkboxChange(event) { console.log('ev', event) }, clickTodoItemHandle(event) { console.log(event) }, clickTodoItemRight(event) { console.log(event) } } })

json

{ "component": true, "usingComponents": { "todo-item": "../todo-item/TodoItem" } }

在list里面包含了item组件,接下来我们来看到item的具体代码。 wxml

{{todo.description}} 我的一天 {{todo.due_date_format}}

wxss

/* components/todo-item/TodoItem.wxss */ .van-ellipsis { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .van-multi-ellipsis--l2 { -webkit-line-clamp: 2; } .van-multi-ellipsis--l2, .van-multi-ellipsis--l3 { display: -webkit-box; overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; } .van-multi-ellipsis--l3 { -webkit-line-clamp: 3; } .todo-item-content { background-color: #fff; border-radius: 15rpx; display: flex; align-items: center; justify-content: space-between; padding: 0 20rpx; height: 100rpx; /* border-bottom: 1px solid #dedede; */ margin-bottom: 4px; } .todo-body { width: 580rpx; padding-left: 20rpx; font-size: 14px; min-height: 30rpx; } .todo-body .todo-des { font-size: 12px; display: flex; } .todo-des { color: #a0a0a0; }

js

// components/todo-item/TodoItem.js Component({ /** * 组件的属性列表 */ properties: { todo: { type: Object, value: {} } }, /** * 组件的初始数据 */ data: { checked: false }, /** * 组件的方法列表 */ methods: { onChange(event) { let done = event.detail let todoId = this.data.todo._id const db = wx.cloud.database() db.collection('todos').doc(todoId).update({ data: { done: done, complete_date: done ? new Date() : null }, success: function(res) { console.log(res) } }) this.setData({ todo: { ...this.data.todo, done, complete_date: done ? new Date() : null } }); this.triggerEvent('checkboxchange', event.detail) }, onClickTodoItem() { this.triggerEvent('clicktodoitem') wx.navigateTo({ url: '/pages/todo-detail/todo-detail?'+this.data.todo._id, }) }, onClickTodoItemRight() { let todoId = this.data.todo._id const db = wx.cloud.database() let isImportant = !this.data.todo.isImportant db.collection('todos').doc(todoId).update({ data: { isImportant } }) this.setData({ todo: { ...this.data.todo, isImportant } }); this.triggerEvent('clicktodoright') }, remove(){ wx.showToast({ title: 'hi', }) } } })

在这里作者把数据库操作和跳转操作都疯转到了组件中去,这样的好处就是比较省事加上业务高度一致所以可以这样做,不过如果想更加灵活可以把这些与业务耦合的内容放在相关的业务页面去编写会更好,然后再去封装业务代码。

然后再看下todo-input wxml

wxss

/* components/todo-input/TodoInput.wxss */ .todo-input-wrapper { display: flex; align-items: center; height: 90rpx; width: 100%; justify-content: space-between; background-color: rgba(100, 96, 96,.6); color: #fff; border-radius: 10rpx; font-size: 16px; } .add-icon, .enter-icon { width: 80rpx; display: flex; height: 90rpx; align-items: center; justify-content: center; } .input-component-wrapper { width: 540rpx; padding-left: 20rpx; } .input-component { width: 100%; color: #fff; height: 90rpx; }

js

// components/todo-input/TodoInput.js import { addTodoItem } from '../../utils/todoDbHelper.js' import Notify from '../../miniprogram_npm/@vant/weapp/notify/notify'; Component({ /** * 组件的属性列表 */ properties: { pageType: { type: Number, value: 0 } // 0我的一天 ,1重要 ,2代办列表 }, /** * 组件的初始数据 */ data: { todoValue: '' }, /** * 组件的方法列表 */ methods: { todoInputHandle(e) { this.data.todoValue = e.detail.value }, todoInputConfirmHandle(e) { let that = this let todoValue = this.data.todoValue let pageType = this.data.pageType console.log('pageType', pageType) if (!todoValue) { Notify({ type: 'warning', message: '请输入代办事项!' }) return } let addParams = { description: todoValue, } if (pageType === 0) { addParams.isMyday = true addParams.addMydayDate = new Date() } if (pageType === 1) { addParams.isImportant = true } console.log('addParams', addParams) addTodoItem(addParams).then(res => { // res 是一个对象,其中有 _id 字段标记刚创建的记录的 id console.log('插入成功', res) that.triggerEvent('success', res) that.setData({ todoValue: '' }) }) } } })

在这里作者用到了一个操作工具类 todoDbHelper

const db = wx.cloud.database() const dbCollection = db.collection('todos') /** * 通过id查询单个todo详情 */ export const queryTodoDetailById = (id) => { return dbCollection.where({ _id: id }).get() } /** * 添加todoItem 三个地方,我的一天,重要,代办列表 */ export const addTodoItem = (params) => { const defaultParams = { // description: description, // 描述,标题 create_date: new Date(), // 创建时间 isMyday: false, addMydayDate: null, // 添加到我的一天的时间 due_date: null, // 结束时间 complete_date: null, // 完成时间 done: false, // 是否完成 isImportant: false, // 是否重要 remark: '', // 备注 type: 0, remind: false, // 是否提醒 remind_date: null // 提醒时间 } return dbCollection.add({ data: { ...defaultParams, ...params } }) } /** * 更新todoItem */ export const updateTodoItem = (id, params) => { return dbCollection.doc(id).update({ data: { ...params } }) } /** * 删除todoItem */ export const removeTodoItem = (id) => { return dbCollection.doc(id).remove() }

这种封装的方式可以学习,所有数据库操作封装到一个工具类中去执行。但是在这里要说一下,我觉得可以封装的更彻底一点就是所有数据库才做都可以写在这里面,比如:item组件中的update操作。

云开发代码

整体来说,云开发代码比较简单是基础的增删查改,因为业务相对简单,除了上面提到过的在小程序调用的add、update、remove、get之外还有两个云函数。

查询数量:待办数量、重要待办数量

// 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ // API 调用都保持和云函数当前所在环境一致 env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() // 云函数入口函数 exports.main = async(event, context) => { const wxContext = cloud.getWXContext() // 先取出集合记录总数 const countResult = await db.collection('todos').where({ _openid: wxContext.OPENID }).count() const isImportantResult = await db.collection('todos').where({ isImportant: true, _openid: wxContext.OPENID }).count() const isImportantCount = isImportantResult.total const count = countResult.total return { count, isImportantCount } }

分页查询todo列表和按日期条件查询

// 云函数入口文件 const cloud = require('wx-server-sdk') const moment = require('moment') cloud.init({ // API 调用都保持和云函数当前所在环境一致 env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() const _ = db.command const MAX_LIMIT = 100 // 云函数入口函数 exports.main = async(event, context) => { const wxContext = cloud.getWXContext() // 先取出集合记录总数 const countResult = await db.collection('todos').count() const isImportantResult = await db.collection('todos').where({ isImportant: true }).count() const isImportantCount = isImportantResult.total const count = countResult.total const queryCount = event.count ? event.count : 10 // 查询参数 const dbParams = event.dbParams ? event.dbParams : {} // openid dbParams._openid = wxContext.OPENID // 我的一天条件/当天 if (dbParams.isMyday) { let curDate = moment().format('YYYY-MM-DD'); let nextDate = moment().add(1, 'days').format('YYYY-MM-DD') dbParams.addMydayDate = _.gte(new Date(curDate)).and(_.lte(new Date(nextDate))) } // 计算需分几次取 const batchTimes = Math.ceil(queryCount / 100) // // 承载所有读操作的 promise 的数组 const tasks = [] for (let i = 0; i < batchTimes; i++) { const promise = db.collection('todos').where(dbParams).skip(i * MAX_LIMIT).limit(MAX_LIMIT).get() tasks.push(promise) } // 等待所有 let data = (await Promise.all(tasks)).reduce((acc, cur) => { return { data: acc.data.concat(cur.data), errMsg: acc.errMsg, } }) return { data: data.data, count, isImportantCount, event } } 总结

整体来说这个小程序很适合新手学习,逻辑相对简单,功能实用性较强。里面有一些代码封装的思维值得学习如:自定义组件、工具类封装这些,如果能封装的更加彻底就更好了。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有