vue.js using public event bus - Stack Overflow
黄舟
黄舟 2017-06-12 09:25:35
0
2
947

While practicing the use of the vue framework and writing a todo demo, I put the input element (new-input component) and the ul and li elements ( todo-items and todo-item components) are written as two parallel components. Now enter text to add in the input component, use the public event bus to trigger the update event, and create a hook function in the life cycle of the todo-items component to listen to the update event and Modify the data in the component, and then the problem comes. The error message shows that the todos array of the component is undefined

#Post the code below

var bus = new Vue({});

var todoItem = Vue.component('todo-item', {
    props:['todo'],
    template:'<li class="animated fadeIn cusFont" v-bind:class="{ done:isDone }"><span><button class="done" v-on:click="done" v-bind:class="{doneButton: isDone}"></button></span><p v-bind:class="{doneItem:isDone}">{{todo.text}}</p><button class="delete" v-on:click="deleteIt">×</button></li>',
    data:function(){
        return {
            isDone:false
        }
    },
    methods:{
        done:function(){
            this.$emit('hasDone');
            this.isDone = !this.isDone;
        },
        deleteIt:function(){
            this.$emit('hasDelete');
        }
    }    
});
var todoItems = Vue.component('todo-items', {
    template:'<ul><todo-item v-for="(item, index) in todos" v-bind:todo="item" v-on:hasDelete="deleteItem(index)"></todo-item></ul>',
    data:function(){
        return {
            todos:[
                {text:'nodeJS'},
                {text:'vue.js'}
            ]
        }
    },
    components:{
        'todo-item':todoItem
    },
    methods:{
        deleteItem:function(index){
            this.todos.splice(index, 1);
        },
        update:function(value){
            this.todos.push(value);
        }
    },
    created(){
        bus.$on('updateData', function(value){
            this.todos.push(value);
        })
    }
})

var newInput = Vue.component('new-input', {
    template:'<input ref="input" placeholder="What needs to be done?" id="js-input-item" v-bind:value="value" class="animated fadeIn cusFont" v-on:keyup.enter="update">',
    data:function(){
        return {
            value:''
        }
    },
    methods:{
        update:function(){
            bus.$emit('updateData', {text:this.$refs.input.value});
        }
    }
})

var todo = new Vue({
    el:'#todo',
    components:{
        "todo-items":todoItems,
        "new-input":newInput
    }
})

For some unknown reason, the deleteItem method in todo-items can also operate the todos array.

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

reply all(2)
typecho

Answer on mobile
The problem mainly occurs in bus.$emit. Bus is a new instance of Vue, and its this has no todos. It should be like this

Inside

created:
const that = this
Afterwards, this inside bus is changed to that

Answer on mobile phone, I won’t write detailed code, you should understand

世界只因有你

This in the callback function monitored by the bus instance does not point to the vue instance you expected. The solution is as mentioned above

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template