docs: ✏️ 优化演示demo支持在顶部显示对应页面微信小程序的二维码

This commit is contained in:
Moonofweisheng 2024-12-14 13:49:11 +08:00
parent 7ed7dd3495
commit b1f42af640
83 changed files with 253 additions and 16 deletions

119
build/qrcode.js Normal file
View File

@ -0,0 +1,119 @@
// 调用微信api生成每个页面的小程序码使用axios发起请求
const fs = require('fs')
const path = require('path')
const axios = require('axios')
const JSON5 = require('json5') // 引入 json5 库
const appID = process.argv[process.argv.indexOf('--APP_ID') + 1] // 在 --APP_ID 后面
const appSecret = process.argv[process.argv.indexOf('--APP_SECRET') + 1] // --APP_SECRET 后面
// 获取 access_token 的函数
async function getAccessToken() {
const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appID}&secret=${appSecret}`
try {
const response = await axios.get(url)
return response.data.access_token
} catch (error) {
console.error(`获取 access_token 失败: ${error.response ? error.response.data : error.message}`)
throw error // 抛出错误以便后续处理
}
}
// 读取 pages.json 文件
const pagesJsonPath = path.join(__dirname, '../src/pages.json') // 计算 pages.json 的路径
let pagesJson
try {
const jsonData = fs.readFileSync(pagesJsonPath, 'utf8')
pagesJson = JSON5.parse(jsonData) // 使用 json5 解析带注释的 JSON
} catch (error) {
console.error(`读取或解析 pages.json 失败: ${error.message}`)
process.exit(1) // 退出程序
}
const pages = pagesJson.pages.filter((page) => page.path.endsWith('Index'))
// 将驼峰命名法转换为小写短横线连接的函数
function camelToKebabCase(str) {
return str
.replace(/([a-z])([A-Z])/g, '$1-$2') // 在小写字母和大写字母之间插入短横线
.replace(/([A-Z])/g, '-$1') // 在大写字母前插入短横线
.replace(/--+/g, '-') // 替换多个短横线为一个短横线
.replace(/^-|-$/g, '') // 去掉开头和结尾的短横线
.toLowerCase() // 转换为小写
}
// 删除 wxqrcode 目录及其内容
function clearWxqrcodeDirectory(outputDir) {
if (fs.existsSync(outputDir)) {
fs.rmSync(outputDir, { recursive: true, force: true }) // 递归删除目录及其内容
console.log(`已删除目录: ${outputDir}`)
}
}
// 生成小程序码的函数
async function generateMiniProgramCode(accessToken, pagePath, retries = 3) {
const url = `https://api.weixin.qq.com/wxa/getwxacode?access_token=${accessToken}`
const data = {
path: pagePath,
width: 430 // 小程序码的宽度,可以根据需要调整
}
for (let attempt = 1; attempt <= retries; attempt++) {
try {
const response = await axios.post(url, data, {
responseType: 'arraybuffer' // 以二进制形式接收图片数据
})
// 确保输出目录存在
const outputDir = path.join(__dirname, '../docs/public/wxqrcode')
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true }) // 创建目录及其父目录
}
// 提取组件名并转换格式
const componentName = pagePath.split('/')[1] // 假设路径格式为 pages/组件名/Index
const formattedName = camelToKebabCase(componentName) // 转换为小写短横线连接
// 将返回的图片数据保存为文件
const fileName = path.join(outputDir, `${formattedName}.png`) // 生成文件名
fs.writeFileSync(fileName, response.data)
console.log(`小程序码已生成并保存为 ${fileName}`)
return // 成功后退出函数
} catch (error) {
console.error(`生成小程序码失败: ${error.response ? error.response.data : error.message}`)
if (attempt < retries) {
console.log(`重试 ${attempt}/${retries}...`)
} else {
console.error(`所有重试均失败,无法生成小程序码: ${pagePath}`)
}
}
}
}
// 遍历每个页面并生成小程序码
async function generateCodesForAllPages(accessToken) {
for (const page of pages) {
await generateMiniProgramCode(accessToken, page.path)
}
}
// 生成二维码图片
async function genrateQRCodeImage() {
const outputDir = path.join(__dirname, '../docs/public/wxqrcode')
// 在开始生成小程序码之前清空 wxqrcode 目录
clearWxqrcodeDirectory(outputDir)
try {
const accessToken = await getAccessToken()
await generateCodesForAllPages(accessToken)
} catch (error) {
console.error('程序执行失败:', error.message)
}
}
// 生成小程序二维码图片 pnpm qrcode -- --APP_ID xxx --APP_SECRET xxx
genrateQRCodeImage()

View File

@ -0,0 +1,48 @@
<template>
<div @mouseenter="showQRCode = true" @mouseleave="showQRCode = false">
<el-tooltip
placement="bottom"
effect="light"
:visible="showQRCode"
:popper-options="{ modifiers: [{ name: 'offset', options: { offset: [0, 20] } }] }"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
>
<path fill="currentColor" d="M2 2h9v9H2zm2 2v5h5V4zm9-2h9v9h-9zm2 2v5h5V4zM5.5 5.5h2.004v2.004H5.5zm11 0h2.004v2.004H16.5zm-3.504 7.496H15V15h-2.004zm7 0H22V15h-2.004zM2 13h9v9H2zm2 2v5h5v-5zm11.996.996H18v2h2v2h2V22h-2.004v-2h-2v-2h-2zM5.5 16.5h2.004v2.004H5.5zm7.496 3.496H15V22h-2.004z"></path>
</svg>
<template #content>
<div class="qr-code">
<img :src="src" alt="二维码" />
</div>
</template>
</el-tooltip>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ElTooltip } from 'element-plus';
interface Props {
/** 二维码资源 */
src: string
}
const props = withDefaults(defineProps<Props>(), {
src: ''
})
const showQRCode = ref(false);
</script>
<style scoped>
.qr-code {
width: 130px; /* 设置二维码的宽度 */
height: auto; /* 高度自适应 */
transition: opacity 0.3s ease; /* 添加过渡效果 */
}
</style>

View File

@ -8,13 +8,14 @@
<div class="demo-header">
<ExternalLink :href="href" class="demo-link" :style="`${expanded ? '' : 'height:0;width:0;opacity:0'}`">
</ExternalLink>
<QrCode class="demo-qrcode" :src="qrcode" v-if="expanded&&qrcode"></QrCode>
<el-icon class="expand-icon" style="cursor: pointer;" @click="toggleExpand">
<component :is="expanded ? Fold : Expand" />
</el-icon>
</div>
<!-- iframe 容器 -->
<div class="iframe-container">
<iframe v-if="expanded" ref="iframe" id="demo" class="iframe" scrolling="auto" frameborder="0" :src="href" />
<iframe v-if="expanded&&transitionEnd" ref="iframe" id="demo" class="iframe" scrolling="auto" frameborder="0" :src="href" />
</div>
</div>
</template>
@ -23,6 +24,8 @@
import { Expand, Fold } from '@element-plus/icons-vue'
import { useRoute, useData } from 'vitepress'
import { computed, onMounted, ref, watch } from 'vue'
import QrCode from './QrCode.vue'
interface Props {
/** 是否展开状态 */
expanded?: boolean
@ -35,7 +38,7 @@ const props = withDefaults(defineProps<Props>(), {
//
const baseUrl = ref('')
const iframe = ref<HTMLIFrameElement | null>(null)
const transitionEnd = ref(false)
const transitionEnd = ref(true)
const emit = defineEmits<{
'update:expanded': [boolean] //
@ -54,6 +57,13 @@ const href = computed(() => {
return baseUrl.value + `pages/${kebabToCamel(paths[paths.length - 1])}/Index`
})
const qrcode = computed(() => {
const path = route.path
const paths = path ? path.split('.')[0].split('/') : []
if (!paths.length) return ''
return `/wxqrcode/${kebabToCamel(paths[paths.length - 1])}.png`
})
// kebab-case camelCase
function kebabToCamel(input: string): string {
return input.replace(/-([a-z])/g, (match, group) => group.toUpperCase())
@ -74,17 +84,13 @@ function toggleExpand() {
//
emit('update:expanded', !props.expanded)
emit('state-change', !props.expanded)
if (props.expanded) {
transitionEnd.value = false
}
transitionEnd.value = false
}
//
function onTransitionEnd() {
if (!props.expanded) {
transitionEnd.value = true
}
transitionEnd.value = true
}
// iframe
@ -180,6 +186,16 @@ watch(
color: var(--color);
}
.demo-qrcode{
font-size: 28px !important;
transition: all 0.3s ease-in-out;
position: absolute;
left: calc(50% - 14px);
--color: inherit;
fill: currentColor;
color: var(--color);
}
.expand-icon {
position: absolute;
right: 8px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -55,7 +55,8 @@
"compiler": "npm run clean:lib && node build/compiler.js",
"upload:mp-weixin": "uni build -p mp-weixin && minici --platform weixin",
"upload:mp-alipay": "uni build -p mp-alipay && minici --platform alipay",
"upload:mp-dingtalk": "uni build -p mp-dingtalk && minici --platform dd"
"upload:mp-dingtalk": "uni build -p mp-dingtalk && minici --platform dd",
"qrcode": "node build/qrcode.js"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-4020420240722002",
@ -97,6 +98,7 @@
"@vue/runtime-core": "^3.4.38",
"@vue/tsconfig": "^0.1.3",
"@vueuse/core": "^12.0.0",
"axios": "^1.7.9",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.7.0",
"eslint-plugin-prettier": "^4.2.1",
@ -104,6 +106,7 @@
"git-cz": "^4.9.0",
"husky": "^8.0.3",
"inquirer": "8.0.0",
"json5": "^2.2.3",
"lint-staged": "^13.2.0",
"mini-types": "^0.1.7",
"miniprogram-api-typings": "^3.12.3",

52
pnpm-lock.yaml generated
View File

@ -120,6 +120,9 @@ importers:
'@vueuse/core':
specifier: ^12.0.0
version: 12.0.0(typescript@5.5.4)
axios:
specifier: ^1.7.9
version: 1.7.9
eslint:
specifier: ^8.36.0
version: 8.36.0
@ -141,6 +144,9 @@ importers:
inquirer:
specifier: 8.0.0
version: 8.0.0
json5:
specifier: ^2.2.3
version: 2.2.3
lint-staged:
specifier: ^13.2.0
version: 13.2.0
@ -188,7 +194,7 @@ importers:
version: 5.4.11(@types/node@18.15.3)(sass@1.59.3)(terser@5.16.6)
vitepress:
specifier: ^1.5.0
version: 1.5.0(@algolia/client-search@5.15.0)(@types/node@18.15.3)(async-validator@4.2.5)(postcss@8.4.49)(sass@1.59.3)(search-insights@2.13.0)(terser@5.16.6)(typescript@5.5.4)
version: 1.5.0(@algolia/client-search@5.15.0)(@types/node@18.15.3)(async-validator@4.2.5)(axios@1.7.9)(postcss@8.4.49)(sass@1.59.3)(search-insights@2.13.0)(terser@5.16.6)(typescript@5.5.4)
vitest:
specifier: ^0.30.1
version: 0.30.1(jsdom@16.7.0)(sass@1.59.3)(terser@5.16.6)
@ -2728,6 +2734,9 @@ packages:
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
engines: {node: '>= 0.4'}
axios@1.7.9:
resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
babel-jest@27.5.1:
resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@ -3669,6 +3678,15 @@ packages:
focus-trap@7.6.2:
resolution: {integrity: sha512-9FhUxK1hVju2+AiQIDJ5Dd//9R2n2RAfJ0qfhF4IHGHgcoEUTMpbTeG/zbEuwaiYXfuAH6XE0/aCyxDdRM+W5w==}
follow-redirects@1.15.9:
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@ -3676,6 +3694,10 @@ packages:
resolution: {integrity: sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==}
engines: {node: '>= 6'}
form-data@4.0.1:
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
engines: {node: '>= 6'}
forwarded@0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
@ -5181,6 +5203,9 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
psl@1.15.0:
resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
@ -9663,13 +9688,14 @@ snapshots:
- '@vue/composition-api'
- vue
'@vueuse/integrations@11.3.0(async-validator@4.2.5)(focus-trap@7.6.2)(vue@3.5.13(typescript@5.5.4))':
'@vueuse/integrations@11.3.0(async-validator@4.2.5)(axios@1.7.9)(focus-trap@7.6.2)(vue@3.5.13(typescript@5.5.4))':
dependencies:
'@vueuse/core': 11.3.0(vue@3.5.13(typescript@5.5.4))
'@vueuse/shared': 11.3.0(vue@3.5.13(typescript@5.5.4))
vue-demi: 0.14.10(vue@3.5.13(typescript@5.5.4))
optionalDependencies:
async-validator: 4.2.5
axios: 1.7.9
focus-trap: 7.6.2
transitivePeerDependencies:
- '@vue/composition-api'
@ -9857,6 +9883,14 @@ snapshots:
available-typed-arrays@1.0.5: {}
axios@1.7.9:
dependencies:
follow-redirects: 1.15.9
form-data: 4.0.1
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
babel-jest@27.5.1(@babel/core@7.25.2):
dependencies:
'@babel/core': 7.25.2
@ -10995,6 +11029,8 @@ snapshots:
dependencies:
tabbable: 6.2.0
follow-redirects@1.15.9: {}
for-each@0.3.3:
dependencies:
is-callable: 1.2.7
@ -11005,6 +11041,12 @@ snapshots:
combined-stream: 1.0.8
mime-types: 2.1.35
form-data@4.0.1:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
forwarded@0.2.0: {}
fraction.js@4.3.7: {}
@ -12686,6 +12728,8 @@ snapshots:
forwarded: 0.2.0
ipaddr.js: 1.9.1
proxy-from-env@1.1.0: {}
psl@1.15.0:
dependencies:
punycode: 2.3.1
@ -13613,7 +13657,7 @@ snapshots:
sass: 1.59.3
terser: 5.16.6
vitepress@1.5.0(@algolia/client-search@5.15.0)(@types/node@18.15.3)(async-validator@4.2.5)(postcss@8.4.49)(sass@1.59.3)(search-insights@2.13.0)(terser@5.16.6)(typescript@5.5.4):
vitepress@1.5.0(@algolia/client-search@5.15.0)(@types/node@18.15.3)(async-validator@4.2.5)(axios@1.7.9)(postcss@8.4.49)(sass@1.59.3)(search-insights@2.13.0)(terser@5.16.6)(typescript@5.5.4):
dependencies:
'@docsearch/css': 3.8.0
'@docsearch/js': 3.8.0(@algolia/client-search@5.15.0)(search-insights@2.13.0)
@ -13626,7 +13670,7 @@ snapshots:
'@vue/devtools-api': 7.6.7
'@vue/shared': 3.5.13
'@vueuse/core': 11.3.0(vue@3.5.13(typescript@5.5.4))
'@vueuse/integrations': 11.3.0(async-validator@4.2.5)(focus-trap@7.6.2)(vue@3.5.13(typescript@5.5.4))
'@vueuse/integrations': 11.3.0(async-validator@4.2.5)(axios@1.7.9)(focus-trap@7.6.2)(vue@3.5.13(typescript@5.5.4))
focus-trap: 7.6.2
mark.js: 8.11.1
minisearch: 7.1.1

View File

@ -25,7 +25,7 @@
<wd-notify />
<wd-toast />
<!-- #ifdef MP-WEIXIN -->
<wd-fab v-model:active="fabActive" draggable type="error" :gap="{ bottom: 58 }" v-if="enableRewardFab">
<wd-fab v-model:active="fabActive" draggable type="error" :gap="{ bottom: 58 }" direction="left" v-if="enableRewardFab">
<wd-button type="error" round @click="goToReward">
<view style="display: flex; align-items: center">
<wd-icon name="thumb-up" size="22px"></wd-icon>
@ -72,8 +72,8 @@ const darkMode = useDark()
const { closeOutside } = useQueue()
const isDark = ref<boolean>(false)
const isRed = ref<boolean>(false)
const fabActive = ref<boolean>(false)
// #ifdef MP-WEIXIN
const fabActive = ref<boolean>(false)
// 广广广广广
const showWxAd = ref<boolean>(Math.random() > 0.5) // 广
const showWxAd2 = ref<boolean>(Math.random() > 0.33) // 广
@ -111,6 +111,13 @@ onMounted(() => {
})
}
if (enableRewardFab.value) {
const timer = setTimeout(() => {
clearTimeout(timer)
fabActive.value = true
}, 500)
}
// #endif
})
</script>