代码之家  ›  专栏  ›  技术社区  ›  Success Man

如何使用在父组件中更新的子组件中的数据Vue.js?

  •  -3
  • Success Man  · 技术社区  · 6 年前

    <template>
        ...
            <PaymentMethod/>
            ...
            <b-btn class="float-right" variant="primary" @click="add">
                 OK
            </b-btn>
        ...
    </template>
    <script>
        export default {
            ...
            methods: {
                add() {
                    ...
                }
            }
        }
    </script>
    

    我的子组件看起来像:

    <template>
        ...
            <b-form-select v-model="selected" :options="methodOptions" />
            ...
            <b-form-select v-model="termSelected" :options="termOptions" />
        ...
    </template>
    <script>
        export default {
            data () {
                return {
                    selected: null,
                    termSelected: null
                }
            },
            ...
        }
    </script>
    

    如果 add

    我该怎么做?

    4 回复  |  直到 4 年前
        1
  •  1
  •   Brian Lee    6 年前

    一种解决方法是使用 sync 修饰符以及计算的getter和setter:

    父组件

    <template>
        ...
            <PaymentMethod :method.sync="method" :term.sync="term"/>
            ...
            <b-btn class="float-right" variant="primary" @click="add">
                 OK
            </b-btn>
        ...
    </template>
    <script>
        export default {
            data () {
                return {
                    method: null,
                    term: null
                }
            },
            ...
        }
    </script>
    

    子组件

    <template>
        ...
            <b-form-select v-model="_method" :options="methodOptions" />
            ...
            <b-form-select v-model="_term" :options="termOptions" />
        ...
    </template>
    <script>
        export default {
            props: ['method', 'term'],
            computed: {
                _method: {
                   get () {
                       return this.method
                   },
                   set (value) {
                       this.$emit('update:method', value)
                   }
                },
                _term: {
                   get () {
                       return this.term
                   },
                   set (value) {
                       this.$emit('update:term', value)
                   }
                },
            },
            ...
        }
    </script>
    

    现在使用父组件的 add 方法,您可以访问子对象的 method term 选项:

    methods: {
        add() {
            // this.method is the value of _method 
            // this.term is the value of _term
        }
    }
    

    更新

    既然您已经声明您想要所选术语/方法的值和文本,我建议进行以下更改:

    起源

    <template>
        ...
            <PaymentMethod :methods="methods" 
                           :terms="terms"  
                           :method.sync="method" 
                           :term.sync="term"/>
            ...
            <b-btn class="float-right" variant="primary" @click="add">
                 OK
            </b-btn>
        ...
    </template>
    <script>
        export default {
            data () {
                return {
                    // define your method and term arrays in the parent component.
                    // pass them as props to the child component.
                    methods: [{...}, {...}, {...}],
                    terms: [{...}, {...}, {...}],
                    method: null,
                    term: null
                }
            },
            // use computed properties to retrieve the selected method / term option.
            computed: {
                selectedMethod () {
                    return this.methods.find(method => method.value === this.method)
                },
                selectedTerm () {
                    return this.terms.find(term => term.value === this.term)
                },
            }
            ...
        }
    </script>
    

    <template>
        ...
            <b-form-select v-model="_method" :options="methods" />
            ...
            <b-form-select v-model="_term" :options="terms" />
        ...
    </template>
    <script>
        export default {
            props: ['method', 'term', 'methods', 'terms'],
            computed: {
                _method: {
                   get () {
                       return this.method
                   },
                   set (value) {
                       this.$emit('update:method', value)
                   }
                },
                _term: {
                   get () {
                       return this.term
                   },
                   set (value) {
                       this.$emit('update:term', value)
                   }
                },
            },
            ...
        }
    </script>
    
        2
  •  1
  •   Boussadjra Brahim    6 年前

    使用Vuex,您的商店.js看起来像:

     import Vue from 'vue';
     import Vuex from 'vuex';
       Vue.use(Vuex);
    
    
     const state = {
        selected: null
     };
     const mutations = {
        SET_SELECTED(state, selected) {
        state.selected =selected;
       }
       }
    
     export default new Vuex.Store({
        state,
       mutations
       })
    

    在应用程序.js:

    import store from './vuex/store';
    const app = new Vue({
    el: '#app',
    store,
    ...})
    

    在父组件中:

        <template>
         ...
       <PaymentMethod :selected="selected" />
         ...
            <b-btn class="float-right" variant="primary" @click="add">
            OK
            </b-btn>
         ...
        </template>
      <script>
       export default {
        data(){
         returen {
           selected:null    
         }
         },
        methods: {
            add() {
             ...
           this.$store.commit("SET_SELECTED",this.selected) 
          }
        }
     }
     </script>
    

       <template>
         ...
         <b-form-select @change="selectItem" v-model="selected" 
                 :options="methodOptions" />
       ...
     </template>
    <script>
      export default {
       data () {
        return {
          selected:null
        }
     },
     methods:{
       selectItem(){
        this.$store.commit("SET_SELECTED",this.selected
        }
        ...
     }
    

        3
  •  0
  •   Krishna    6 年前

    最好的推荐方法是使用$emit
    下面的例子可以告诉你怎么做?</br>

    Vue.component('child-tmp', {
      props: ['post'],
      template: `
      <button @click="$emit('add-like')">Like</button>
      `
    })
    new Vue({
      el: "#app",
      data: {
        posts: [{
          title: "Heading goes here 1",
          content: "Something sadofnd idfidif disong.",
          likes: 0
        },
        {
          title: "Heading 2 goes here",
          content: "Something sadofnd idfidif disong.",
          likes: 0
        }],
        totalLikes: 0
      }
    })
    <script src="https://unpkg.com/vue"></script>
    
    <div id="app">
      <h2>Posts:</h2>
      <section>
        <div v-for="post in posts">
          <h2>
            {{post.title}}
          </h2>
          <p>
            {{post.content}}
          </p>
          <child-tmp v-bind:post="post" v-on:add-like="post.likes = post.likes+1"></child-tmp><span style="margin-left:10px;">{{post.likes}}</span>
        </div>
      </section>
    </div>

        4
  •  -1
  •   xneg    6 年前

    有两种方法:

    1您可以在子组件中选择数据时发出事件:

    <template>
        ...
            <b-form-select v-model="selected" :options="methodOptions" />
        ...
    </template>
    <script>
        export default {
            data () {
                return {
                    selected: null
                }
            },
            ...
            methods: {
              onSelect() {
                this.$emit('selectData', this.selected);
              }
            }
        }
    </script>
    

    然后在父组件中处理此事件:

    <template>
        ...
            <PaymentMethod @selectData="changeChildData($event)"/>
            ...
            <b-btn class="float-right" variant="primary" @click="add">
                 OK
            </b-btn>
    
        ...
    </template>
    <script>
        export default {
            ...
            data() {
                return {
                  childData: null
                }
            },
            methods: {
                changeChildData(newData) {
                  this.childData = newData;
                },
                add() {
                    ...
                }
            }
        }
    </script>
    

    2或者你可以使用存储 Vuex

    或事件总线(Vuex的简化版本):

    import Vue from 'vue';
    export const EventBus = new Vue();
    

    <script>
        import { EventBus } from '../EventBus.js';
        export default {
            data () {
                return {
                    selected: null
                }
            },
            ...
            methods: {
              onSelect() {
                EventBus.$emit('selectData', this.selected);
              }
            }
        }
    </script>
    

    <script>
        import { EventBus } from '../EventBus.js';
        export default {
            ...
            data() {
                return {
                  childData: null
                }
            },
            created() {
                EventBus.$on('selectData', (data) => {
                    this.childData = data;
                });
            },
            methods: {
                add() {
                    ...
                }
            }
        }
    </script>