vue.js - 为什么当 pinia 中的状态发生变化时我的 vue 组件不更新?

标签 vue.js vue-reactivity pinia

我正在开发一个使用 vue 和 firebase 的网站。在身份验证部分之后,用户进入仪表板,其中有他的项目列表,这些项目是 firestore 中用户文档的子集合。

我创建了一个管理这些数据的 pinia 商店,并且每次使用表单创建项目或删除项目时,state.projects 都会使用新的项目数组进行更新,这些项目会循环显示列表在 View 中。

在 View 内部,我可以访问 store.projects,这要归功于应该是 react 性的 getter,但是当我添加或删除项目时, View 中没有任何反应,但仍然是 state .projects 得到更新。

这里是DashboardView.vue的代码:

 <template>
  <MainHeader mode="dashboard" />

  <main class="main">
    <div class="main__container">
      <section class="main__section">
        <div class="section__header">
          <h1 class="header__title">Projects</h1>
          <!-- <TextInput type="text" placeholder="Search" v-model="filter" /> -->
        </div>
        <div class="section__content">
          <ul class="content__list">
            <li
              v-for="project in projects"
              :key="project.id"
              class="content__item"
            >
              {{ project.id }}
              <!-- <router-link
                :to="{ name: 'ProjectView', params: { id: project.id} }">
              </router-link> -->
              <SimpleButton @click="deleteProject(project.id)" type="button" text="delete" />
            </li>
          </ul>
        </div>
        <div class="section__footer">
          <form @submit.prevent="createProject">
            <TextInput type="text" placeholder="name" v-model="form.id" />
            <TextInput type="text" placeholder="website" v-model="form.website" />
            <SimpleButton type="submit" text="Add" />
          </form>
        </div>
      </section>
    </div>
  </main>
</template>

<script>
import { useUserDataStore } from "../stores/UserDataStore.js";
import MainHeader from "../components/MainHeader.vue";
import SimpleButton from "../components/SimpleButton.vue";
import TextInput from "../components/TextInput.vue";
import { ref } from '@vue/reactivity';

export default {
  name: "DashboardView",
  components: {
    MainHeader,
    SimpleButton,
    TextInput,
  },
  setup() {

    // const filter = "";
    const form = ref({});
    const userDataStore = useUserDataStore();
    const projects  = userDataStore.getProjects;

    const createProject = () => {
      userDataStore.createProject(form.value)
    }

    const deleteProject = (id) => {
      userDataStore.deleteProject(id)
    }

    return {
      projects,
      form,
      createProject,
      deleteProject,
    };

  },
};
</script>

这里是pinia商店代码:

   import { defineStore } from "pinia";
import router from "../router";
import { db } from '../firebase';
import { doc, setDoc, getDoc, getDocs, collection, deleteDoc } from 'firebase/firestore'

export const useUserDataStore = defineStore('UserDataStore', {
    state: () => {
        userData: { }
        projects: []
        uid: null
    },
    actions: {
        createNewUser(uid, name) {
            setDoc(doc(db, "users", uid), {
                name
            })
                .then(() => {
                    this.fetchUserData(uid)
                })
                .catch((error) => console.log(error))
        },

        fetchUserData(uid) {
            this.uid = uid

            // Fetch user doc with uid
            getDoc(doc(db, "users", uid))
                .then((response) => {
                    this.userData = response.data()

                    // Fetch user projects
                    getDocs(collection(db, "users", uid, "projects"))
                        .then((response) => {

                            const projectsArray = []

                            response.forEach(el => {
                                projectsArray.push({ data: el.data(), id: el.id})
                            })

                            this.projects = projectsArray
                            console.log(this.projects);

                            router.push({ name: 'DashboardView' })
                        })
                })
                .catch((error) => console.log(error))
        },

        createProject(details) {

            const { id, website } = details

            setDoc(doc(db, "users", this.uid, "projects", id), {
                website
            }).then(() => {
                console.log('created');
                this.fetchUserData(this.uid)
            })
            .catch((err) => console.log(err))
        },

        deleteProject(id) {
            deleteDoc(doc(db, "users", this.uid, "projects", id))
                .then(() => {
                    console.log('deleted');
                    this.fetchUserData(this.uid);
                })
                .catch(err => console.log(err))
        }
    },

    getters: {
        getProjects: (state) => state.projects
    }
})

最佳答案

store 是响应式对象,store 属性的响应性在 setup 函数中被访问时被禁用:

const projects  = userDataStore.getProjects;

应该是:

const projects  = computed(() => userDataStore.getProjects);

或者:

const { getProjects: projects } = storeToRefs(userDataStore);

关于vue.js - 为什么当 pinia 中的状态发生变化时我的 vue 组件不更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72078388/

相关文章:

javascript - 如何将项目推送到 Vuejs 中数据对象的数组中? Vue 似乎没有在看 .push() 方法

javascript - 不能在单个商店内使用 vue-router 和 pinia

vuejs3 - 使用 Pinia Store 中的对象,如何使用 vee-validate 验证它

javascript - 我如何使用 Vue.js 实现它?

javascript - Vue3在按钮单击时以编程方式创建组件实例

javascript - Vue.js 卡片中的某些项目没有反应性

typescript - Pinia/TypeScript 从操作中访问 getter — 类型上不存在属性

javascript - Vue.js + Express : Cannot get . Prevent/e.preventDefault() 可以工作吗?

validation - Vuetify 表单验证——定义匹配输入的 ES6 规则

javascript - 我的 Vue 对象不是响应式的。它可以在本地运行,但不能在托管服务器上运行