專案中需要做這樣的一個元件
根據不同的數值,這個藍色的條顯示的寬度不同。
這個其實很簡單,我只要根據資料動態的計算它的寬度,生成節點就行了。
其中的部分react程式碼如下
{data && data.length > 0
? data.map((item, index) => (
<div className={styles.item} key={index}>
<div className={styles.itemTop}>
<span>{item.name || item.label}</span>
<span className={styles.num}>{item.value}</span>
</div>
<p className={styles.progressBar}>
<span
className={styles.inner}
style={{ background, width: getWidth(item.value)}
/>
</p>
</div>
))
: null}
這樣就實現如上圖所示的功能顯示,但是現在又有個需求,就是需要那個藍色的條剛載入的時候動起來。
transition
我一開始就想到了css的transition屬性,然後把它加入程式碼中
.inner {
width: 0;
transition: width 0.6s ease;
}
可是這個動畫並沒有生效。
然後我就回過頭來思考它為什麼沒有生效?
transition這個屬性只有在width屬性發生改變的時候才會產生作用。現在只能說明span的width並沒有發生改變。
這時候就要說到我的這段程式碼了,它是一邊計算寬度,一邊渲染節點的,也就是說它節點生成的時候,寬度就已經定好了。所以transition當然不會生效了
現在我要怎麼改進這段程式碼使動畫生效呢?
我只能先讓節點生成好,然後再改變它的寬度了。
這就想到了react中的ref屬性了,這個屬性接受字串或者一個函式,而這個函式在節點載入完成後或者節點銷燬前都會觸發,然後我就可以通過這個函式返回的引數,操作這個節點改變寬度了,這正是我所需要的。
有了思路,開始改進程式碼。
{data && data.length > 0
? data.map((item, index) => (
<div className={styles.item} key={index}>
<div className={styles.itemTop}>
<span>{item.name || item.label}</span>
<span className={styles.num}>{item.value}</span>
</div>
<p className={styles.progressBar}>
<span
className={styles.inner}
style={{ background }}
ref={n => {
if (n && n.style) {
n.style.width = `${getWidth(item.value)}px`;
}
}}
/>
</p>
</div>
))
: null}
然後開啟瀏覽器看結果,果然成功了。
效果如下。