【问题标题】:How to resolve "Property or method is not defined on the instance but referenced during render.. " in Vue.js?如何解决 Vue.js 中的“属性或方法未在实例上定义但在渲染期间引用..”?
【发布时间】:2021-02-12 05:36:04
【问题描述】:

我正在尝试从前端请求通知,但我收到此错误。

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

在代码中,方法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!")
                    });
                }
            }
        }
    };
    

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

【问题讨论】:

  • 你的 get & set requestPermission 方法应该在computed prop里面

标签: javascript laravel vue.js push-notification web-push


【解决方案1】:

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

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 不是响应式的,这就是为什么您需要数据中的属性。

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 2020-07-18
    • 2018-08-26
    • 2018-04-09
    • 2018-05-15
    • 1970-01-01
    • 2021-02-09
    • 2017-06-16
    • 2018-06-22
    相关资源
    最近更新 更多