Skip to content

Commit f420359

Browse files
committed
docs: update
1 parent 6407d71 commit f420359

File tree

7 files changed

+311
-55
lines changed

7 files changed

+311
-55
lines changed

packages/@vuepress/theme-blog/components/Home.vue

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,182 @@
1-
# Theme Inheritance
1+
# Theme Inheritance <Badge type="warn" text="beta" />
22

33
## Motivation
44

5+
We have two main reasons to support this feature:
6+
7+
1. VuePress provides users with a [default theme](./default-theme-config.md), which meets the needs of document writers in most scenarios, even so, there are still many users who choose to `eject` and modify, even if they may only need to make minor changes to one of the components.
8+
9+
2. In [0.x](https://vuepress.vuejs.org/guide/custom-themes.html#site-and-page-metadata), only one `Layout.vue` is needed for a theme, so we can achieve simple expansion by directly wrapping `Layout.vue` of another theme.
10+
11+
By 1.x, the elements of a theme has become more complex, we have started to have [theme level configuration](./option-api.md), which supports plugins, custom global layout, etc. In addition, we have also introduced the [directory structure conventions](./writing-a-theme.md#directory-structure) on theme development, such as `styles/index.styl`, under this background, we can not achieve inheritance as 0.x did.
12+
13+
Therefore, we need to provide a reasonable and reliable theme inheritance strategy.
14+
15+
## Concepts
16+
17+
To introduce this section, let's start with a few basic concepts:
18+
19+
- **Atomic theme**:i.e. the parent theme, which is implemented entirely from scratch, like the default theme.
20+
- **Derived theme**:i.e. the child theme, created based on parent theme;
21+
22+
::: tip
23+
For now theme inheritance doesn't support high-level inheritance, that means, a derived topic cannot be inherited.
24+
:::
25+
26+
## Usage
27+
28+
Suppose you want to create a theme inherited from the default theme of VuePress, you just need to configure the [extend](./option-api.md#extend) option in your theme configuration:
29+
30+
```js
31+
module.exports = {
32+
extend: '@vuepress/theme-default'
33+
}
34+
```
35+
36+
## Inheritance Strategy
37+
38+
**All the capabilities of the parent theme will be `"passed"` to the child theme. For file-level conventions, child theme can override it by creating a file with the same name in the same location. For some theme configuration options, such as [globalLayout](./option-api.md/globallayout), child theme can override it by the same name configuration.**
39+
40+
The [file-level agreement](./writing-a-theme.md#directory-structure) at are as follows:
41+
42+
- **Global Components**,i.e. the Vue components under `theme/global-components`.
43+
- **Components**,i.e. the Vue components under `theme/components`.
44+
- **Global Style and Palette**,i.e. `index.styl` and `palette.styl` under `theme/styles`.
45+
- **HTML Template**,i.e. `dev.html` and `ssr.html` under `theme/templates`.
46+
- **Theme-Level App Enhancement File**,i.e. `theme/enhanceApp.js`
47+
48+
For theme configuration, the configuration options that can be overrode by child theme are as follows:
49+
50+
- [devTemplate](./option-api.md#devtemplate)
51+
- [ssrTemplate](./option-api.md#ssrtemplate)
52+
- [globalLayout](./option-api.md#globallayout)
53+
54+
Theme configuration options that cannot be overrode by child theme:
55+
56+
- [extend](./option-api.md#extend)
57+
58+
Theme configuration options requiring special treatment:
59+
60+
- [plugins](./option-api.md#plugins):See [Override Plugins](#override-plugins)
61+
62+
## Override Plugins
63+
64+
For [plugins](./option-api.md#plugins) in the parent theme, the child theme cannot override it intuitively, but the options of plugin can be overrode by creating plugin configuration with the same name.
65+
66+
For example, if the parent theme has the following configuration:
67+
68+
```js
69+
// parentThemePath/index.js
70+
module.exports = {
71+
plugins: [
72+
['@vuepress/search', {
73+
searchMaxSuggestions: 5
74+
}]
75+
]
76+
}
77+
```
78+
79+
The child theme can modify the options of plugin in the following ways:
80+
81+
```js
82+
// themePath/index.js
83+
module.exports = {
84+
plugins: [
85+
['@vuepress/search', {
86+
searchMaxSuggestions: 10
87+
}]
88+
]
89+
}
90+
```
91+
92+
Child theme can even disable it:
93+
94+
```js
95+
// themePath/index.js
96+
module.exports = {
97+
plugins: [
98+
['@vuepress/search', false]
99+
]
100+
}
101+
```
102+
103+
::: warning
104+
Normally, you don't need to do this unless you know clearly that disabling plugins in parent themes won't cause problems.
105+
:::
106+
107+
## Override Components
108+
109+
You may want to override the same-name components in the parent theme. By default, when the components in the parent theme use relative paths to reference other components, you will not be able to do this because you cannot modify the code of the parent theme at run time.
110+
111+
VuePress achieves this requirement in a clever way, but there is a requirement for the parent theme - **All components must use the `@theme` alias to refer to other components**.
112+
113+
For example, if you are developing an atomic theme with the following structure:
114+
115+
::: vue
116+
theme
117+
├── components
118+
│   ├── `Home.vue`
119+
│   ├── `Navbar.vue`
120+
│   └── `Sidebar.vue`
121+
├── layouts
122+
│   ├── `404.vue`
123+
│   └── `Layout.vue`
124+
├── package.json
125+
└── index.js
126+
:::
127+
128+
Then, in any Vue components on the theme, **you should access the theme root directory through `@theme`**:
129+
130+
```vue
131+
<script>
132+
import Home from '@theme/components/Navbar.vue'
133+
// ...
134+
</script>
135+
```
136+
137+
On this premise, when you create a `Navbar` component in the same place in the child theme
138+
139+
::: vue
140+
theme
141+
└── components
142+
   └── `Navbar.vue`
143+
:::
144+
145+
`@theme/components/Navbar.vue` will automatically map to the Navbar component in the child theme. and when you remove the component, `@theme/components/Navbar.vue` will automatically restore to the Navbar component in the parent theme.
146+
147+
In this way, you can easily "tamper" with some part of an atomic theme.
148+
149+
::: tip
150+
1. You'd better override the component based on the code of the corresponding component in the parent theme.
151+
2. Currently, when developing theme locally, you need to manually restart dev serverwhen a component is created or removed.
152+
:::
153+
154+
## Access Parent Theme
155+
156+
You can use `@parent-theme` to access the root path of the parent theme. The following example shows creating a layout component with the same name in a child theme and simply using slots in the parent theme. [@vuepress/theme-vue](https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/theme-vue) is created in this way based on the default theme.
157+
158+
```vue
159+
<!-- themePath/components/Foo.vue -->
160+
<template>
161+
<ParentLayout>
162+
<Foo slot="foo"/>
163+
</ParentLayout>
164+
</template>
165+
166+
<script>
167+
import ParentLayout from '@parent-theme/layouts/Layout.vue'
168+
import Foo from '@theme/components/Foo.vue'
169+
170+
export default {
171+
components: {
172+
ParentLayout,
173+
Foo
174+
}
175+
}
176+
</script>
177+
```
178+
5179

6180

7-
## What is Subject Inheritance?
8181

9182

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,33 @@
11
---
2-
metaTitle: Option API | Theme
2+
metaTitle: Configuration | Theme
33
---
44

5-
# Option API
5+
# Theme Configuration
6+
7+
As with plugins, the theme configuration file `themeEntry` should export a `plain JavaScript object`(`#1`). If the plugin needs to take options, it can be a function that exports a plain object(`#2`). The function will be called with the `siteConfig.themeConfig` as the first argument, along with [ctx](./context-api.md) which provides some compile-time metadata.
8+
9+
``` js
10+
// #1
11+
module.exports = {
12+
// ...
13+
}
14+
```
15+
16+
``` js
17+
// #2
18+
module.exports = (themeConfig, ctx) => {
19+
return {
20+
// ...
21+
}
22+
}
23+
```
24+
25+
26+
::: tip
27+
1. You should see the difference between `themeEntry` and `themeConfig`, the former is a configuration for ths theme itself, which is provided by VuePress. the latter is the user's configuration for the theme, which is implemented by the currently used theme, e.g. [Default Theme Config](./default-theme-config.md).
28+
29+
2. In addition to the options listed in this section, `themeEntry` also supports all [Option API](../plugin/option-api.md) and [Life Cycle](../plugin/life-cycle.md) supported by plugins.
30+
:::
631

732
## plugins
833

@@ -11,9 +36,33 @@ metaTitle: Option API | Theme
1136

1237
**Also see:**
1338

14-
- [Plugin > Using a plugin](../plugin/using-a-plugin.md).
39+
- [Plugin > Using a Plugin](../plugin/using-a-plugin.md).
1540

16-
## extend
41+
---
42+
43+
::: warning
44+
You probably don't need to use following options tagged with <Badge text="Danger Zone" vertical="middle"/> unless you know what you are doing!
45+
:::
46+
47+
## devTemplate <Badge text="Danger Zone"/>
48+
49+
- Type: `String`
50+
- Default: undefined
51+
52+
HTML template path used in `dev` mode, default template see [here](https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/core/lib/app/index.dev.html)
53+
54+
## ssrTemplate <Badge text="Danger Zone"/>
55+
56+
- Type: `String`
57+
- Default: undefined
58+
59+
HTML template path used in `build` mode, default template see [here](https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/core/lib/app/index.ssr.html)
60+
61+
**Also see:**
62+
63+
- [Vue SSR Guide > template](https://ssr.vuejs.org/api/#template).
64+
65+
## extend <Badge text="Danger Zone"/>
1766

1867
- Type: `String`
1968
- Default: undefined
@@ -24,12 +73,52 @@ module.exports = {
2473
}
2574
```
2675

27-
VuePress supports a theme to be inherited from another theme. VuePress will follow the principle of `override` to automatically help you resolve the priorities of various theme attributes, such as styles, layout components.
28-
29-
Note that in the child theme, VuePress will apply a `@parent-theme` [alias](../plugin/option-api.md#alias) pointing to the package directory of parent theme.
76+
VuePress provides the ability to inherit one theme from another. VuePress will follow the concept of `override` and automatically help you prioritize various thematic attributes, e.g. styles and layout components.
3077

3178
**Also see:**
3279

33-
- [Example: `@vuepress/theme-vue`](https://github.com/vuejs/vuepress/tree/master/packages/@vuepress/theme-vue)
34-
- [Design Concepts of VuePress 1.x](../miscellaneous/design-concepts.md)
80+
- [Theme Inheritance](./inheritance.md)
81+
- [VuePress 1.x 的设计理念](../miscellaneous/design-concepts.md)
82+
83+
## globalLayout <Badge text="Danger Zone"/>
84+
85+
- Type: `String`
86+
- Default: undefined
87+
88+
```js
89+
// themePath/index.js
90+
module.exports = {
91+
globalLayout: '/path/to/your/global/vue/sfc'
92+
}
93+
```
94+
95+
Global layout component is a component responsible for the global layout strategy. The [default global layout](https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/core/lib/app/components/GlobalLayout.vue) will help you render different layouts according to [$frontmatter.layout](../guide/frontmatter.md#layout), so in most cases you do not need to configure this option.
96+
97+
For example, when you want to set a global header and footer for your theme, you can do this:
98+
99+
```vue
100+
<!-- themePath/layouts/GlobalLayout.vue -->
101+
<template>
102+
<div id="global-layout">
103+
<header><h1>Header</h1></header>
104+
<component :is="layout"/>
105+
<footer><h1>Footer</h1></footer>
106+
</div>
107+
</template>
35108
109+
<script>
110+
export default {
111+
computed: {
112+
layout () {
113+
if (this.$page.path) {
114+
if (this.$vuepress.isLayoutExists(this.$frontmatter.layout)) {
115+
return this.$frontmatter.layout
116+
}
117+
return 'Layout'
118+
}
119+
return 'NotFound'
120+
}
121+
}
122+
}
123+
</script>
124+
```

packages/docs/docs/theme/using-a-theme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module.exports = {
1414

1515
## Theme Shorthand
1616

17-
If you prefix the plugin with `vuepress-theme-`, you can use a shorthand to leave out that prefix:
17+
If you prefix the theme with `vuepress-theme-`, you can use a shorthand to leave out that prefix:
1818

1919
``` js
2020
module.exports = {
@@ -47,5 +47,5 @@ module.exports = {
4747
```
4848

4949
::: warning Note
50-
The plugin whose name starts with `@vuepress/theme-` is an officially maintained theme.
50+
The theme whose name starts with `@vuepress/theme-` is an officially maintained theme.
5151
:::

0 commit comments

Comments
 (0)