Skip to content

Commit

Permalink
fix(Progress): fix render error when use v-show and improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
ascodelife authored and chenjiahan committed Aug 25, 2021
1 parent ce015ea commit 841e09d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 66 deletions.
57 changes: 18 additions & 39 deletions src/progress/Progress.tsx
@@ -1,15 +1,5 @@
import {
ref,
watch,
computed,
nextTick,
reactive,
onMounted,
defineComponent,
ExtractPropTypes,
} from 'vue';
import { computed, defineComponent, ExtractPropTypes } from 'vue';
import { truthProp, createNamespace, addUnit } from '../utils';
import { useExpose } from '../composables/use-expose';

const [name, bem] = createNamespace('progress');

Expand All @@ -36,67 +26,56 @@ export default defineComponent({
props,

setup(props) {
const root = ref<HTMLElement>();
const pivotRef = ref<HTMLElement>();

const state = reactive({
rootWidth: 0,
pivotWidth: 0,
});

const background = computed(() =>
props.inactive ? '#cacaca' : props.color
);

const resize = () => {
nextTick(() => {
state.rootWidth = root.value ? root.value.offsetWidth : 0;
state.pivotWidth = pivotRef.value ? pivotRef.value.offsetWidth : 0;
});
};
const scaleX = computed(() => +props.percentage! / 100);
const translateX = computed(() => {
let offset = 0;
if (+props.percentage! !== 0) {
offset = (100 - +props.percentage!) / 2 / (+props.percentage! / 100);
}
return `${offset}%`;
});

const renderPivot = () => {
const { rootWidth, pivotWidth } = state;
const { textColor, pivotText, pivotColor, percentage } = props;
const text = pivotText ?? `${percentage}%`;
const show = props.showPivot && text;

if (show) {
const left = ((rootWidth - pivotWidth) * +percentage!) / 100;
const style = {
color: textColor,
left: `${left}px`,
left: `${+percentage!}%`,
transform: `translate(-${+percentage!}%,-50%)`,
background: pivotColor || background.value,
};

return (
<span ref={pivotRef} style={style} class={bem('pivot')}>
<span style={style} class={bem('pivot')}>
{text}
</span>
);
}
};

watch(() => [props.showPivot, props.pivotText], resize);
onMounted(resize);
useExpose({ resize });

return () => {
const { trackColor, percentage, strokeWidth } = props;
const { trackColor, strokeWidth } = props;
const rootStyle = {
background: trackColor,
height: addUnit(strokeWidth),
};
const portionStyle = {
background: background.value,
width: (state.rootWidth * +percentage!) / 100 + 'px',
width: '100%',
transform: `scaleX(${scaleX.value}) translateX(-${translateX.value})`,
};

return (
<div ref={root} class={bem()} style={rootStyle}>
<span class={bem('portion')} style={portionStyle}>
{renderPivot()}
</span>
<div class={bem()} style={rootStyle}>
<span class={bem('portion')} style={portionStyle}></span>
{renderPivot()}
</div>
);
};
Expand Down
27 changes: 0 additions & 27 deletions src/progress/README.zh-CN.md
Expand Up @@ -108,30 +108,3 @@ progressRef.value?.resize();
| --van-progress-pivot-font-size | _var(--van-font-size-xs)_ | - |
| --van-progress-pivot-line-height | _1.6_ | - |
| --van-progress-pivot-background-color | _var(--van-primary-color)_ | - |

## 常见问题

### 组件从隐藏状态切换到显示状态时,渲染不正确?

Progress 组件在挂载时,会获取自身的宽度,并计算出进度条的样式。如果组件一开始处于隐藏状态,则获取到的宽度永远为 0,因此无法展示正确的进度。

#### 解决方法

方法一,如果是使用 `v-show` 来控制组件展示的,则替换为 `v-if` 即可解决此问题:

```html
<!-- Before -->
<van-progress v-show="show" />
<!-- After -->
<van-progress v-if="show" />
```

方法二,调用组件的 resize 方法来主动触发重绘:

```html
<van-progress v-show="show" ref="progress" />
```

```js
this.$refs.progress.resize();
```

0 comments on commit 841e09d

Please sign in to comment.