Javascript VUE 3-使用setInterval从阵列中删除项
我想用VUE3创建一个简单的Snackbar。我已经在VUE2中完成了这项工作,但Vue3的工作方式似乎略有不同 我已将邮件数组保存在商店中,如下所示:Javascript VUE 3-使用setInterval从阵列中删除项,javascript,vue.js,vuejs3,Javascript,Vue.js,Vuejs3,我想用VUE3创建一个简单的Snackbar。我已经在VUE2中完成了这项工作,但Vue3的工作方式似乎略有不同 我已将邮件数组保存在商店中,如下所示: import { createStore } from 'vuex' export default createStore({ state: { snackbarText: [] }, mutations: { DELETE_SNACKBAR_MESSAGE(state) { state.snackba
import { createStore } from 'vuex'
export default createStore({
state: {
snackbarText: []
},
mutations: {
DELETE_SNACKBAR_MESSAGE(state) {
state.snackbarBarText.shift()
},
ADD_SNACKBAR_MESSAGE(state, message) {
state.snackbarBarText.push(message)
}
},
getters: {
MESSAGES: (state) => state.snackbarText
}
})
这就是我到目前为止在Snackbar.vue组件中所做的:
import { useStore } from 'vuex';
import { ref, watch} from 'vue';
export default {
set() {
const store = useStore();
const text = ref(store.getters["MESSAGES"]);
if (text.value.length) {
let timer = setInterval(() => {
store.commit('DELETE_SNACKBAR_MESSAGE');
if (text.value.length) {
clearInterval(timer)
}
}, 3000)
}
return { text }
}
}
有没有办法检查Snackbar中文本的长度
ref并调用启动计时器的函数?我只是在Vue3中实现这一点有困难,因为我还不太熟悉合成API
它的工作方式是,将消息添加到数组中并显示给用户。3秒后,它们将从阵列中移除。使用watch
很笨重,在setInterval停止后,我很难重新启动它
谢谢大家! !重写我使用
setInterval
的原始答案。
setInterval不适用于此特定类型的功能。不能以“干净”的方式从一个元素转换到下一个元素
在Vue2中,您可能会使用EventBus
来侦听snackbar消息数组的任何更改。但是在Vue3中,他们删除了该功能。您可以继续使用类似EventBus的模块或使用
这是整个组件:
<template>
<transition name="component-fade" @after-leave="checkForMoreSnacks">
<div class="snackbar" v-if="currentSnack">
<div class="snackbar__container">
<p>{{ currentSnack }}</p>
<button @click="closeCurrentSnack">Close Me</button>
</div>
</div>
</transition>
</template>
<script>
import { useStore } from "vuex";
import { computed, ref } from "vue";
export default {
setup() {
const timerInterval = 1500;
const store = useStore();
let timeoutToken = null;
let snacks = computed(() => store.getters["GET_SNACKBAR_MESSAGES"]);
let currentSnack = ref(null);
// The event that triggers the Snackbar to initially appear.
// Much like an EventBus emit
store.subscribe(mutation => {
// listen for this specific mutation call
if (mutation.type === "ADD_SNACKBAR_MESSAGE") {
// if there is already a currentSnack don't proceed
if (currentSnack.value) return;
// if no token, set the value to this settimeout function where we do:
// 1. Set the current value to the [0] index of the snacks array.
// 2. Remove that item from the snacks array in the store
currentSnack.value = snacks.value[0];
timeoutToken = setTimeout(() => {
closeCurrentSnack();
}, timerInterval);
}
});
function closeCurrentSnack() {
store.commit("DELETE_SNACKBAR_MESSAGE");
currentSnack.value = null;
timeoutToken = null;
}
function checkForMoreSnacks() {
if (!snacks.value.length) {
timeoutToken = null;
currentSnack.value = null;
} else {
currentSnack.value = snacks.value[0];
timeoutToken = setTimeout(() => {
closeCurrentSnack();
}, timerInterval);
}
}
return {
currentSnack,
checkForMoreSnacks,
closeCurrentSnack
};
}
};
</script>
<style lang="scss" scoped>
.snackbar {
position: absolute;
right: 10px;
bottom: 10px;
max-width: 500px;
border: solid 2px red;
padding: 1rem;
border-radius: 5px;
&__container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 30px;
}
}
.component-fade-enter-active,
.component-fade-leave-active {
transition: opacity 0.3s ease;
}
.component-fade-enter-from,
.component-fade-leave-to {
opacity: 0;
}
</style>
{{CurrentSnapshot}}
关上我
从“vuex”导入{useStore};
从“vue”导入{computed,ref};
导出默认值{
设置(){
常数timerInterval=1500;
const store=useStore();
让timeoutToken=null;
让零食=计算(()=>store.getters[“获取SNACKBAR\u消息]);
设CurrentSnapshot=ref(null);
//触发Snackbar最初出现的事件。
//很像事件总线
store.subscribe(变异=>{
//听这个特定的突变呼叫
if(mutation.type==“添加\u SNACKBAR\u消息”){
//如果已经存在一个问题,请不要继续
if(currentSnapshot.value)返回;
//如果没有令牌,请将该值设置为此settimeout函数,我们将执行以下操作:
//1.将当前值设置为数组的[0]索引。
//2.将该物品从商店的零食阵列中移除
currentSnack.value=snacks.value[0];
timeoutToken=setTimeout(()=>{
CloseCurrentSnapshot();
},timerInterval);
}
});
函数closeCurrentSnapshot(){
提交(“删除SNACKBAR\u消息”);
currentSnapshot.value=null;
timeoutToken=null;
}
函数CHECKFORMORE(){
如果(!零食.值.长度){
timeoutToken=null;
currentSnapshot.value=null;
}否则{
currentSnack.value=snacks.value[0];
timeoutToken=setTimeout(()=>{
CloseCurrentSnapshot();
},timerInterval);
}
}
返回{
小吃,
checkformore零食,
快餐
};
}
};
.斯纳克巴{
位置:绝对位置;
右:10px;
底部:10px;
最大宽度:500px;
边框:实心2px红色;
填充:1rem;
边界半径:5px;
&__容器{
显示:网格;
网格模板列:1fr;
网格模板行:1fr 30px;
}
}
.组件淡入激活状态,
.组件淡入淡出激活状态{
过渡:不透明度0.3s;
}
.组件淡入淡出,
.组件淡出至{
不透明度:0;
}
关键在于离开后的@钩子。我意识到,一旦显示的snackbar被移除,我们就可以使用这个钩子检查更多
这个钩子也是不使用setInterval
的原因
还为此创建了一个git