mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
fix(TextEllipsis): should recalculate the ellipsis state when activated (#12741)
This commit is contained in:
parent
661f35d238
commit
d87c5e2b18
@ -2,6 +2,7 @@ import {
|
||||
ref,
|
||||
watch,
|
||||
computed,
|
||||
onActivated,
|
||||
onMounted,
|
||||
defineComponent,
|
||||
type ExtractPropTypes,
|
||||
@ -42,6 +43,7 @@ export default defineComponent({
|
||||
const expanded = ref(false);
|
||||
const hasAction = ref(false);
|
||||
const root = ref<HTMLElement>();
|
||||
let needRecalculate = false;
|
||||
|
||||
const actionText = computed(() =>
|
||||
expanded.value ? props.collapseText : props.expandText,
|
||||
@ -53,29 +55,31 @@ export default defineComponent({
|
||||
return match ? Number(match[0]) : 0;
|
||||
};
|
||||
|
||||
const cloneContainer = () => {
|
||||
if (!root.value || !root.value.isConnected) return;
|
||||
|
||||
const originStyle = window.getComputedStyle(root.value);
|
||||
const container = document.createElement('div');
|
||||
const styleNames: string[] = Array.prototype.slice.apply(originStyle);
|
||||
|
||||
styleNames.forEach((name) => {
|
||||
container.style.setProperty(name, originStyle.getPropertyValue(name));
|
||||
});
|
||||
|
||||
container.style.position = 'fixed';
|
||||
container.style.zIndex = '-9999';
|
||||
container.style.top = '-9999px';
|
||||
container.style.height = 'auto';
|
||||
container.style.minHeight = 'auto';
|
||||
container.style.maxHeight = 'auto';
|
||||
|
||||
container.innerText = props.content;
|
||||
document.body.appendChild(container);
|
||||
|
||||
return container;
|
||||
};
|
||||
|
||||
const calcEllipsised = () => {
|
||||
const cloneContainer = () => {
|
||||
if (!root.value) return;
|
||||
|
||||
const originStyle = window.getComputedStyle(root.value);
|
||||
const container = document.createElement('div');
|
||||
const styleNames: string[] = Array.prototype.slice.apply(originStyle);
|
||||
styleNames.forEach((name) => {
|
||||
container.style.setProperty(name, originStyle.getPropertyValue(name));
|
||||
});
|
||||
|
||||
container.style.position = 'fixed';
|
||||
container.style.zIndex = '-9999';
|
||||
container.style.top = '-9999px';
|
||||
container.style.height = 'auto';
|
||||
container.style.minHeight = 'auto';
|
||||
container.style.maxHeight = 'auto';
|
||||
|
||||
container.innerText = props.content;
|
||||
document.body.appendChild(container);
|
||||
return container;
|
||||
};
|
||||
|
||||
const calcEllipsisText = (
|
||||
container: HTMLDivElement,
|
||||
maxHeight: number,
|
||||
@ -168,7 +172,12 @@ export default defineComponent({
|
||||
|
||||
// Calculate the interceptional text
|
||||
const container = cloneContainer();
|
||||
if (!container) return;
|
||||
|
||||
if (!container) {
|
||||
needRecalculate = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const { paddingBottom, paddingTop, lineHeight } = container.style;
|
||||
const maxHeight = Math.ceil(
|
||||
(Number(props.rows) + 0.5) * pxToNum(lineHeight) +
|
||||
@ -209,6 +218,13 @@ export default defineComponent({
|
||||
|
||||
onMounted(calcEllipsised);
|
||||
|
||||
onActivated(() => {
|
||||
if (needRecalculate) {
|
||||
needRecalculate = false;
|
||||
calcEllipsised();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
[windowWidth, () => [props.content, props.rows, props.position]],
|
||||
calcEllipsised,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { mount } from '../../../test';
|
||||
import { nextTick } from 'vue';
|
||||
import { defineComponent, KeepAlive, nextTick } from 'vue';
|
||||
import TextEllipsis, { type TextEllipsisInstance } from '..';
|
||||
|
||||
const originGetComputedStyle = window.getComputedStyle;
|
||||
@ -34,6 +34,7 @@ afterAll(() => {
|
||||
|
||||
test('should render action slot correctly', async () => {
|
||||
const wrapper = mount(TextEllipsis, {
|
||||
attachTo: document.body,
|
||||
props: {
|
||||
content,
|
||||
},
|
||||
@ -57,6 +58,7 @@ test('should render action slot correctly', async () => {
|
||||
|
||||
test('should render content correctly', async () => {
|
||||
const wrapper = mount(TextEllipsis, {
|
||||
attachTo: document.body,
|
||||
props: {
|
||||
content,
|
||||
},
|
||||
@ -68,6 +70,7 @@ test('should render content correctly', async () => {
|
||||
|
||||
test('Expand and Collapse should be work', async () => {
|
||||
const wrapper = mount(TextEllipsis, {
|
||||
attachTo: document.body,
|
||||
props: {
|
||||
content,
|
||||
expandText: 'expand',
|
||||
@ -83,6 +86,7 @@ test('Expand and Collapse should be work', async () => {
|
||||
|
||||
test('should emit click event after Expand/Collapse is clicked', async () => {
|
||||
const wrapper = mount(TextEllipsis, {
|
||||
attachTo: document.body,
|
||||
props: {
|
||||
content,
|
||||
expandText: 'expand',
|
||||
@ -102,6 +106,7 @@ test('text not exceeded', async () => {
|
||||
|
||||
const shortContent = 'Vant is a component library';
|
||||
const wrapper = mount(TextEllipsis, {
|
||||
attachTo: document.body,
|
||||
props: {
|
||||
content: shortContent,
|
||||
expandText: 'expand',
|
||||
@ -112,3 +117,45 @@ test('text not exceeded', async () => {
|
||||
await nextTick();
|
||||
expect(wrapper.text()).not.toMatch('...');
|
||||
});
|
||||
|
||||
// https://github.com/vant-ui/vant/issues/12445
|
||||
test('should recalculate the ellipsis state when the component is activated', async () => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
const Comp = defineComponent({
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
};
|
||||
},
|
||||
beforeMount() {
|
||||
setTimeout(() => {
|
||||
this.show = true;
|
||||
}, 1000);
|
||||
},
|
||||
render() {
|
||||
return this.show ? <TextEllipsis content={content} /> : null;
|
||||
},
|
||||
});
|
||||
|
||||
const wrapper = mount(
|
||||
{
|
||||
data() {
|
||||
return {
|
||||
render: true,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return <KeepAlive>{this.render ? <Comp /> : null}</KeepAlive>;
|
||||
},
|
||||
},
|
||||
{ attachTo: document.body },
|
||||
);
|
||||
|
||||
wrapper.setData({ render: false });
|
||||
await vi.advanceTimersByTimeAsync(1000);
|
||||
await wrapper.setData({ render: true });
|
||||
expect(wrapper.text()).toMatch(content);
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user