Design and Implementation of the NutUI Collapse Panel Component
This article explains the design principles, implementation details, and advanced features of NutUI’s Collapse panel component, covering basic interaction, height‑based animation, flexible title bar with icons, configuration upgrades, slot usage, CSS variable styling, and Vue 3 provide/inject communication, supplemented with code examples.
NutUI is a JD‑style mobile UI component library built with Vue, offering over 70 components, TypeScript support, on‑demand import, and theme customization, and it works on H5 and mini‑program platforms.
The Collapse panel is a common UI element that can expand or collapse content, useful for navigation, detail sections, and filter categories. Its design follows the typical pattern of a header that toggles the visibility of a content area.
Initially the expand/collapse behavior can be achieved with a simple Boolean variable controlling v-show . For better extensibility and animation, the component adjusts the content container’s height and uses CSS transform together with the will-change property to optimize rendering.
The height‑based animation calculates the content’s offsetHeight and sets the wrapper’s height accordingly, while applying will-change: height to let the browser prepare for the change.
const wrapperRefEle = wrapperRef.value;
const contentRefEle = contentRef.value;
if (!wrapperRefEle || !contentRefEle) { return; }
const offsetHeight = contentRefEle.offsetHeight || 'auto';
if (offsetHeight) {
const contentHeight = `${offsetHeight}px`;
wrapperRefEle.style.willChange = 'height';
wrapperRefEle.style.height = !proxyData.openExpanded ? 0 : contentHeight;
}The title bar can display an icon that rotates 180° when the panel is expanded. This is achieved with a CSS rotate transformation based on the component’s state.
if (parent.props.icon && !proxyData.openExpanded) {
proxyData.iconStyle['transform'] = 'rotate(0deg)';
} else {
proxyData.iconStyle['transform'] = 'rotate(' + parent.props.rotate + 'deg)';
}Additional configuration options include a subtitle ( sub‑title ), an extraRender slot for custom content, and a disabled state that applies a distinct style.
.nut-collapse-item-disabled {
color: #c8c9cc;
cursor: not-allowed;
pointer-events: none;
}Vue 3 also allows using CSS variables directly in scoped styles, enabling dynamic theming such as changing a component’s color at runtime.
Component communication between nut‑collapse and nut‑collapse‑item is handled via Vue’s provide / inject API. The provide function adds a key/value pair to the component’s provides object, while inject retrieves it, traversing the prototype chain if necessary.
// a.vue
import { defineComponent, provide } from 'vue';
export default defineComponent({
setup() {
const msg = 'Hello NutUI';
provide('msg', msg);
}
});
// b.vue
import { defineComponent, inject } from 'vue';
export default defineComponent({
setup() {
const msg = inject('msg') || '';
}
});The article concludes that the NutUI Collapse component combines simple state toggling, height‑based animation, flexible icon handling, slot‑based extensibility, and Vue 3’s provide/inject communication to create a reusable, customizable UI element.
JD Retail Technology
Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.