如何解决Vue.js中的“属性或方法未在实例上定义但在渲染期间引用的问题”?

问题描述

我正在尝试从前端请求通知,但出现此错误

属性方法“ requestPermission”未在实例上定义,但在渲染期间被引用。通过初始化该属性,确保该属性在data选项中或对于基于类的组件都是反应性的。

代码中,正确拼写了方法requestPermission。但是我仍然面临着同样的问题。

Vue模板

<template>
    <div>
        <div class="sticky-top alert alert-primary" v-if="requestPermission"
             v-on:click="enableNotifications">
            Want to kNow when we publish a new recipe?
            <button class="btn btn-sm btn-dark">Enable Notifications</button>
        </div>
        <nav class="navbar navbar-expand-md navbar-light navbar-laravel">
            <div class="container">
                <router-link :to="{name: 'home'}" class="navbar-brand">Notification PWA</router-link>
                <button
                    class="navbar-toggler"
                    type="button"
                    data-toggle="collapse"
                    data-target="#navbarSupportedContent"
                    aria-controls="navbarSupportedContent"
                    aria-expanded="false"
                >
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav ml-auto">
                        <li>
                            <router-link :to="{name: 'home'}" class="nav-link">Recipes</router-link>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>

    <div class="py-4">
            <router-view></router-view>
        </div>
    </div>
</template>

Vue.js中的脚本

<script>
    import firebase from "firebase/app";
    import axios from "axios";
    import "firebase/messaging";

    export default {
        data() {
            return {
                // use a getter and setter to watch the user's notification preference in local storage
                get requestPermission() {
                    return (localStorage.getItem("notificationPref") === null)
                },set requestPermission(value) {
                    console.log(value)
                    localStorage.setItem("notificationPref",value)
                }
            }
        },methods: {
            registerToken(token) {
                axios.post(
                    "/api/register-token",{
                        token: token
                    },{
                        headers: {
                            "Content-type": "application/json",Accept: "application/json"
                        }
                    }
                ).then(response => {
                    console.log(response)
                });
            },enableNotifications() {
                if (!("Notification" in window)) {
                    alert("Notifications are not supported");
                } else if (Notification.permission === "granted") {
                    this.initializefirebase();
                } else if (Notification.permission !== "denied") {
                    Notification.requestPermission().then((permission) => {
                        if (permission === "granted") {
                            this.initializefirebase();
                        }
                    })
                } else {
                    alert("No permission to send notification")
                }
                this.requestPermission = Notification.permission;
            },initializefirebase() {
                if (firebase.messaging.isSupported()) {
                    let config = {
                        apiKey: "xxxxxxxxxxxxxxxxxxx",authDomain: "xxxxxxxxxxxxxx",projectId: "xxxxxxxxxx",messagingSenderId: "xxxxxxxxxxxxx",appId: "xxxxxxxxxxxxxxxxxxxxxxxxxx",};
                    firebase.initializeApp(config);
                    const messaging = firebase.messaging();

                    messaging.getToken()
                        .then((token) => {
                            console.log(token);
                            this.registerToken(token)
                        })
                        .catch((err) => {
                            console.log('An error occurred while retrieving token. ',err);
                        });

                    messaging.onMessage(function (payload) {
                        console.log("Message received",payload);
                        let n = new Notification("New Recipe alert!")
                    });
                }
            }
        }
    };
    

有什么办法可以解决这个问题?

解决方法

我认为您应该为此使用计算属性:

export default {
  data () {
    return {
      requestPermissionValue: null
    }
  },computed: {
    requestPermission: {
      get () {
        return this.requestPermissionValue
      },set (value) {
        this.requestPermissionValue = value
        localStorage.setItem("notificationPref",value)
      }
    }
  },created () {
    this.requestPermissionValue = localStorage.getItem("notificationPref") === null
  }
}

只要您不更改其他组件中的notificationPref localStorage项,它就可以正常工作。

创建的挂钩创建基于localStorage的值的初始副本。 localStorage不是被动的,这就是为什么您需要数据中的属性。