mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-18 12:34:25 +08:00
feat(badge): good animation
This commit is contained in:
parent
5f8581bb63
commit
779c74909d
@ -1,9 +1,9 @@
|
||||
# Basic
|
||||
```html
|
||||
<n-badge hide-zero :value="value" :max="10">
|
||||
<n-badge hide-zero :value="value" :max="15">
|
||||
<n-icon type="ios-alarm" :size="24" />
|
||||
</n-badge>
|
||||
<n-badge dot>
|
||||
<n-badge dot :show="value > 0">
|
||||
<n-icon type="ios-alarm" :size="24" />
|
||||
</n-badge>
|
||||
<n-badge :value="value" type="error">
|
||||
@ -34,6 +34,6 @@ export default {
|
||||
```
|
||||
```css
|
||||
.n-badge {
|
||||
margin: 0 12px 8px 0;
|
||||
margin: 0 24px 8px 0;
|
||||
}
|
||||
```
|
@ -1,27 +1,38 @@
|
||||
<template>
|
||||
<transition
|
||||
name="n-fade-up-width-expand"
|
||||
appear
|
||||
:appear="appeared"
|
||||
@enter="handleEnter"
|
||||
>
|
||||
<span
|
||||
ref="numbers"
|
||||
class="n-scroll-number"
|
||||
:style="{
|
||||
maxWidth: styleMaxWidth
|
||||
maxWidth: styleMaxWidth,
|
||||
width: styleMaxWidth
|
||||
}"
|
||||
>
|
||||
<span
|
||||
v-if="oldNumber !== null"
|
||||
class="n-scroll-number__old-number n-scroll-number__old-number--top"
|
||||
class="n-scroll-number-old-number n-scroll-number-old-number--top"
|
||||
:class="oldNumberScrollAnimationClass"
|
||||
>{{ oldNumber }}</span>
|
||||
<span
|
||||
ref="numberWrapper"
|
||||
class="n-scroll-number__new-number"
|
||||
class="n-scroll-number-current-number"
|
||||
:class="newNumberScrollAnimationClass"
|
||||
>{{ newNumber }}</span>
|
||||
>
|
||||
<span
|
||||
ref="numberWrapper"
|
||||
class="n-scroll-number-current-number__inner"
|
||||
:class="{
|
||||
'n-scroll-number-current-number__inner--slide-in':
|
||||
true
|
||||
}"
|
||||
>{{ newNumber }}</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="oldNumber !== null"
|
||||
class="n-scroll-number__old-number n-scroll-number__old-number--bottom"
|
||||
class="n-scroll-number-old-number n-scroll-number-old-number--bottom"
|
||||
:class="oldNumberScrollAnimationClass"
|
||||
>{{ oldNumber }}</span>
|
||||
</span>
|
||||
@ -32,7 +43,7 @@
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
type: [Number, String],
|
||||
required: true
|
||||
},
|
||||
oldOriginalNumber: {
|
||||
@ -42,6 +53,10 @@ export default {
|
||||
newOriginalNumber: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
appeared: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@ -55,13 +70,13 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
newNumberScrollAnimationClass () {
|
||||
return this.active ? `n-scroll-number__new-number--${this.scrollAnimationDirection}-scroll` : null
|
||||
return this.active ? `n-scroll-number-current-number--${this.scrollAnimationDirection}-scroll` : null
|
||||
},
|
||||
oldNumberScrollAnimationClass () {
|
||||
return this.active ? `n-scroll-number__old-number--${this.scrollAnimationDirection}-scroll` : null
|
||||
return this.active ? `n-scroll-number-old-number--${this.scrollAnimationDirection}-scroll` : null
|
||||
},
|
||||
styleMaxWidth () {
|
||||
return this.maxWidth ? `${this.maxWidth + 1}px` : null
|
||||
return this.maxWidth ? `${this.maxWidth}px` : null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -74,9 +89,6 @@ export default {
|
||||
mounted () {
|
||||
this.maxWidth = this.$refs.numberWrapper.offsetWidth
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.scrollDown()
|
||||
},
|
||||
updated () {
|
||||
this.maxWidth = this.$refs.numberWrapper.offsetWidth
|
||||
},
|
||||
@ -102,7 +114,7 @@ export default {
|
||||
this.active = true
|
||||
})
|
||||
},
|
||||
scrollDown (sync) {
|
||||
scrollDown () {
|
||||
this.scrollAnimationDirection = 'down'
|
||||
this.active = false
|
||||
this.$nextTick().then(() => {
|
||||
|
@ -3,9 +3,15 @@
|
||||
v-if="valueIsNumber"
|
||||
class="n-scroll-numbers"
|
||||
>
|
||||
<scroll-number
|
||||
v-if="max && max < value"
|
||||
:appeared="appeared"
|
||||
:value="'+'"
|
||||
/>
|
||||
<scroll-number
|
||||
v-for="(number, i) in numbers"
|
||||
:key="numbers.length - i - 1"
|
||||
:appeared="appeared"
|
||||
:old-original-number="oldValue"
|
||||
:new-original-number="newValue"
|
||||
:value="number"
|
||||
@ -30,6 +36,14 @@ export default {
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
appeared: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@ -49,6 +63,9 @@ export default {
|
||||
if (this.value < 1) return [0]
|
||||
const numbers = []
|
||||
let value = this.value
|
||||
if (this.max) {
|
||||
value = Math.min(this.max, value)
|
||||
}
|
||||
while (value >= 1) {
|
||||
numbers.push(value % 10)
|
||||
value /= 10
|
||||
|
@ -7,13 +7,19 @@
|
||||
}"
|
||||
>
|
||||
<slot />
|
||||
<transition name="n-badge--transition">
|
||||
<transition
|
||||
name="n-badge--transition"
|
||||
@after-enter="handleAfterEnter"
|
||||
@after-leave="handleAfterLeave"
|
||||
>
|
||||
<sup
|
||||
v-if="(value !== null || dot) && !(hideZero && value === 0)"
|
||||
v-if="showBadge"
|
||||
class="n-badge-sup"
|
||||
>
|
||||
<scroll-numbers
|
||||
v-if="!dot"
|
||||
:appeared="appeared"
|
||||
:max="max"
|
||||
:value="value"
|
||||
/>
|
||||
</sup>
|
||||
@ -48,14 +54,37 @@ export default {
|
||||
},
|
||||
default: null
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
hideZero: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
appeared: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
number () {
|
||||
return (this.max === null || typeof value === 'string') ? this.value : (this.value > this.max ? `${this.max}+` : this.value)
|
||||
},
|
||||
showBadge () {
|
||||
return this.show && (this.value !== null || this.dot) && !(this.hideZero && this.value <= 0)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.showBadge) this.appeared = true
|
||||
},
|
||||
methods: {
|
||||
handleAfterEnter () {
|
||||
this.appeared = true
|
||||
},
|
||||
handleAfterLeave () {
|
||||
this.appeared = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,49 +45,75 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes n-number-slide-in {
|
||||
from {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes n-number-slide-out {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
}
|
||||
to {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
|
||||
@include b(scroll-numbers) {
|
||||
white-space: nowrap;
|
||||
@include b(scroll-number) {
|
||||
@include fade-up-width-expand-transition($duration: 2s);
|
||||
@include fade-up-width-expand-transition($duration: .2s);
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
@include e(old-number) {
|
||||
height: 18px;
|
||||
@include b(scroll-number-old-number) {
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@include m(top) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
@include m(bottom) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
@include m(down-scroll) {
|
||||
animation: n-number-fade-down-out 2s $fast-in-cubic-bezier;
|
||||
animation: n-number-fade-down-out .2s $fast-in-cubic-bezier;
|
||||
animation-iteration-count: 1
|
||||
}
|
||||
@include m(up-scroll) {
|
||||
animation: n-number-fade-up-out 2s $fast-in-cubic-bezier;
|
||||
animation: n-number-fade-up-out .2s $fast-in-cubic-bezier;
|
||||
animation-iteration-count: 1
|
||||
}
|
||||
}
|
||||
@include e(new-number) {
|
||||
@include b(scroll-number-current-number) {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
@include m(down-scroll) {
|
||||
animation: n-number-fade-down-in 2s $fast-in-cubic-bezier;
|
||||
animation: n-number-fade-down-in .2s $fast-in-cubic-bezier;
|
||||
animation-iteration-count: 1
|
||||
}
|
||||
@include m(up-scroll) {
|
||||
animation: n-number-fade-up-in 2s $fast-in-cubic-bezier;
|
||||
animation: n-number-fade-up-in .2s $fast-in-cubic-bezier;
|
||||
animation-iteration-count: 1
|
||||
}
|
||||
@include e(inner) {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,10 +139,10 @@
|
||||
bottom: calc(100% - 4px);
|
||||
}
|
||||
}
|
||||
@include badge-type-mixin('info');
|
||||
@include badge-type-mixin('success');
|
||||
@include badge-type-mixin('warning');
|
||||
@include badge-type-mixin('error');
|
||||
// @include badge-type-mixin('info');
|
||||
// @include badge-type-mixin('success');
|
||||
// @include badge-type-mixin('warning');
|
||||
// @include badge-type-mixin('error');
|
||||
}
|
||||
|
||||
@include b(badge-sup) {
|
||||
@ -128,7 +154,7 @@
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
border-radius: 9px;
|
||||
background-color: rgba(186, 45, 67, 1);
|
||||
background-color: rgb(232, 0, 0);// rgba(186, 45, 67, 1);
|
||||
padding: 0 6px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
|
Loading…
Reference in New Issue
Block a user