当我在另一个组件中添加数据时,我必须更新另一个组件

时间:2019-01-07 00:51:12

标签: javascript vue.js

当我使用TaskForm添加数据时,我必须重新加载页面以查看CardComponent所保持的效果。我想立即查看最近添加的数据。实现此结果的最佳方法是什么?

我必须发布两个组件的代码,所以我正在使用Pastebin

TaskForm:https://pastebin.com/HVjwkAKd

CardComponent:https://pastebin.com/PM00TzRq

我不擅长使用Vue,这就是为什么我寻求帮助。谢谢!

2 个答案:

答案 0 :(得分:2)

这是使用Vuex(一种在多个组件之间提供反应性状态的集中式单例)进行状态管理的典型用例。

文档中的两个要点是:

  • Vuex存储是反应性的。 Vue组件从中检索状态时,如果商店的状态发生变化,它们将作出反应并有效地进行更新。

  • 您不能直接更改商店的状态。更改商店状态的唯一方法是显式提交突变。这样可以确保每次状态更改都留下可跟踪的记录,并启用有助于我们更好地了解应用程序的工具。

此示例显示了如何进行突变并观察组件中的状态变化:

Vue.use(Vuex)

const baseComponent = {
  props: ['resource'],
  data: () => ({
    loading: false
  }),
  computed: {
    title () {
      return this.resource.charAt(0).toUpperCase() + this.resource.slice(1) + ' Component'
    },
    btnText () {
      return this.loading ? `Fetching ${this.resource}...` : `Fetch ${this.resource}`
    }
  },
  methods: {
    async fetchResource() {
      this.loading = !this.loading

      const resources = await fetch(`https://jsonplaceholder.typicode.com/${this.resource}`)
        .then(response => response.json())
        .then(resources => resources)

      this.$store.commit(`set${this.resource.charAt(0).toUpperCase() + this.resource.slice(1)}`, resources)

      this.loading = !this.loading
    }
  },
  template: `<div>
  <h1>{{ title }}</h1>
  <button @click="fetchResource" :disabled="loading">{{ btnText }}</button>
  <p>Total Posts: {{ $store.getters['getPosts'].length }}</p>
  <p>Total Todos: {{ $store.getters['getTodos'].length }}</p>
  </div>`
}

Vue.component('component-a', baseComponent)
Vue.component('component-b', baseComponent)

const store = new Vuex.Store({
  state: {
    posts: [],
    todos: []
  },
  getters: {
    getPosts: (state) => state.posts,
    getTodos: (state) => state.todos,
  },
  mutations: {
    setPosts: (state, posts) => {
      state.posts = posts
    },
    setTodos: (state, todos) => {
      state.todos = todos
    }
  }
})

new Vue({
  el: '#app',
  store
})
#app {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
  <component-a resource="posts"></component-a>
  <component-b resource="todos"></component-b>
</div>

答案 1 :(得分:0)

我决定使用公共汽车,因为我的项目不大。现在看起来像这样:

TaskForm:

methods:{

            addTask() {
                EventBus.$emit('taskCreated',{title:this.title, second_title:this.second_title});
                axios.post('./api/word', {
                    title:this.title,
                    second_title:this.second_title
                     })

                 }

CardComponent:

created(){

          axios.get('./api/word')
                .then(response => this.words = response.data);        


          EventBus.$on('taskCreated', (title,second_title) => {

              this.words.push(title);

              this.words.push(second_title);           


              axios.get('./api/word')
                .then(response => this.words = response.data);


          });

我的问题是CardComponent中代码的重复。如果created()中不存在带有axios的代码,则不会生成任何内容。如果我在EventBus部分中省略了此代码,则看不到自动更新。但是,当我使用此代码时,有时没有可见的更新,有时没有添加一个任务,而是出现了两个或三个(它们当然是相同的)。有什么办法可以解决我的问题?