【问题标题】:Pass data from Component into Root将数据从 Component 传递到 Root
【发布时间】:2017-08-12 23:55:17
【问题描述】:

假设这个组件:

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Example Component</div>
                    <div class="panel-body">
                        I'm an example component!
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
          return {
              items: [
                  { message: 'Test 1' },
                  { message: 'Test 2' },
                  { message: 'Test 3' },
              ]
            }
        },
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

这是我的app.js

Vue.component('example', require('./components/Example.vue'));

const app = new Vue({
    el: '#app'
});

现在,我需要像这样打印示例组件中的所有items

<ul id="example-2">
   <li v-for="(item, index) in items">
       @{{ index }} - @{{ item.message }}
   </li>
</ul>

它返回给我以下错误:

[Vue 警告]:实例上未定义属性或方法“items” 但在渲染期间引用。确保声明反应数据 数据选项中的属性。 (见于)

主要问题是:

如何将数据从子组件传递到 Root ?

任何帮助将不胜感激。

【问题讨论】:

  • 您是否希望父级能够指定子级应该如何布置数据?比如,父组件应该指定你的组件的panel-body

标签: vue.js vuejs2


【解决方案1】:

您可以通过三种方式进行非父子关系(直接关系)通信。

  1. 从子组件发出一个事件,然后从接收父组件发出值,直到根接收到该值。 (不要用这个)

  2. 使用event bus,如果您的应用程序很小,这就是您要寻找的答案。

  3. 使用 vuex,如果您的应用程序将更多地使用组件状态/是大型应用程序,这就是您正在寻找的答案。


示例

// assuming your component
import { mapActions } from 'vuex'

export default {
    data() {
      return {
          items: [
              { message: 'Test 1' },
              { message: 'Test 2' },
              { message: 'Test 3' },
          ]
        }
    },
    mounted() {
        console.log('Component mounted.')
        this.setItemsToStore(this.items)
    },
    methods: {
      ...mapActions({
        'setItemsToStore': 'SET_ITEMS_TO_STORE'
      })
    }
}

然后在 main.js 中连接 vuex

import Vue from 'vue'
import { store } from './path/to/store'
import App from './path/to/App'

new Vue({
  el: '#app',
  store,
  template: '<App/>',
  components: { App }
})

设置模块化 vuex 存储,例如:

import Vue from 'vue'
import Vuex from 'vuex'
import itemStore from './modules/itemStore'

Vue.use(Vuex)

export const store = new Vuex.Store({
  modules: {
    itemStore
  }
})

最后你的 itemStore 看起来像:

const state = {
  ITEMS: []
}

const getters = {
  GET_ITEMS: (state) => {
    return state.ITEMS
  }
}

const mutations = {
  MUTATE_ITEMS: (state, payload) => {
    state.ITEMS = payload
  }
}

const actions = {
  SET_ITEMS_TO_STORE: ({commit}, payload) => {
    commit('MUTATE_ITEMS', payload)
  }
}

export default {
  state,
  getters,
  mutations,
  actions
}

完成此设置后,您的app.js 可以像这样使用它:

import { mapGetters } from 'vuex'

const app = new Vue({
  el: '#app',
  computed: {
    ...mapGetters({
      'items': 'GET_ITEMS'
    })
  }
});

示例 2

//bus.js

export new Vue()

这是一个空的 vue 实例,将在整个应用程序中使用。

// your assumed component
import eventBus from 'path/to/bus.js'

export default {
  data() {
    return {
     items: [
          { message: 'Test 1' },
          { message: 'Test 2' },
          { message: 'Test 3' },
       ]
     }
  },
  mounted() {
    console.log('Component mounted.')
    eventBus.$emit('items-evt', this.items)
  }
}

在这里,您只需在安装组件时发出一个事件。

// app.vue
import eventBus from 'path/to/bus.js'

const app = new Vue({
  el: '#app',
  data () {
    return {
      items: []
    }
  },
  created () {
    eventBus.$on('items-evt', (items) => {
      this.items = items
    })
  }
});

在应用组件创建时监听它。

【讨论】:

  • 谢谢。我阅读了vuex 链接,但我仍然不知道该怎么做! :(
  • 哇!多么困难! :(
  • 如果您的应用程序有很多组件间通信,这将是值得的。否则,使用 eventBus,那就更简单了。
  • 如果你能给我一个eventBus 的例子,我将不胜感激。
  • @HamedKamrava 我为 eventBus 添加了一个示例
猜你喜欢
  • 2018-07-18
  • 2020-03-15
  • 1970-01-01
  • 2021-12-14
  • 2020-10-01
  • 2018-11-09
  • 2021-05-18
  • 2017-04-09
  • 2013-11-28
相关资源
最近更新 更多