如何向 Vuetify Snackbar 添加进度条?
How to add a progress bar to Vuetify Snackbar?
我寻找一种向 Vuetify 的 Snackbar 组件添加进度条的优雅方式。该栏必须与超时道具同步。我使用了 setInterval,但直接在组件上应用样式可能更好?
<template>
<v-snackbar :value="true" :timeout="timeout" light>
<span>Text to display</span>
<v-progress-linear absolute bottom :value="progressValue" />
</v-snackbar>
</template>
<script>
export default {
name: 'SnackBarProgress',
props: {
timeout: {
type: Number,
default: 5000
}
},
data: () => ({
progressValue: 0,
steps: 1,
interval: null
}),
mounted() {
this.startProgress();
},
beforeDestroy() {
clearInterval(this.interval);
},
methods: {
startProgress() {
if (this.timeout < 1) {
return;
}
clearInterval(this.interval);
this.interval = setInterval(() => {
if (this.steps === this.timeout) {
clearInterval(this.interval);
return;
}
this.steps = this.steps + 100;
this.progressValue = Math.round((this.steps / this.timeout) * 100);
}, 100);
}
}
};
</script>
我个人的做法是设置一个 setTimeout
来评估计时器的当前状态,并将其绑定到进度条。
首先,让我们创建一个接受与显示小吃店相关的 v-model 的组件。为此,我们需要一个 value
道具。我们还将为以毫秒为单位的超时创建一个属性,默认值为 5 秒。
props: {
value: {
default: false,
},
timeout: {
default: 5 * 1000,
},
}
接下来,我们将创建一个变量来跟踪我们当前的时间
data() {
return {
currentTime: 0,
};
},
现在我们将创建我们的方法来使进度条每秒递增 10 次。如果当前时间大于超时时间,那么我们需要更新 v-model 来隐藏 snackbar
methods: {
syncPbar() {
//Create a timeout every 100 miliseconds
setTimeout(() => {
//Increment the time counter by 100
this.currentTime += 100;
//If our current time is larger than the timeout
if (this.timeout <= this.currentTime) {
//Wait 500 miliseconds for the dom to catch up, then reset the snackbar
setTimeout(() => {
this.$emit("input", false); //Update the v-model to false
this.currentTime = 0; // reset the current time
}, 500);
} else {
//Recursivly update the progress bar
this.syncPbar();
}
}, 100);
}
}
然后我们需要监控值(来自 v-model),如果为真则开始倒计时。
watch: {
value(v) {
if (v) this.syncPbar();
}
}
最后,我们将创建我们的模板。由于 v-progress-linear
期望值是 0-100,我们需要计算已经过去的时间百分比。最简单的方法是将 currentTime
和 timeout
相除,然后乘以 100。然而,这可能会给我们一个浮点数,因此我们需要使用 [=21 强制它为整数=] 所以我们四舍五入到最接近的百分点。我们还需要创建一个 slot
来承载我们小吃店的文本。
<template>
<v-snackbar :value="value" light>
<span>
<slot></slot>
</span>
<v-progress-linear
absolute
bottom
:value="Math.floor(100 * (currentTime / timeout))"
/>
</v-snackbar>
</template>
现在我们已经创建了我们的组件,我们可以在我们的父级中使用它,我们只需要指定一个超时和一个 v-model。
<mySnack
v-model="showSnack"
:timeout="5 * 1000"
>
Snackbar text
</mySnack>
要查看完整的工作示例,请查看我创建的 codesandbox。
我寻找一种向 Vuetify 的 Snackbar 组件添加进度条的优雅方式。该栏必须与超时道具同步。我使用了 setInterval,但直接在组件上应用样式可能更好?
<template>
<v-snackbar :value="true" :timeout="timeout" light>
<span>Text to display</span>
<v-progress-linear absolute bottom :value="progressValue" />
</v-snackbar>
</template>
<script>
export default {
name: 'SnackBarProgress',
props: {
timeout: {
type: Number,
default: 5000
}
},
data: () => ({
progressValue: 0,
steps: 1,
interval: null
}),
mounted() {
this.startProgress();
},
beforeDestroy() {
clearInterval(this.interval);
},
methods: {
startProgress() {
if (this.timeout < 1) {
return;
}
clearInterval(this.interval);
this.interval = setInterval(() => {
if (this.steps === this.timeout) {
clearInterval(this.interval);
return;
}
this.steps = this.steps + 100;
this.progressValue = Math.round((this.steps / this.timeout) * 100);
}, 100);
}
}
};
</script>
我个人的做法是设置一个 setTimeout
来评估计时器的当前状态,并将其绑定到进度条。
首先,让我们创建一个接受与显示小吃店相关的 v-model 的组件。为此,我们需要一个 value
道具。我们还将为以毫秒为单位的超时创建一个属性,默认值为 5 秒。
props: {
value: {
default: false,
},
timeout: {
default: 5 * 1000,
},
}
接下来,我们将创建一个变量来跟踪我们当前的时间
data() {
return {
currentTime: 0,
};
},
现在我们将创建我们的方法来使进度条每秒递增 10 次。如果当前时间大于超时时间,那么我们需要更新 v-model 来隐藏 snackbar
methods: {
syncPbar() {
//Create a timeout every 100 miliseconds
setTimeout(() => {
//Increment the time counter by 100
this.currentTime += 100;
//If our current time is larger than the timeout
if (this.timeout <= this.currentTime) {
//Wait 500 miliseconds for the dom to catch up, then reset the snackbar
setTimeout(() => {
this.$emit("input", false); //Update the v-model to false
this.currentTime = 0; // reset the current time
}, 500);
} else {
//Recursivly update the progress bar
this.syncPbar();
}
}, 100);
}
}
然后我们需要监控值(来自 v-model),如果为真则开始倒计时。
watch: {
value(v) {
if (v) this.syncPbar();
}
}
最后,我们将创建我们的模板。由于 v-progress-linear
期望值是 0-100,我们需要计算已经过去的时间百分比。最简单的方法是将 currentTime
和 timeout
相除,然后乘以 100。然而,这可能会给我们一个浮点数,因此我们需要使用 [=21 强制它为整数=] 所以我们四舍五入到最接近的百分点。我们还需要创建一个 slot
来承载我们小吃店的文本。
<template>
<v-snackbar :value="value" light>
<span>
<slot></slot>
</span>
<v-progress-linear
absolute
bottom
:value="Math.floor(100 * (currentTime / timeout))"
/>
</v-snackbar>
</template>
现在我们已经创建了我们的组件,我们可以在我们的父级中使用它,我们只需要指定一个超时和一个 v-model。
<mySnack
v-model="showSnack"
:timeout="5 * 1000"
>
Snackbar text
</mySnack>
要查看完整的工作示例,请查看我创建的 codesandbox。