简体   繁体   中英

how to share data between components in VUE js (while creating list)

Could you please tell me how to share data between components in VUE js (while creating list).I have two components list components and add todo component .I want to add items in list when user click on add button .But issue is input field present in different component and list is present in different component here is my code https://plnkr.co/edit/bjsVWU6lrWdp2a2CjamQ?p=preview

// Code goes here

var MyComponent = Vue.extend({
    template: '#todo-template',
    props: ['items']


});
var AddTODO = Vue.extend({
    template: '#add-todo',
    props: ['m'],
    data: function () {
        return {
            message: ''
        }
    },
    methods: {
        addTodo: function () {
            console.log(this.message)
            console.log(this.m);
            //this.m =this.message;
        },
    },
});
Vue.component('my-component', MyComponent);
Vue.component('add-todo', AddTODO)


var app = new Vue({
    el: '#App',
    data: {
        message: '',
        items: []
    },


});

The whole point of having a great MVVM framework is to let you have a view-model: a central store of all the state in your page/app/whatever. Components can emit events. You can have an event bus. But if you can save the day with a simple, global variable containing all your state, this is by far the cleanest, best solution. So just put your to-dos in an array, in a variable in global scope, then declare them in the data of every component that needs them. Here it is working in Plunkr .

markup

<div id="App" >
    <add-todo></add-todo>
    <my-component></my-component>
</div>
<template id="add-todo">
    <div>
        <input type="text" v-model="message">
        <button @click="addTodo">Add todo</button>
    </div>
</template>
<template id="todo-template">
    <div>
        <ul >
            <li v-for="(item,index) in store.items">
                {{item.message}}
            </li>
        </ul>
    </div>
</template>
<script src="vue.js"></script>
<script src="script.js"></script>

code

// This is the magic store. This is all you need.
var vueStore = {items : []};

var MyComponent = Vue.extend({
    template: '#todo-template',
    data : function(){return {store : vueStore}}
});
var AddTODO = Vue.extend({
    template: '#add-todo',
    data: function () {
        return {
            message: '',
            store : vueStore
        }
    },
    methods: {
        addTodo: function (event) {    
          this.store.items.push({'message' : this.message})
        },
    },
});
Vue.component('my-component', MyComponent);
Vue.component('add-todo', AddTODO)    
var app = new Vue({
    el: '#App',
    data: {
        store : vueStore
    },
});

This is not a savage hack! We're being called to stop thinking about events, move up the food chain, and think about reactive pipes. Components don't care when or by who the central store gets updated. Vue takes care of it.

Here's the page on state management.

So you could use events and emit the created todo to the root vue instance. I edited / forked your plunkr (I'm rather the fiddle type).

https://plnkr.co/edit/bnMiDmi30vsj3a8uROBK?p=preview

So I edited this line here, which listens for a custom event added and pushes the first argument to items.

<add-todo v-on:added='items.push(arguments[0])'></add-todo>

And also these lines, which emit the event. And i changed from the property m to the data message , because you shouldnt mutate props:

    <input type="text" v-model="message">
    <button @click="$emit('added', message)">Add todo</button>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM