Skip to content

Commit fe64607

Browse files
release: v2.8.2
2 parents 440718f + 5edbfe8 commit fe64607

14 files changed

+292
-197
lines changed

.vitepress/config.js

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ module.exports = {
1313
['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }],
1414
['script', { src: 'https://cdn.wwads.cn/js/makemoney.js', async: '' }]
1515
],
16+
vue: {
17+
reactivityTransform: true
18+
},
1619
themeConfig: {
1720
repo: pkg.repository,
1821
logo: '/logo.svg',

.vitepress/theme/SponsorsGroup.vue

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<script lang="ts">
2+
// shared data across instances so we load only once
3+
let data = $ref<SponsorData>()
4+
5+
const base = `https://sponsors.vuejs.org`
6+
const dataUrl = `${base}/vite.json`
7+
</script>
8+
9+
<script setup lang="ts">
10+
import { onMounted, onUnmounted } from 'vue'
11+
12+
interface Sponsor {
13+
url: string
14+
img: string
15+
name: string
16+
}
17+
18+
interface SponsorData {
19+
special: Sponsor[]
20+
platinum: Sponsor[]
21+
platinum_china: Sponsor[]
22+
gold: Sponsor[]
23+
silver: Sponsor[]
24+
bronze: Sponsor[]
25+
}
26+
27+
const { tier, placement = 'aside' } = defineProps<{
28+
tier: keyof SponsorData
29+
placement?: 'aside' | 'page' | 'landing'
30+
}>()
31+
32+
let container = $ref<HTMLElement>()
33+
let visible = $ref(false)
34+
35+
onMounted(async () => {
36+
// only render when entering view
37+
const observer = new IntersectionObserver(
38+
(entries) => {
39+
if (entries[0].isIntersecting) {
40+
visible = true
41+
observer.disconnect()
42+
}
43+
},
44+
{ rootMargin: '0px 0px 300px 0px' }
45+
)
46+
observer.observe(container)
47+
onUnmounted(() => observer.disconnect())
48+
49+
// load data
50+
if (!data) {
51+
data = await (await fetch(dataUrl)).json()
52+
}
53+
})
54+
</script>
55+
56+
<template>
57+
<div
58+
ref="container"
59+
class="sponsor-container"
60+
:class="[tier.startsWith('plat') ? 'platinum' : tier, placement]"
61+
>
62+
<template v-if="data && visible">
63+
<a
64+
v-for="{ url, img, name } of data[tier]"
65+
class="sponsor-item"
66+
:href="url"
67+
target="_blank"
68+
rel="sponsored noopener"
69+
>
70+
<picture v-if="img.endsWith('png')">
71+
<source
72+
type="image/avif"
73+
:srcset="`${base}/images/${img.replace(/\.png$/, '.avif')}`"
74+
/>
75+
<img :src="`${base}/images/${img}`" :alt="name" />
76+
</picture>
77+
<img v-else :src="`${base}/images/${img}`" :alt="name" />
78+
</a>
79+
</template>
80+
</div>
81+
</template>
82+
83+
<style scoped>
84+
.sponsor-container {
85+
--max-width: 100%;
86+
display: flex;
87+
justify-content: space-evenly;
88+
flex-wrap: wrap;
89+
}
90+
91+
.sponsor-container.platinum {
92+
--max-width: 260px;
93+
}
94+
.sponsor-container.gold {
95+
--max-width: 160px;
96+
}
97+
.sponsor-container.silver {
98+
--max-width: 140px;
99+
}
100+
101+
.sponsor-item {
102+
margin: 2px 0;
103+
display: flex;
104+
align-items: center;
105+
border-radius: 2px;
106+
transition: background-color 0.2s ease;
107+
height: calc(var(--max-width) / 2 - 6px);
108+
}
109+
.sponsor-item.action {
110+
font-size: 11px;
111+
color: #999;
112+
}
113+
.sponsor-item img {
114+
width: 100%;
115+
max-width: calc(var(--max-width) - 30px);
116+
max-height: calc(var(--max-width) / 2 - 20px);
117+
margin: 10px 20px;
118+
}
119+
.special .sponsor-item {
120+
height: 160px;
121+
}
122+
.special .sponsor-item img {
123+
max-width: 300px;
124+
max-height: 150px;
125+
}
126+
127+
/* aside mode (on content pages) */
128+
.sponsor-container.platinum.aside {
129+
--max-width: 200px;
130+
}
131+
.sponsor-container.gold.aside {
132+
--max-width: 124px;
133+
}
134+
.aside .sponsor-item {
135+
margin: 0;
136+
}
137+
</style>

.vitepress/theme/SponsorsSidebar.vue

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script setup lang="ts">
2+
import SponsorsGroup from './SponsorsGroup.vue'
3+
import { useData } from 'vitepress'
4+
const { frontmatter } = useData()
5+
</script>
6+
7+
<template>
8+
<div v-if="frontmatter.sponsors !== false">
9+
<a
10+
class="sponsors-aside-text"
11+
href="https://github.com/sponsors/yyx990803"
12+
target="_blank"
13+
>Sponsors</a
14+
>
15+
<SponsorsGroup tier="platinum" />
16+
<SponsorsGroup tier="gold" />
17+
</div>
18+
</template>
19+
20+
<style>
21+
a.sponsors-aside-text {
22+
color: #999;
23+
display: block;
24+
margin: 3em 0 1em;
25+
font-weight: 700;
26+
font-size: 11px;
27+
text-transform: uppercase;
28+
letter-spacing: 0.4px;
29+
padding-left: 2em;
30+
}
31+
</style>

.vitepress/theme/index.js

+2-35
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,14 @@
11
import Theme from 'vitepress/theme'
22
import { h } from 'vue'
3-
import sponsors from './sponsors.json'
4-
import './sponsors.css'
3+
import SponsorsSidebar from './SponsorsSidebar.vue'
54
import './custom.css'
65

76
export default {
87
...Theme,
98
Layout() {
109
return h(Theme.Layout, null, {
1110
'sidebar-bottom': () =>
12-
h('div', { class: 'sponsors sidebar' }, [
13-
h(
14-
'a',
15-
{
16-
href: 'https://github.com/sponsors/yyx990803',
17-
target: '_blank',
18-
rel: 'noopener'
19-
},
20-
[h('span', 'Sponsors')]
21-
),
22-
...sponsors.map(({ href, src, name, id }) =>
23-
h(
24-
'a',
25-
{
26-
href,
27-
target: '_blank',
28-
rel: 'noopener',
29-
'aria-label': 'sponsor-img'
30-
},
31-
[h('img', { src, alt: name, id: `sponsor-${id}` })]
32-
)
33-
)
34-
]),
35-
'page-top-ads': () =>
36-
h('div', { id: 'wwads-container' }, [
37-
h('div', {
38-
class: 'wwads-cn wwads-vertical',
39-
'data-id': 111,
40-
style: {
41-
maxWidth: '150px'
42-
}
43-
})
44-
])
11+
h('div', { class: 'sponsors sidebar' }, [h(SponsorsSidebar)])
4512
})
4613
}
4714
}

.vitepress/theme/sponsors.css

-56
This file was deleted.

.vitepress/theme/sponsors.json

-45
This file was deleted.

config/index.md

+11-5
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,11 @@ export default defineConfig(async ({ command, mode }) => {
477477
configure: (proxy, options) => {
478478
// proxy 是 'http-proxy' 的实例
479479
}
480+
},
481+
// Proxying websockets or socket.io
482+
'/socket.io': {
483+
target: 'ws://localhost:3000',
484+
ws: true
480485
}
481486
}
482487
}
@@ -587,6 +592,7 @@ createServer()
587592

588593
-`package.json` 中包含 `workspaces` 字段
589594
- 包含以下几种文件之一
595+
- `lerna.json`
590596
- `pnpm-workspace.yaml`
591597

592598
接受一个路径作为自定义工作区的 root 目录。可以是绝对路径或是相对于 [项目 root 目录](/guide/#index-html-and-project-root) 的相对路径。示例如下:
@@ -761,19 +767,19 @@ export default defineConfig({
761767

762768
### build.manifest {#build-manifest}
763769

764-
- **类型:** `boolean`
770+
- **类型:** `boolean | string`
765771
- **默认:** `false`
766772
- **相关内容:** [后端集成](/guide/backend-integration)
767773

768-
当设置为 `true`,构建后将会生成 `manifest.json` 文件,包含了没有被 hash 的资源文件名和 hash 后版本的映射。可以为一些服务器框架渲染时提供正确的资源引入链接。
774+
当设置为 `true`,构建后将会生成 `manifest.json` 文件,包含了没有被 hash 过的资源文件名和 hash 后版本的映射。可以为一些服务器框架渲染时提供正确的资源引入链接。当该值为一个字符串时,它将作为 manifest 文件的名字
769775

770776
### build.ssrManifest {#build-ssrmanifest}
771777

772-
- **类型:** `boolean`
778+
- **类型:** `boolean | string`
773779
- **默认值:** `false`
774-
- **相关链接:** [Server-Side Rendering](/guide/ssr)
780+
- **相关链接:** [服务端渲染](/guide/ssr)
775781

776-
当设置为 `true` 时,构建也将生成 SSR 的 manifest 文件,以确定生产中的样式链接与资产预加载指令。
782+
当设置为 `true` 时,构建也将生成 SSR 的 manifest 文件,以确定生产中的样式链接与资产预加载指令。当该值为一个字符串时,它将作为 manifest 文件的名字。
777783

778784
### build.ssr {#build-ssr}
779785

0 commit comments

Comments
 (0)