从组件延迟安装 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
将是 window
或 undefined
(取决于严格模式)。不管怎样,你应该改变你的代码:
setTimeout(() => { this.popupAndroid = true }, 10000)
或绑定您的函数:
setTimeout(function() { this.popupAndroid = true }.bind(this), 10000)
我创建了一个 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
将是 window
或 undefined
(取决于严格模式)。不管怎样,你应该改变你的代码:
setTimeout(() => { this.popupAndroid = true }, 10000)
或绑定您的函数:
setTimeout(function() { this.popupAndroid = true }.bind(this), 10000)