首页 > 解决方案 > 错误::未捕获(承诺中)类型错误:无法读取未定义的属性“内容”

问题描述

编写应用程序时,我得到与标题相同的错误。我在 Vue 中创建了一个应用程序并将数据存储在 firestore 中。

数据通过 发送this.$store.dispatch ('function')。我在该文件的第 47 行 EditNote.vue 中收到错误

methods: {
        editNote() {
            this.$store.dispatch('editNote', this.docId, {
                content: this.note.content
            });

            this.note.content = '';
        }
})

我不知道它是什么,也许你们中的一些人可以帮助我。如果你们中的任何人可以提供帮助,谢谢。

./src/components/EditNote.vue

<template>
    <div class="editnote">
        <div class="content">
            <div class="content__header">
                <h2 class="content__title">
                    Edytuj notatkę 
                </h2>
                <span class="content__close" @click="$emit('close')">
                    <i class="fas fa-times"></i>
                </span>
            </div>

            <div class="content__inside">
                <form @submit.prevent>
                    <textarea
                        class="content__textarea"
                        v-model.trim="note.content"
                        rows="6"
                        cols="20"
                        :placeholder="this.noteContent"
                    ></textarea>

                    <span class="content__plus-icon" @click="editNote"
                        ><i class="fas fa-edit"></i
                    ></span>
                </form>
            </div>
        </div>
    </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
    props: ['docId', 'noteContent'],
    data() {
        return {
            note: {
                content: ''
            }
        };
    },

    methods: {
        editNote() {
            this.$store.dispatch('editNote', this.docId, {
                content: this.note.content
            });

            this.note.content = '';
        }
    }
};
</script>

./src/store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import * as fb from '../firebase';
import router from '../router/index';

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        userProfile: {},
        notes: []
    },

    mutations: {
        setUserProfile(state, val) {
            state.userProfile = val;
        },

        setNotes(state, val) {
            state.notes = val;
        }
    },

    actions: {
        async getNotes() {
            await fb.usersCollection
                .doc(fb.auth.currentUser.uid)
                .collection('notes')
                .orderBy('createdOn', 'desc')
                .onSnapshot(snapshot => {
                    let notesArray = [];

                    snapshot.forEach(doc => {
                        let note = doc.data();
                        note.id = doc.id;

                        notesArray.push(note);
                    });

                    store.commit('setNotes', notesArray);
                });
        },

        async addNote({}, note) {
            await fb.usersCollection
                .doc(fb.auth.currentUser.uid)
                .collection('notes')
                .add({
                    createdOn: new Date(),
                    content: note.content,
                    userId: fb.auth.currentUser.uid
                });
        },

        async editNote({ commit }, docId, note) {
            await fb.usersCollection
                .doc(fb.auth.currentUser.uid)
                .collection('notes')
                .doc(docId)
                .update({
                    createdOn: new Date(),
                    content: note.content
                });
        },

        async deleteNote({}, docId) {
            if (window.confirm('Jesteś pewny/a, że chcesz usunąć notatkę?')) {
                await fb.usersCollection
                    .doc(fb.auth.currentUser.uid)
                    .collection('notes')
                    .doc(docId)
                    .delete();
            }
        },

        async signup({ dispatch }, form) {
            // sign user up
            const { user } = await fb.auth.createUserWithEmailAndPassword(
                form.email,
                form.password
            );

            // create user profile object in userCollection
            await fb.usersCollection.doc(user.uid).set({
                username: form.username,
                email: form.email,
                password: form.password
            });

            // fetch user profile and set in state
            dispatch('fetchUserProfile', user);

            router.push('/login');
        },

        async login({ dispatch }, form) {
            // sign user in
            const { user } = await fb.auth.signInWithEmailAndPassword(
                form.email,
                form.password
            );

            // fetch user profile and set in state
            dispatch('fetchUserProfile', user);
        },

        async logout({ commit }) {
            await fb.auth.signOut();

            // clear userProfile and redirect to /login
            commit('setUserProfile', {});
            router.push('/login');
        },

        async fetchUserProfile({ commit }, user) {
            // fetch user profile
            const userProfile = await fb.usersCollection.doc(user.uid).get();

            // set user profile in state
            commit('setUserProfile', userProfile.data());

            // change router to dashboard
            if (router.currentRoute.path === '/login') {
                router.push('/');
            }
        }
    },
    modules: {}
});

export default store;

./src/views/Homepage.vue

<transition
                enter-active-class="animate__animated animate__backInUp animate__faster"
                leave-active-class="animate__animated animate__backOutDown animate__faster"
                mode="out-in"
                appear
            >
                <EditNote
                    v-if="showEditNote"
                    @close="toggleEditNote()"
                    :docId="selectedNote"
                    :noteContent="selectedNoteContent"
                ></EditNote>
            </transition>

            <div class="notes">
                <div
                    class="notes__container-title-icon"
                    @click="toggleAddNotes"
                >
                    <h3 class="notes__title">Notatki</h3>
                    <span class="notes__plus-icon">
                        <i class="fas fa-plus"></i>
                    </span>
                </div>

                <ul class="notes__list" v-if="notes.length">
                    <li
                        class="notes__item"
                        v-for="note in notes"
                        :key="note.id"
                    >
                        {{ note.content }}

                        <br />
                        <span class="notes__createdOn">{{
                            getCurrentDate(note.createdOn)
                        }}</span>
                        <br />
                        <div class="notes__extras">
                            <span
                                class="notes__edit"
                                @click="toggleEditNote(note.id, note.content)"
                                ><i class="far fa-edit"></i
                            ></span>
                            <span
                                class="notes__delete"
                                @click="deleteNote(note.id)"
                                ><i class="far fa-trash-alt"></i
                            ></span>
                        </div>
                    </li>
                </ul>

                <ul class="notes__list" style="list-style-type: none" v-else>
                    <li class="notes__item">
                        Nie ma żadnej notatki 
                    </li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>
import AddNotes from '@/components/AddNotes';
import EditNote from '@/components/EditNote';
import { mapState } from 'vuex';

export default {
    data() {
        return {
            showAddNotes: false,
            showEditNote: false,
            selectedNote: '',
            selectedNoteContent: '',
        };
    },

    components: {
        AddNotes,
        EditNote
    },

    computed: {
        ...mapState(['userProfile', 'notes']),
    },

    beforeMount() {
        this.getCurrentDate();
    },

    created() {
        this.getNotes();
    },

    methods: {
        toggleEditNote(docId, noteContent) {
            this.showEditNote = !this.showEditNote;

            if (this.showEditNote) {
                this.selectedNote = docId;
                this.selectedNoteContent = noteContent;
            } else {
                this.selectedNote = {};
                this.selectedNoteContent = {};
            }
        },

        toggleAddNotes() {
            this.showAddNotes = !this.showAddNotes;
        },

        getNotes() {
            this.$store.dispatch('getNotes');
        },

        deleteNote(docId) {
            this.$store.dispatch('deleteNote', docId);
        },

标签: javascriptfirebasevue.jsvuejs2vuex

解决方案


问题在于editNote行动。动作只能接收一个参数,因此您需要将多个值作为对象或数组传递。将其更改为:

async editNote({ commit }, { docId, note }) {  // Notice the braces
   await fb.usersCollection
     .doc(fb.auth.currentUser.uid)
     .collection('notes')
     .doc(docId)
     .update({
        createdOn: new Date(),
        content: note.content
     });
},

并以这种方式在您的组件中调用它:

methods: {
   editNote() {
      const docId = this.docId;
      const note = {
         content: this.note.content
      };

      this.$store.dispatch('editNote', { docId, note }); // Notice the braces

      this.note.content = '';
   }
}

推荐阅读