开发微信记账本小程序之技术要点记录

发布于:2025-02-10 ⋅ 阅读:(34) ⋅ 点赞:(0)

我喜欢极简风格,所以我搭建了这款微信记账本小程序。在开发微信记账本小程序过程中,有一些值得关注的技术要点,我则简而记之。

1、空态界面

在没有数据时,我设计了空状态时的占位提示。

在框架中,我使用了 wx:if="{{ isShow }}" 来判断是否需要渲染该代码块。而isShow的赋值逻辑是通过判断数组的长度,如果为0则为false,否则为true。

图片

2、新增记账

这里我基于表单元素封装了一个业务表单组件,通过遮罩层弹出。使用到的表单项有form、input、radio、textarea、picker、button,通过自定义样式实现定制化界面。

其实,我有考虑过使用Skyline进行渲染的。但是由于还不太掌握,所以还是使用自定义组件的方式,实现弹层效果。

况且,这个模块后面还会在其他地方用到,所以为了提高可复用性才做了封装。

图片

那么,在微信小程序中,如何封装自定义组件和引用呢?

1) 创建自定义组件:

首先,在项目根目录下创建一个文件夹 `components`,用于存放自定义组件。

在 `components` 文件夹下创建一个子文件夹`my-component`,用于存放自定义组件的相关文件。

在 `my-component` 文件夹下创建以下四个文件:

  •     `my-component.wxml`:组件的模板结构。

  •      `my-component.wxss`:组件的样式表。

  •      `my-component.js`:组件的逻辑代码。

  •       `my-component.json`:组件的配置信息。

编写组件的代码,然后在需要使用该组件的页面中进行引用。

2)引用自定义组件:

在需要使用自定义组件的页面的 `json` 文件中,添加 `usingComponents` 字段,用于声明要使用的自定义组件。

     // json     {       "usingComponents": {         "my-component": "/components/my-component/my-component"       }     }     

在页面的 `wxml` 文件中,使用自定义组件的标签来引用它。

     // wxml     <my-component></my-component>

注意,自定义组件的名称必须遵循一定的命名规范,即以字母开头,可以包含数字、下划线、横杠等字符。

这样,就大致上在微信小程序中使用自定义组件了。接下来,就是写页面结构布局与样式,还有业务逻辑代码了。

这里的拖拽效果,我是基于框架提供的draggable-sheet 组件实现的,封装了这一能力,包括:

  • 隐藏滚动条

  • 滚动回弹效果

  • 滚动到指定位置(snap 到关键点)

  • 滚动帧回调(实现滚动驱动动画)

<draggable-sheet  class="sheet"  initial-child-size="0.5"  min-child-size="0.2"  max-child-size="0.8"  snap="{{true}}"  snap-sizes="{{[0.4, 0.6]}}"  worklet:onsizeupdate="onSizeUpdate">  <scroll-view    scroll-y="{{true}}"    type="list"    associative-container="draggable-sheet"    bounces="{{true}}"  /></draggable-sheet>

3、选择类型和分类管理

这里的长按拖动分类排序,我认为也是一个技术难点。

实现长按拖拽某个选项进行排序,我采用了以下技术方案来实现。

首先,在页面的 `wxml` 文件中,为每个选项添加一个 `touchstart` 和 `touchmove` 事件监听器。

// wxml<view class="item" bindtouchstart="startDrag" bindtouchmove="drag" data-index="{{index}}">  {{item}}</view>

在对应的 `js` 文件中,定义 `startDrag` 和 `drag` 方法。`startDrag` 方法用于记录触摸开始时的位置和索引,`drag` 方法用于处理拖拽过程中的逻辑。

// javascriptPage({  data: {    items: ['餐饮', '交通', '服饰']  },  startDrag: function (e) {    // 记录触摸开始时的位置和索引    this.setData({      startX: e.touches[0].clientX,      startY: e.touches[0].clientY,      startIndex: e.currentTarget.dataset.index    });  },  drag: function (e) {    // 获取触摸移动时的位置    const moveX = e.touches[0].clientX;    const moveY = e.touches[0].clientY;    const startX = this.data.startX;    const startY = this.data.startY;    const startIndex = this.data.startIndex;

    // 计算拖拽的距离    const distanceX = moveX - startX;    const distanceY = moveY - startY;

    // 如果拖拽距离大于一定阈值,则认为是拖拽操作    if (Math.abs(distanceX) > 10 || Math.abs(distanceY) > 10) {      // 获取当前拖拽的元素      const currentItem = this.data.items[startIndex];      // 从数组中移除当前元素      const newItems = this.data.items.filter((item, index) => index !== startIndex);      // 计算新的插入位置      const newIndex = startIndex + Math.round(distanceX / 100);      // 将当前元素插入到新的位置      newItems.splice(newIndex, 0, currentItem);      // 更新数据      this.setData({        items: newItems      });    }  }});

这样,当用户长按并拖动某个选项时,选项会根据拖动的距离进行重新排序。

图片

4、智能分类和报表分析

为了实现日、月的收支报表,以及分类统计图表,我采用了echarts可视化图表库。这也是一项大工程,后面再单独展开写一下。

图片

5、账目管理

看,这里修改数据的模块,就是引用了前面封装的组件。这开发效率,杠杠滴。

而删除前询问用户以避免误删数据,我是使用了框架的wx.showModal方法显示模态对话框。

图片

当然,还有更多开发过程中的技术要点和开发技巧。但是如果都要一一细写,恐怕就要等后面出教程了。