2017-04-01 144 views
5

我很努力工作。我需要从FormComponent访问ChooseLangComponent中的selected值。有没有直接的方法来做到这一点,或者我们必须从父组件中传递它(像中间人一样)?我已经在ChooseLangComponent上尝试了$emit,并且在FormComponent上尝试了v-on:..,但没有奏效。在子组件之间传递数据

ChooseLangComponent:

<template lang="html"> 
    <div class="choose-lang"> 
     <select v-model="selected"> 
      <option v-for="lang in langs" v-bind:value="lang.value">{{lang.text}}</option> 
     </select> 
    </div> 
</template> 

<script> 
    export default { 
     data() { 
      return { 
       selected: 'en', 
       langs: [ 
        { text: 'English', value: 'en' }, 
        { text: 'German', value: 'ge' }, 
       ] 
      } 
     } 
    } 
</script> 

FormComponent:

<template lang="html"> 
    <div class="form-name"> 
     <div class="inputs"> 
      <input type="text" v-model="nameText" v-on:keyup.enter="send_name"> 
     </div> 
    </div> 
</template> 

export default { 
    data() { 
     return { 
      nameText: '', 
     } 
    }, 
    methods: { 
     send_name() { 
       // I need the selected language here 
     } 
    } 
} 

父组件:

<div id="app"> 
    <choose-lang></choose-lang> 
    ... 
    <form-comp></form-comp> 
</div> 

... 
Vue.component('choose-lang', require('./components/ChooseLangComponent.vue')); 
Vue.component('form-comp', require('./components/FormComponent.vue')); 

const app = new Vue({ 
el: '#app', 
data: { 
    ... 
}); 
+0

这样的事情呢? - http://jsbin.com/siyipuboki/edit?html,js输出 –

回答

7

好有2点简单的方法,一个更加其中涉及Vuex,如果您的应用程序规模很大。

第一种方式是创建事件总线 - 想法是在一个集线器中发射事件,然后将它们捕捉到需要的地方。

const Bus = new Vue({}) 

Vue.component('lang', { 
     template: '#lang-tmp', 
     data() { 
      return { 
       selected: 'en', 
       langs: [ 
        { text: 'English', value: 'en' }, 
        { text: 'German', value: 'ge' }, 
       ] 
      } 
     }, 
     created() { 
      this.changeLang() 
     }, 
     methods: { 
      changeLang() { 
      Bus.$emit('langChanged', this.selected) 
      } 
     } 
}) 

Vue.component('frm', { 
    template: '#frm-tmp', 
    data() { 
    return { 
     selectedItem: 'en' 
    } 
    }, 
    created() { 
    Bus.$on('langChanged', (selected) => { 
     this.selectedItem = selected 
    }) 
    } 
}) 

const app = new Vue({ 

    el: '#app' 

}) 

http://jsbin.com/siyipuboki/edit?html,js,output

第二种方式是创建店面的那种 - 普通对象,将举行所选项目的状态

const store = { 
    data: { 
    selected: null 
    } 
} 

Vue.component('lang', { 
     template: '#lang-tmp', 
     data() { 
      return { 
       selected: 'en', 
       langs: [ 
        { text: 'English', value: 'en' }, 
        { text: 'German', value: 'ge' }, 
       ] 
      } 
     }, 
     created() { 
      this.changeLang() 
     }, 
     methods: { 
      changeLang() { 
      store.data.selected = this.selected 
      } 
     } 
}) 

Vue.component('frm', { 
    template: '#frm-tmp', 
    data() { 
    return { 
     storeSelected: store.data 
    } 
    } 
}) 

const app = new Vue({ 

    el: '#app' 

}) 

http://jsbin.com/qagahabile/edit?html,js,output

同时请参阅本VueJS access child component's data from parent

+0

谢谢,只要我在我的项目上测试,我会尽快接受。我想给你+1,但不能因为拒绝... –

+0

第一种方法有问题。 '总线未定义',指的是langComponent中的总线。我在app.js上声明了'const Bus = ...',并且组件在单独的文件中(不知道这是不是问题) –

+0

对不起,jsbin没有任何错误地正常工作。 –