我有一个组件(倒数计时器),它将在网站的所有页面上运行。在顶级App.vue文件中引用了它。我需要能够从应用程序内的任何其他组件调用该组件内部的事件(以重新启动时间),而不管它的层次结构链有多深(意味着,我不想在每个事件中都运行事件和$ emits)网站上针对这一件事的单一组件)。
每当我对服务器进行ajax调用时,我都想重置计时器。因此,每次在下面的代码中单击一个按钮时,我都想触发倒数计时器组件上的startCountdown(true)
事件。
Here's a codesandbox example of what I'm doing.
Main.js
import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";
import router from "./router/router";
import VueAwesomeCountdown from "vue-awesome-countdown";
Vue.config.productionTip = false;
Vue.use(Vuex);
Vue.use(VueAwesomeCountdown);
const store = new Vuex.Store({
state: {
count: 0
},
getters: {
count: state => {
return state.count;
}
},
mutations: {
increment: state => state.count++,
decrement: state => state.count--
},
actions: {
increment: context => {
context.commit("increment");
},
decrement: context => {
context.commit("decrement");
}
}
});
new Vue({
el: "#app",
router,
store,
template: "<App />",
components: {
App
}
});
App.vue
<template>
<div id="app">
<router-link to="/" class="btn bt-link">Page 1</router-link> |
<router-link to="/Page2" class="btn bt-link">Page 2</router-link> |
<router-link to="/Page3" class="btn bt-link">Page 3</router-link>
<hr>
<br>
<br>
<router-view></router-view>
<br>
<br>
<hr>
<!-- Timer countdown -->
<countdown ref="sessionTimer" :left-time="99000">
<span slot="process" slot-scope="{ timeObj }">Session Timer Countdown: {{ timeObj.ceil.s }}</span>
<span slot="finish">TIMED OUT!</span>
</countdown>
<button class="ml-3 btn btn-warning" @click="restart">Manual Restart</button>
<hr>
<!-- The below is just show vuex is wired up correctly -->
<p>This is just to show that Vuex is working properly.</p>
<p>{{ count }}</p>
<p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</p>
</div>
</template>
<script>
export default {
name: "App",
computed: {
count() {
return this.$store.getters.count;
}
},
methods: {
restart() {
this.$refs.sessionTimer.startCountdown(true);
},
increment() {
this.$store.dispatch("increment");
},
decrement() {
this.$store.dispatch("decrement");
}
},
components: {}
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 20px;
}
</style>
Page2.vue
<template>
<div>
<h1>Page 2</h1>
<br>
<br>
<button class="btn btn-success" @click="interactWithServer">Interact with Server 2</button>
<br>
<br>
<SubComponent></SubComponent>
</div>
</template>
<script>
import SubComponent from "./Page2-SubComponent.vue";
export default {
methods: {
interactWithServer() {
//This function will interact with server but I need to start countdown timer over again first
//axios call goes here after timer is reset
}
},
components: {
SubComponent
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>
Page-SubComponent.vue
<template>
<div>
<h3>SUB COMPONENT</h3>
<br>
<br>
<button class="btn btn-primary" @click="interactWithServer">Interact with Server 2.1</button>
</div>
</template>
<script>
export default {
methods: {
interactWithServer() {
//This function will interact with server but I need to start countdown timer over again first
//axios call goes here after timer is reset
}
}
};
</script>
答案 0 :(得分:1)
不确定是否有更短的方法,但是您可以在商店中触发一个变量,然后从App.vue
文件中侦听该变量,然后执行restart
打开,这是一个{{3 }}样本
// store
state: {
changed: false
}
getters: {
changed: (state) => state.changed
}
mutation: {
changed: (state) => state.changed = !state.changed
}
// App.vue
computed: {
trigger() {
return this.$store.getters.changed
}
},
methods: {
restart() {
this.$refs.sessionTimer.startCountdown(true);
}
},
watch: {
trigger() {
this.restart()
}
}
关于其他组件:
interactWithServer() {
this.$store.commit("changed");
}
答案 1 :(得分:0)
最好将计时器的编号保存在商店中的:left-time =“ 99000” 中,以及在 interactWithServer()中触发事件时 strong>重设吗?
Main.js (附加代码)
state:{
timer: 99000
},
getters: {
getTimer: state => {
return state.timer;
}
},
mutations: {
resetTimer: state => state.timer = 99000
},
actions: {
restartTimer: context => {
context.commit("resetTimer");
}
}
App.vue (修改后的代码)
</template>
<countdown ref="sessionTimer" :left-time="timer">
<span slot="process" slot-scope="{ timeObj }">Session Timer Countdown: {{ timeObj.ceil.s }}</span>
<span slot="finish">TIMED OUT!</span>
</countdown>
</template>
<script>
computed: {
timer() {
return this.$store.getters.timer;
}
},
</script>
然后在 interactWithServer()中调用 this。$ store.dispatch(“ restartTimer”);