在我正在处理的网站中,我不得不使用事件发射器来达到要求。请查看fiddle。添加新邮件时,它会正常工作。但是当我点击route1
或route2
并返回Parent
视图时,问题便开始了。然后,我尝试添加一条新消息。它将出现两次或三次(如果您访问所有路线并返回)。我不完全确定是怎么回事。任何解决这个问题的建议都会很棒。
PS:请不要建议使用$parent
而不是$root
,因为在我的项目中我必须使用$root
,因为该组件不是父组件的直接子组件。
以下是示例。
const Parent = {
template: `
<div>
<child-component></child-component>
<p v-for="msg in allMessages">{{msg}}</p>
</div>
`,
computed: {
allMessages: function () {
return this.$root.$store.state.storedMessages
}
},
mounted(){
this.$root.$on('NewMessage', function(data){
this.$store.dispatch('newMessage', data)
})
}
}
Vue.component('navs', {
template: `
<div>
<div class="left-nav-menu">
<router-link to="/">Parent</router-link>
<router-link to="/route1">route1</router-link>
<router-link to="/route2">route2</router-link>
</div>
</div>
`
})
Vue.component('child-component', {
template: `
<form id="messageForm" @submit.prevent="sendMessage">
<input type="text" v-model="message">
<button type="submit" >Send Message</button>
</form>
`,
data () {
return {
message: ''
}
},
computed: {
allMessages: function () {
return this.$root.$store.state.storedMessages
}
},
methods: {
sendMessage: function () {
this.$root.$emit('NewMessage', this.message)
}
}
})
const route1 = {
template: `<p>Route1</p>`
}
const route2 = {
template: `<p>Route2</p>`
}
const store = new Vuex.Store({
state: {
storedMessages: []
},
mutations: {
newMessage(state, data) {
state.storedMessages.push(data)
}
},
actions: {
newMessage({commit}, payload) {
commit('newMessage', payload)
}
}
})
const router = new VueRouter({
routes: [
{ name: 'parent', path: '/', component: Parent },
{ name: 'route1', path: '/route1', component: route1 },
{ name: 'route2', path: '/route2', component: route2 }
]
})
new Vue({
el: '#app',
store,
router
})
* {
box-sizing: border-box;
}
.listing {
list-style-type: none;
overflow: hidden;
padding: 0;
li {
float: left;
width: 175px;
padding: 10px;
text-align: center;
border: 1px #ddd solid;
background: white;
margin: 5px;
cursor: pointer;
img {
width: 100%;
margin-bottom: 7px;
}
&:hover {
background: #eee;
}
}
}
.item-view {
text-align: center;
}
.item {
background: white;
padding: 10px;
}
a {
font-size: 16px;
display: inline-block;
padding: 10px;
border: 1px #ddd solid;
background: white;
color: black;
margin: 10px;
&.back-listing {
position: absolute;
left: 0;
top: 0;
}
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex/dist/vuex.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<navs></navs>
<router-view></router-view>
</div>
答案 0 :(得分:3)
这种情况正在发生,因为您不断在mounted
中添加消息处理程序。你需要删除它们。
const Parent = {
template: `
<div>
<child-component></child-component>
<p v-for="msg in allMessages">{{msg}}</p>
</div>
`,
computed: {
allMessages: function () {
return this.$root.$store.state.storedMessages
}
},
methods:{
sendMessage(data){
this.$store.dispatch('newMessage', data)
}
},
mounted(){
this.$root.$on('NewMessage', this.sendMessage)
},
beforeDestroy(){
this.$root.$off('NewMessage', this.sendMessage)
}
}
更新了代码。
const Parent = {
template: `
<div>
<child-component></child-component>
<p v-for="msg in allMessages">{{msg}}</p>
</div>
`,
computed: {
allMessages: function () {
return this.$root.$store.state.storedMessages
}
},
methods:{
sendMessage(data){
this.$store.dispatch('newMessage', data)
}
},
mounted(){
this.$root.$on('NewMessage', this.sendMessage)
},
beforeDestroy(){
this.$root.$off('NewMessage', this.sendMessage)
}
}
Vue.component('navs', {
template: `
<div>
<div class="left-nav-menu">
<router-link to="/">Parent</router-link>
<router-link to="/route1">route1</router-link>
<router-link to="/route2">route2</router-link>
</div>
</div>
`
})
Vue.component('child-component', {
template: `
<form id="messageForm" @submit.prevent="sendMessage">
<input type="text" v-model="message">
<button type="submit" >Send Message</button>
</form>
`,
data () {
return {
message: ''
}
},
computed: {
allMessages: function () {
return this.$root.$store.state.storedMessages
}
},
methods: {
sendMessage: function () {
this.$root.$emit('NewMessage', this.message)
}
}
})
const route1 = {
template: `<p>Route1</p>`
}
const route2 = {
template: `<p>Route2</p>`
}
const store = new Vuex.Store({
state: {
storedMessages: []
},
mutations: {
newMessage(state, data) {
state.storedMessages.push(data)
}
},
actions: {
newMessage({commit}, payload) {
commit('newMessage', payload)
}
}
})
const router = new VueRouter({
routes: [
{ name: 'parent', path: '/', component: Parent },
{ name: 'route1', path: '/route1', component: route1 },
{ name: 'route2', path: '/route2', component: route2 }
]
})
new Vue({
el: '#app',
store,
router
})
&#13;
* {
box-sizing: border-box;
}
.listing {
list-style-type: none;
overflow: hidden;
padding: 0;
li {
float: left;
width: 175px;
padding: 10px;
text-align: center;
border: 1px #ddd solid;
background: white;
margin: 5px;
cursor: pointer;
img {
width: 100%;
margin-bottom: 7px;
}
&:hover {
background: #eee;
}
}
}
.item-view {
text-align: center;
}
.item {
background: white;
padding: 10px;
}
a {
font-size: 16px;
display: inline-block;
padding: 10px;
border: 1px #ddd solid;
background: white;
color: black;
margin: 10px;
&.back-listing {
position: absolute;
left: 0;
top: 0;
}
}
&#13;
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex/dist/vuex.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<navs></navs>
<router-view></router-view>
</div>
&#13;