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

Posted

技术标签:

【中文标题】如何解决 Vue.js 中的“属性或方法未在实例上定义但在渲染期间引用..”?【英文标题】:How to resolve "Property or method is not defined on the instance but referenced during render.. " in 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里面 【参考方案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 不是响应式的,这就是为什么您需要数据中的属性。

【讨论】:

以上是关于如何解决 Vue.js 中的“属性或方法未在实例上定义但在渲染期间引用..”?的主要内容,如果未能解决你的问题,请参考以下文章

[Vue 警告]:属性或方法未在实例上定义,但在渲染期间引用

属性或方法...未在实例上定义,但在渲染期间引用

“属性或方法未在实例上定义,但在渲染期间引用”

Vue属性或方法未在实例上定义但在渲染期间引用?

VueJS:属性或方法......未在实例上定义,但在渲染期间引用

(Vuejs)属性或方法未在实例上定义,但在渲染期间引用