从组件延迟安装 pwa

Install pwa from a component with delay

我创建了一个 v-dialog 组件,它会在我的 webapp 加载时出现并用于安装 PWA:

<template>
    <div>
         <v-dialog
            v-model="popupAndroid"
            max-width="80%"
            >
            <v-card color="background">
                <v-card-title class="headline" style="word-break: normal !important;"
                >Add the {{nombreFarmacia}} app to your desktop.</v-card-title>

                <v-card-text>
                For a better experience add the {{nombreFarmacia}} app to your desktop.
                </v-card-text>

                <v-card-actions>
                    <v-spacer></v-spacer>

                    <v-btn @click="dismiss">Cancelar</v-btn>

                    <v-btn @click="install" color="primary" class="textoMenu--text">Aceptar</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>
        <v-dialog
            v-model="popupIos"
            max-width="80%"
            >
            <v-card color="background" class="pico">
                <v-card-title class="headline" style="text-align: center; word-break: normal !important;"
                >Add the {{nombreFarmacia}} app to your desktop.</v-card-title>

                <v-card-text>
                For a better experience add the {{nombreFarmacia}} app to your desktop install {{nombreFarmacia}} in your iPhone.
                Press<br><img style="display:block; margin: 0 auto" src="boton-opciones-ios-min.png" width="40" height="40"><br> then "Add to start".
                </v-card-text>

                <v-card-actions>
                    <v-spacer></v-spacer>
                    <v-btn @click="dismiss" color="primary" class="textoMenu--text">Ok</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>
    </div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
    name: "DialogInstalacion",
    data() {
        return {
        popupAndroid: null,
        popupIos: null,
        deferredPrompt: null,
        nombreFarmacia: "",
        userAgent: "",
        };
    },
    created() {
        // Android / desktop
        this.nombreFarmacia = this.$store.getters.getFarmacia.nombre;
        window.addEventListener("beforeinstallprompt", e => {
            e.preventDefault();
            // Stash the event so it can be triggered later.
            this.deferredPrompt = e;
            //console.log(e.platforms);
            this.popupAndroid = true
            //e.prompt()
        // Update UI notify the user they can install the PWA
        });
        window.addEventListener("appinstalled", () => {
            this.popupAndroid = null;
        });

        //iOS
        // Detects if device is on iOS
        const isIos = () => {
            const userAgent = window.navigator.userAgent.toLowerCase();
            return /iphone|ipad|ipod/.test( userAgent );
        }

        const isInStandaloneMode = () => ('standalone' in window.navigator) && (window.navigator.standalone);

        // Checks if should display install popup notification:
        if (isIos() && !isInStandaloneMode()) {
            //this.setState({ showInstallMessage: true });
            this.popupIos = true;
        }
    },
    methods: {
        dismiss() {
        this.popupAndroid = null;
        this.popupIos = null;
        },
        install() {
        this.popupAndroid = null
        this.deferredPrompt.prompt();
        }
    }
};
</script>

到目前为止一切都是正确的。加载主网站后,该组件也会随之加载,并出现 ios/android/desktop 的相应提示。出现我的问题是因为我需要这个提示延迟出现。为此,我尝试在创建的方法中执行以下操作:

created() {
        //Android / desktop
        this.nombreFarmacia = this.$store.getters.getFarmacia.nombre;
        window.addEventListener("beforeinstallprompt", e => {
            e.preventDefault();
            // Stash the event so it can be triggered later.
            this.deferredPrompt = e;
            //console.log(e.platforms);
            setTimeout(function () {
                this.popupAndroid = true
            },10000)
            ...

...但提示不会以这种方式出现。

问题是您丢失了 this 的正确上下文。您没有将箭头函数传递给 setTimeout,因此 this 将是 windowundefined(取决于严格模式)。不管怎样,你应该改变你的代码:

setTimeout(() => { this.popupAndroid = true }, 10000)

或绑定您的函数:

setTimeout(function() { this.popupAndroid = true }.bind(this), 10000)