Skip to content

ReadMore Expand-to-Read-More Component

This component is generally used in scenarios where the content is long: part of it is initially collapsed, and clicking expands the full content.

📌 Platform Compatibility

APP(vue)H5WeChat Mini ProgramAlipay Mini Program

🏯 Basic Usage Example

html
<!-- Global usage -->
<hy-read-more>
    <rich-text :nodes="content"></rich-text>
</hy-read-more>
ts
import { ref } from 'vue';

const content = ref(`A mountain need not be high; with an immortal dwelling, it gains renown. Water need not be deep; with a dragon, it gains spirit. This is a humble room, but my virtue makes it fragrant.
Moss stains the steps green; grass colors seep blue through the curtain. Learned scholars chat and laugh here; among visitors there are no simpletons. One may softly play the unadorned zither and read gilded scriptures.
No pipes and strings clamor in the ears, no official documents weary the body. Like Zhuge Liang's hut in Nanyang, like Yang Ziyun's pavilion in western Shu. As Confucius said: "What humbleness is there?"`);

Configuring the Expansion Height

  • By configuring the showHeight height (in px), the button labeled "Expand to read full text" will only appear if the height of the content passed in via the slot exceeds this value
html
<hy-read-more showHeight="600">
    <rich-text :nodes="content"></rich-text>
</hy-read-more>

Custom Styles

Note

The upper part of this component has a white fading shadow, used to blend the click area with the text content. If you don't want this shadow, you can adjust the shadowStyle object, whose internals are as follows:

javascript
{
    // #ifndef APP-NVUE
    backgroundImage: "linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)",
    // #endif
    // #ifdef APP-NVUE
    // Complex backgroundImage properties are not supported on nvue
    backgroundImage: "linear-gradient(to top, #fff, rgba(255, 255, 255, 0.5))",
    // #endif
    paddingTop: "100px",
    marginTop: "-100px",
}
  • If you don't want the shadow, simply set backgroundImage to none; adjust paddingTop and marginTop to suitable values as needed.
html
<template>
    <hy-read-more :shadowStyle="shadowStyle">
        <rich-text :nodes="content"></rich-text>
    </hy-read-more>
</template>

<script setup>
    import { reactive } from 'vue';

    const shadowStyle = reactive({
        backgroundImage: 'none',
        paddingTop: '0',
        marginTop: '20rpx',
    });
</script>

Asynchronous Initialization

Note

Sometimes the content to be displayed is fetched from the backend. When the component's internal mounted lifecycle initializes, the request has not yet returned, which can cause the content height to be inaccurate during initialization. After the request completes and rendering finishes (i.e., this.$nextTick), you can call the component's init method via ref to re-initialize it.

html
<template>
    <hy-read-more showHeight="600" ref="uReadMoreRef">
        <rich-text :nodes="content"></rich-text>
    </hy-read-more>
</template>

<script setup>
    import { ref, onMounted, nextTick } from 'vue';

    // Create reactive data
    const content = ref('');

    // Create a component reference
    const uReadMoreRef = ref(null);

    // Simulate a backend request
    async function fetchData() {
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve(`A mountain need not be high; with an immortal dwelling, it gains renown. Water need not be deep; with a dragon, it gains spirit. This is a humble room, but my virtue makes it fragrant.
      Moss stains the steps green; grass colors seep blue through the curtain. Learned scholars chat and laugh here; among visitors there are no simpletons. One may softly play the unadorned zither and read gilded scriptures.
      No pipes and strings clamor in the ears, no official documents weary the body. Like Zhuge Liang's hut in Nanyang, like Yang Ziyun's pavilion in western Shu. As Confucius said: "What humbleness is there?"`);
            }, 2000);
        });
    }

    // Called after the component is mounted
    onMounted(async () => {
        await fetchData();
        content.value = text;

        // Wait for the DOM to update
        await nextTick();

        // Call the child component's init method
        if (uReadMoreRef.value) {
            uReadMoreRef.value.init();
        }
    });
</script>

API

readMore Props

ParameterDescriptionTypeDefault
showHeightThe "expand full text" button is only displayed when the content exceeds this height; default unit is pxstring|number400
toggleWhether to show a collapse button after expandingbooleanfalse
closeTextPrompt text when collapsedstringExpand to read full text
openTextPrompt text when expandedstringCollapse
colorColor of the prompt textstring-
fontSizeSize of the prompt text; default unit is pxstring|number14
textIndentNumber of characters for the first-line indent of paragraphsstring2em
nameUsed as the callback parameter returned in the open and close eventsstring-
shadowStyleCustom handling of the shadow, in object formCSSProperties-
customStyleExternal styles to be appliedCSSProperties-

Events

Event NameDescriptionCallback Parameters
openTriggered when the content is expandedname - the value of the name parameter passed in props
closeTriggered when the content is collapsedname - the value of the name parameter passed in props

Slots

Slot NameDescriptionAccepted Values
defaultDefault slot-

Methods

NameDescription
initRe-initializes the component's internal height calculation process
03:29