【问题标题】:Nuxt component not updating but store is updating as expectedNuxt 组件未更新,但商店正在按预期更新
【发布时间】:2021-03-03 22:03:19
【问题描述】:

在这里已经获得了一些很好的帮助(我是 Vue 的新手,我学到了很多东西,这很酷)我还有一个问题。我的组件的状态正在按预期更新。在搜索字段中输入值时,该值将发送到 API,API 将响应并更新状态。现在的问题是我需要单击路由(而不是使用刷新/f5),然后才能在当前视图中真正看到更新的组件。到目前为止我的代码:

search.vue(不介意学生插值,虚拟数据)

<div class="mx-auto mt-2 max-w-7xl sm:px-6 lg:px-8">
      <div class="flex justify-between flex-1 max-w-xl px-4">
        <div class="px-4 py-6 sm:px-0">
          <ul id="tutors" class="grid grid-cols-1 gap-6">
            <li
              v-for="tutor in tutors"
              :key="tutor.name"
              class="overflow-hidden bg-white border rounded-lg shadow-md"
            >
              <div class="flex">
                <div class="w-2/3">
                  <img
                    class="flex-shrink-0 object-cover w-full h-64 mx-auto bg-black"
                    :src="student.imageUrl"
                    :alt="student.imageAlt"
                  />
                </div>
                <div class="p-6">
                  <div
                    class="text-xs font-semibold leading-snug tracking-wide text-gray-500 uppercase"
                  >
                    {{ student.subject }} &bull; {{ student.age }} jaar
                  </div>
                  <h4 class="text-lg font-semibold leading-5 tracking-wide">
                    {{ tutor.name }}
                  </h4>
                  <div class="mt-2">
                    {{ student.hourlyRate }}€

                    <span class="text-sm text-gray-600">per uur</span>
                  </div>
                  <div class="mt-2">
                    <span class="font-semibold text-light-blue-800"
                      >{{ student.rating }}/5 sterren</span
                    >
                    <span class="text-sm text-gray-600 truncate">
                      (na {{ student.reviewCount }} reviews)
                    </span>
                  </div>
                  </div>
                </div>
              </div>
            </li>
          </ul>

search.vue JS

<script>
import { mapGetters, mapState } from 'vuex'

export default {
  name: 'Zoeken',
  components: {},

  data: () => ({
    postcode: '',
    attributes: [],
  }),
  computed: {
    ...mapGetters(['isAuthenticated', 'loggedInUser']),
    ...mapState(['tutors']),
  },
  methods: {
    async fetchTutors() {
      const postcode = this.postcode
      await this.$store.dispatch('loadAllTutors', postcode)
    },
  },
  layout: 'app',
  middleware: 'auth',
}
</script>

store/index.js

export const getters = {
  isAuthenticated(state) {
    return state.auth.loggedIn
  },

  loggedInUser(state) {
    return state.auth.user
  },
}

export const state = () => ({})

export const mutations = {
  SET_TUTORS(state, val) {
    if (val == null || val.update === undefined) {
      state.tutors = val
    } else {
      const update = val.update
      state.tutors = { ...state.tutors, ...update }
    }
  },
}

export const actions = {
  loadAllTutors({ commit }, postcode) {
    this.$axios
      .post('http://notawanker.com/tutors/search', {
        postcode,
      })

      .then(({ data }) => {
        commit(
          'SET_TUTORS',
          data.map((item) => item.attributes)
        )
      })
      .catch((error) => console.log(error))
  },
}

这将是应用程序的主要组件,可以在其中搜索附近的用户。主要部分和 API 正在工作,但使其反应仍然是一个问题。我尝试了几种不同的方法都没有成功。非常感谢。

【问题讨论】:

    标签: vue.js nuxt.js vuex


    【解决方案1】:

    据我了解,在您的代码中,您首先使用 SET_TUTORS 来填充导师状态,但您在搜索后也使用它来更新?

      SET_TUTORS(state, val) {
        if (val == null || val.update === undefined) {
          state.tutors = val
        } else {
          const update = val.update
          state.tutors = { ...state.tutors, ...update }
        }
      },
    }
    

    如果是这样,你不能使用你正在做的更新不是响应式的,它将在 store 中更新,但不会触发 vue 响应式。

    你需要使用 Vue.set

     } else {
          const update = val.update
          this.$set(state.tutors, myProperty, myNewValue }
        }
    

    用于更新多个属性:

     } else {
          const update = val.update
    
    // for replacing the whole object
          this.state.tutors = Object.assign({}, this.state.tutors, update)
    
    // for replacing the a nested object in tutors
          this.state.tutors = Object.assign({}, this.state.tutors.myObjectToUpdate, update)
        }
    

    让我知道它是否有效,同时我可以建议您阅读更多关于 vuejs 中的反应性的信息,它会不时为您节省一些时间 :)

    https://vuejs.org/v2/guide/reactivity.html#For-Objects

    关注您的评论:

    当你从 state 更新单个属性时,你可以使用 this.$set(),当你想一次更新更多属性时,你需要使用 object.assign

    例子:

    tutors: {
     types: {
      women: 32
     } 
    }
    And you just want to add the men property number, you will do => this.$set(state.tutors.types, men, 32)
    

    上面的响应句柄reactivity,而myProperty就是你要添加的属性对象的名字

    根据您的问题,由于 SET_TUTORS 是多种用途,因此我会以这种方式编写代码以在需要更新时进行更新,如果它是基本 SET,则应该覆盖该状态中的所有内容:

     SET_TUTORS(state, val) {
        if (val == null || val.update === undefined) {
          state.tutors = Object.assign({}, val)
        } else {
          // will create a new object based on your current state and the updated values
          state.tutors = Object.assign({}, this.state.tutors, update)
        }
      },
    

    希望对你有帮助

    【讨论】:

    • 已经为此投了你的票。我阅读了文档并试图理解它。我只需要结果列表是反应性的,所以我假设我需要使用 this.$set 方法。但是我有: ` else { const update = val.update this.$set(state.tutors, myProperty, update) } ` myProperty 到底是什么?我应该在页面代码中添加一些东西还是 fetchTutors 方法足够了
    • 谢谢,我已经更新了回答您的评论问题的答案,希望对您有所帮助
    猜你喜欢
    • 1970-01-01
    • 2018-08-19
    • 2019-09-16
    • 1970-01-01
    • 2017-06-30
    • 2020-09-06
    • 2021-11-22
    • 2018-08-08
    • 1970-01-01
    相关资源
    最近更新 更多