feat: add pwa install button (#27)
* feat: add pwa tooltip * feat: add pwa install button
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { installPrompt } from './utils/pwa'
|
||||
import { isDark } from '~/composables'
|
||||
// https://github.com/vueuse/head
|
||||
// you can use this to manipulate the document head in any components,
|
||||
@@ -16,6 +17,8 @@ useHead({
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
installPrompt()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@@ -10,6 +10,7 @@ declare module '@vue/runtime-core' {
|
||||
ChooseFood: typeof import('./components/ChooseFood.vue')['default']
|
||||
Counter: typeof import('./components/Counter.vue')['default']
|
||||
DishTag: typeof import('./components/tags/DishTag.vue')['default']
|
||||
InstallPwa: typeof import('./components/InstallPwa.vue')['default']
|
||||
MeatTag: typeof import('./components/tags/MeatTag.vue')['default']
|
||||
Menu: typeof import('./components/Menu.vue')['default']
|
||||
README: typeof import('./components/README.md')['default']
|
||||
|
||||
29
src/components/InstallPwa.vue
Normal file
29
src/components/InstallPwa.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<script lang="ts" setup>
|
||||
import { useAppStore } from '~/stores/app'
|
||||
const app = useAppStore()
|
||||
|
||||
const install = () => {
|
||||
const deferredPrompt = app.deferredPrompt
|
||||
// Show the install prompt
|
||||
deferredPrompt.prompt()
|
||||
// Wait for the user to respond to the prompt
|
||||
deferredPrompt.userChoice.then((choiceResult: any) => {
|
||||
if (choiceResult.outcome === 'accepted')
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('User accepted the install prompt')
|
||||
else
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('User dismissed the install prompt')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Transition>
|
||||
<div v-if="app.deferredPrompt" text="center" m="t-2">
|
||||
<button class="shadow" bg="green-500" p="x-4 y-0" m="2" @click="install">
|
||||
安装
|
||||
</button>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
@@ -25,6 +25,8 @@ title: 帮助
|
||||
- 点击首页最上方的大锅图标,可清空所选食材和工具。
|
||||
- 本项目支持 PWA,使用浏览器打开时,可将其添加到主屏幕以获得近原生 APP 的体验。
|
||||
|
||||
<InstallPwa />
|
||||
|
||||
## FAQ
|
||||
|
||||
### 页面无法点击、资源加载失败?
|
||||
|
||||
4
src/shims.d.ts
vendored
4
src/shims.d.ts
vendored
@@ -1,6 +1,10 @@
|
||||
declare interface Window {
|
||||
// extend the window
|
||||
wx: any
|
||||
/**
|
||||
* pwa install prompt event
|
||||
*/
|
||||
deferredPrompt: Event | any
|
||||
}
|
||||
|
||||
// with vite-plugin-md, markdowns can be treat as Vue components
|
||||
|
||||
12
src/stores/app.ts
Normal file
12
src/stores/app.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { acceptHMRUpdate, defineStore } from 'pinia'
|
||||
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
const deferredPrompt = ref<Event | any>()
|
||||
|
||||
return {
|
||||
deferredPrompt,
|
||||
}
|
||||
})
|
||||
|
||||
if (import.meta.hot)
|
||||
import.meta.hot.accept(acceptHMRUpdate(useAppStore, import.meta.hot))
|
||||
35
src/utils/pwa.ts
Normal file
35
src/utils/pwa.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { isClient } from '@vueuse/core'
|
||||
import { useAppStore } from '~/stores/app'
|
||||
|
||||
/**
|
||||
* https://web.dev/customize-install/#detect-install
|
||||
* @returns
|
||||
*/
|
||||
export function installPrompt() {
|
||||
if (!isClient)
|
||||
return
|
||||
|
||||
const app = useAppStore()
|
||||
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
// Prevent the mini-infobar from appearing on mobile
|
||||
// e.preventDefault()
|
||||
// Stash the event so it can be triggered later.
|
||||
app.deferredPrompt = e
|
||||
// Update UI notify the user they can install the PWA
|
||||
// showInstallPromotion()
|
||||
// Optionally, send analytics event that PWA install promo was shown.
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('\'beforeinstallprompt\' event was fired.')
|
||||
})
|
||||
|
||||
window.addEventListener('appinstalled', () => {
|
||||
// Hide the app-provided install promotion
|
||||
// hideInstallPromotion()
|
||||
// Clear the deferredPrompt so it can be garbage collected
|
||||
app.deferredPrompt = null
|
||||
// Optionally, send analytics event to indicate successful install
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('PWA was installed')
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user