How to Build a High‑Performance Vertical‑Scroll Calendar with NutUI

This article explains the design and implementation of NutUI's vertical‑scroll Calendar component, covering data initialization, virtual‑list rendering, scroll and boundary handling, and extensible slots, props, and events to achieve both smooth interaction and optimal performance.

Aotu Lab
Aotu Lab
Aotu Lab
How to Build a High‑Performance Vertical‑Scroll Calendar with NutUI

Introduction

In most client applications, selecting dates is a common requirement, and calendar components provide an efficient solution. Two typical UI patterns exist: horizontal switching that renders a single month and allows month changes via buttons or swipes, and vertical switching that renders multiple months and scrolls vertically.

Horizontal mode renders fewer nodes and offers better rendering performance, while vertical mode gives a more intuitive visual experience but may involve more nodes.

NutUI Calendar Overview

The NutUI Calendar component implements the vertical‑scroll pattern, offering single‑date and range selection, custom content slots, and extensible props and events.

Design Approach

Initialize raw date data once and render nodes in segments within the visible area.

Apply a virtual‑list technique to reduce rendering cost.

Handle scroll events and boundary conditions.

Enrich the component with slots, props, and events for extensibility.

Core Parameters

Original date data : calculated from the provided date range.

Current selected date : the date shown in the current viewport.

Display range : the subset of dates that need to be rendered.

Container size : used to compute scroll offsets.

Date Data Processing

The algorithm first validates the input range (defaulting to the past year if absent), determines the number of months, and generates date objects for each month. For each month the weekday of the first and last day is computed, and days from the previous or next month are added to fill the week.

const getDaysStatus = (currMonthDays, dateInfo) => {
  let { year, month } = dateInfo;
  return Array.from(Array(currMonthDays), (v, k) => ({
    day: k + 1,
    type: "curr",
    year,
    month,
  }));
  // ...additional logic for previous month days
};

Virtual List

When the data set is large, rendering all nodes at once can freeze the UI. A virtual list renders only the visible viewport and creates or destroys nodes as the user scrolls. In the NutUI Calendar, a scrollWrapper holds the total height, a monthsWrapper contains the rendered months, and the viewport represents the visible area.

During scrolling, the wrapper moves, and when a boundary is reached the months inside monthsWrapper are updated while preserving the overall height to avoid visual jumps.

Scroll and Boundary Handling

Scrolling is captured via the scroll event (compatible with Taro‑to‑WeChat‑Mini‑Program conversion). The average height of a date cell is used to estimate which month is currently in view. The algorithm computes the current month index, adjusts it when crossing month boundaries, and updates the displayed month title.

const mothsViewScroll = (e) => {
  const currentScrollTop = e.target.scrollTop;
  let current = Math.floor(currentScrollTop / state.avgHeight);
  // boundary checks and state updates …
};

Feature Completion

After the basic scrolling calendar is functional, the component is extended with:

Slots for custom date rendering.

Slots for custom header content.

Props for titles, buttons, and range text.

Callback events for date selection, click actions, and closing the calendar.

Conditional slot rendering avoids unnecessary DOM nodes.

Conclusion

The article presents the design rationale and implementation details of the NutUI vertical‑scroll Calendar, demonstrating how virtual lists, segmented rendering, and careful scroll handling can achieve both performance and a smooth user experience.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PerformancenutuiCalendarDate PickerVirtual List
Aotu Lab
Written by

Aotu Lab

Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.