1 | ![@nuxt/components](https://user-images.githubusercontent.com/904724/99790294-2f75d300-2b24-11eb-8114-0a2569913fae.png)
|
2 |
|
3 | # @nuxt/components
|
4 |
|
5 | [![npm version][npm-version-src]][npm-version-href]
|
6 | [![npm downloads][npm-downloads-src]][npm-downloads-href]
|
7 | [![Github Actions CI][github-actions-ci-src]][github-actions-ci-href]
|
8 | [![Codecov][codecov-src]][codecov-href]
|
9 | [![License][license-src]][license-href]
|
10 |
|
11 | > Module to scan and auto import components for Nuxt 2.13+
|
12 |
|
13 | - [🎲 Play on CodeSandbox](https://githubbox.com/nuxt/components/tree/master/example)
|
14 | - [🎬 Demonstration video (49s)](https://www.youtube.com/watch?v=lQ8OBrgVVr8)
|
15 | - [📖 Release Notes](./CHANGELOG.md)
|
16 |
|
17 | ## Table of Contents
|
18 |
|
19 | - [Features](#features)
|
20 | - [Usage](#usage)
|
21 | - [Dynamic Components](#dynamic-components)
|
22 | - [Lazy Imports](#lazy-imports)
|
23 | - [Overwriting Components](#overwriting-components)
|
24 | - [Directories](#directories)
|
25 | - [Directory Properties](#directory-properties)
|
26 | - [Library authors](#library-authors)
|
27 | - [License](#license)
|
28 |
|
29 | ## Features
|
30 |
|
31 | - Automatically scan `components/` directory
|
32 | - No need to manually import components anymore
|
33 | - Multiple paths with customizable prefixes and lookup/ignore patterns
|
34 | - Lazy loading (Async components)
|
35 | - Production code-splitting optimization (loader)
|
36 | - Hot reloading
|
37 | - Module integration ([library authors](#library-authors))
|
38 | - Fully tested
|
39 |
|
40 | ## Usage
|
41 |
|
42 | Set the `components` option in `nuxt.config`:
|
43 |
|
44 | ```js
|
45 | export default {
|
46 | components: true
|
47 | }
|
48 | ```
|
49 |
|
50 | **Note:** If using nuxt `2.10...2.13`, you have to also manually install and add `@nuxt/components` to `buildModules` inside `nuxt.config`.
|
51 |
|
52 | **Create your components:**
|
53 |
|
54 | ```bash
|
55 | | components/
|
56 | ---| ComponentFoo.vue
|
57 | ---| ComponentBar.vue
|
58 | ```
|
59 |
|
60 | **Use them whenever you want, they will be auto imported in `.vue` files :**
|
61 |
|
62 | ```html
|
63 | <template>
|
64 | <ComponentFoo />
|
65 | <component-bar />
|
66 | </template>
|
67 | ```
|
68 |
|
69 | No need anymore to manually import them in the `script` section!
|
70 |
|
71 | See [live demo](https://codesandbox.io/s/nuxt-components-cou9k) or [video example](https://www.youtube.com/watch?v=lQ8OBrgVVr8).
|
72 |
|
73 | ### Lazy Imports
|
74 |
|
75 | Nuxt by default does code-slitting per page and components. But sometimes we also need to lazy load them:
|
76 | - Component size is rather big (or has big dependencies imported) like a text-editor
|
77 | - Component is rendered conditionally with `v-if` or being in a modal
|
78 |
|
79 | In order to [lazy load](https://webpack.js.org/guides/lazy-loading/) a component, all we need to do is to add `Lazy` prefix to component name.
|
80 |
|
81 | You now can easily import a component on-demand:
|
82 |
|
83 | ```html
|
84 | <template>
|
85 | <LazyComponentFoo v-if="foo" />
|
86 | <button @click="loadFoo">
|
87 | Load Foo
|
88 | </button>
|
89 | </template>
|
90 |
|
91 | <script>
|
92 | export default {
|
93 | data () {
|
94 | return {
|
95 | foo: null
|
96 | }
|
97 | },
|
98 | methods: {
|
99 | async loadFoo () {
|
100 | this.foo = await this.$axios.$get('foo')
|
101 | }
|
102 | }
|
103 | }
|
104 | </script>
|
105 | ```
|
106 |
|
107 | ### Nested Components
|
108 |
|
109 | If you have components in nested directories:
|
110 |
|
111 | ```bash
|
112 | | components/
|
113 | ---| my/
|
114 | ---| form/
|
115 | ------| TextArea.vue
|
116 | ````
|
117 |
|
118 | The component name will contain its path:
|
119 |
|
120 | ```html
|
121 | <MyFormTextArea />
|
122 | ```
|
123 |
|
124 | For clarity, it is recommended that component file name matches its name. You can also use `MyFormTextArea.vue` as name with same directory structure.
|
125 |
|
126 | If for any reason different prefix is desired, we can add specific directory with the `prefix` option: (See [directories](#directories) section)
|
127 |
|
128 | ```js
|
129 | components: [
|
130 | '~/components/',
|
131 | { path: '~/components/foo/', prefix: 'foo' }
|
132 | ]
|
133 | ```
|
134 |
|
135 | ## Overwriting Components
|
136 |
|
137 | It is possible to have a way to overwrite components using the [level](#level) option. This is very useful for modules and theme authors.
|
138 |
|
139 | Considering this structure:
|
140 |
|
141 | ```bash
|
142 | | node_modules/
|
143 | ---| my-theme/
|
144 | ------| components/
|
145 | ---------| Header.vue
|
146 | | components/
|
147 | ---| Header.vue
|
148 | ```
|
149 |
|
150 | Then defining in the `nuxt.config`:
|
151 |
|
152 | ```js
|
153 | components: [
|
154 | '~/components', // default level is 0
|
155 | { path: 'node_modules/my-theme/components', level: 1 }
|
156 | ]
|
157 | ```
|
158 |
|
159 | Our `components/Header.vue` will overwrite our theme component since the lowest level overwrites.
|
160 |
|
161 | ## Directories
|
162 |
|
163 | By setting `components: true`, default `~/components` directory will be included.
|
164 | However you can customize module behaviour by providing directories to scan:
|
165 |
|
166 | ```js
|
167 | export default {
|
168 | components: [
|
169 | '~/components', // shortcut to { path: '~/components' }
|
170 | { path: '~/components/awesome/', prefix: 'awesome' }
|
171 | ],
|
172 | }
|
173 | ```
|
174 |
|
175 | Each item can be either string or object. String is shortcut to `{ path }`.
|
176 |
|
177 | **Note:** Don't worry about ordering or overlapping directories! Components module will take care of it. Each file will be only matched once with longest path.
|
178 |
|
179 | ### Directory Properties
|
180 |
|
181 | #### path
|
182 |
|
183 | - Required
|
184 | - Type: `String`
|
185 |
|
186 | Path (absolute or relative) to the directory containing your components.
|
187 |
|
188 | You can use Nuxt aliases (`~` or `@`) to refer to directories inside project or directly use a npm package path similar to require.
|
189 |
|
190 | #### extensions
|
191 |
|
192 | - Type: `Array<string>`
|
193 | - Default:
|
194 | - Extensions supported by Nuxt builder (`builder.supportedExtensions`)
|
195 | - Default supported extensions `['vue', 'js']` or `['vue', 'js', 'ts', 'tsx']` depending on your environment
|
196 |
|
197 | **Example:** Support multi-file component structure
|
198 |
|
199 | If you prefer to split your SFCs into `.js`, `.vue` and `.css`, you can only enable `.vue` files to be scanned:
|
200 |
|
201 | ```
|
202 | | components
|
203 | ---| componentC
|
204 | ------| componentC.vue
|
205 | ------| componentC.js
|
206 | ------| componentC.scss
|
207 | ```
|
208 |
|
209 | ```js
|
210 | // nuxt.config.js
|
211 | export default {
|
212 | components: [
|
213 | { path: '~/components', extensions: ['vue'] }
|
214 | ]
|
215 | }
|
216 | ```
|
217 |
|
218 | #### pattern
|
219 |
|
220 | - Type: `string` ([glob pattern]( https://github.com/isaacs/node-glob#glob-primer))
|
221 | - Default: `**/*.${extensions.join(',')}`
|
222 |
|
223 | Accept Pattern that will be run against specified `path`.
|
224 |
|
225 | #### ignore
|
226 |
|
227 | - Type: `Array`
|
228 | - Items: `string` ([glob pattern]( https://github.com/isaacs/node-glob#glob-primer))
|
229 | - Default: `[]`
|
230 |
|
231 | Ignore patterns that will be run against specified `path`.
|
232 |
|
233 | #### prefix
|
234 |
|
235 | - Type: `String`
|
236 | - Default: `''` (no prefix)
|
237 |
|
238 | Prefix all matched components.
|
239 |
|
240 | Example below adds `awesome-`/`Awesome` prefix to the name of components in `awesome/` directory.
|
241 |
|
242 | ```js
|
243 | // nuxt.config.js
|
244 | export default {
|
245 | components: [
|
246 | '~/components',
|
247 | { path: '~/components/awesome/', prefix: 'awesome' }
|
248 | ]
|
249 | }
|
250 | ```
|
251 |
|
252 | ```bash
|
253 | components/
|
254 | awesome/
|
255 | Button.vue
|
256 | Button.vue
|
257 | ```
|
258 |
|
259 | ```html
|
260 | <template>
|
261 | <div>
|
262 | <AwesomeButton>Click on me 🤘</AwesomeButton>
|
263 | <Button>Click on me</Button>
|
264 | </div>
|
265 | </template>
|
266 | ```
|
267 |
|
268 | #### pathPrefix
|
269 |
|
270 | - Type: `Boolean`
|
271 | - Default: `true`
|
272 |
|
273 | Prefix component name by it's path
|
274 |
|
275 | #### watch
|
276 |
|
277 | - Type: `Boolean`
|
278 | - Default: `true`
|
279 |
|
280 | Watch specified `path` for changes, including file additions and file deletions.
|
281 |
|
282 | #### transpile
|
283 |
|
284 | - Type: `Boolean`
|
285 | - Default: `'auto'`
|
286 |
|
287 | Transpile specified `path` using [`build.transpile`](https://nuxtjs.org/api/configuration-build#transpile), by default (`'auto'`) it will set `transpile: true` if `node_modules/` is in `path`.
|
288 |
|
289 | #### level
|
290 |
|
291 | - Type: `Number`
|
292 | - Default: `0`
|
293 |
|
294 | Level are use to define a hint when overwriting the components which have the same name in two different directories, this is useful for theming.
|
295 |
|
296 | ```js
|
297 | export default {
|
298 | components: [
|
299 | '~/components', // default level is 0
|
300 | { path: 'my-theme/components', level: 1 }
|
301 | ]
|
302 | }
|
303 | ```
|
304 |
|
305 | Components having the same name in `~/components` will overwrite the one in `my-theme/components`, learn more in [Overwriting Components](#overwriting-components). The lowest value will overwrites.
|
306 |
|
307 | ## Migration guide
|
308 |
|
309 | ## `v1` to `v2`
|
310 |
|
311 | Starting with `nuxt@2.15`, Nuxt uses `@nuxt/components` v2:
|
312 |
|
313 | - All components are globally available so you can move `components/global/`
|
314 | to `components/` and `global: true` is not required anymore
|
315 | - Full path inside `components` is used to prefix component names. If you were structing your
|
316 | components in multiple directories, should either add prefix or register in `components` section of `nuxt.config` or use new `pathPrefix` option.
|
317 |
|
318 | **Example:**
|
319 |
|
320 | ```
|
321 | components
|
322 | ├── atoms
|
323 | │ └── icons
|
324 | ├── molecules
|
325 | │ └── illustrations
|
326 | ├── organisms
|
327 | │ └── ads
|
328 | └── templates
|
329 | ├── blog
|
330 | └── home
|
331 | ```
|
332 |
|
333 | ```js
|
334 | // nuxt.config.js
|
335 | export default {
|
336 | components: [
|
337 | '~/components/templates',
|
338 | '~/components/atoms',
|
339 | '~/components/molecules',
|
340 | '~/components/organisms',
|
341 | ]
|
342 | }
|
343 | ```
|
344 |
|
345 | ## Library Authors
|
346 |
|
347 | Making Vue Component libraries with automatic tree-shaking and component registration is now damn easy ✨
|
348 |
|
349 | This module expose a hook named `components:dirs` so you can easily extend the directory list without updating user configuration in your Nuxt module.
|
350 |
|
351 | Imagine a directory structure like this:
|
352 |
|
353 | ```bash
|
354 | | node_modules/
|
355 | ---| awesome-ui/
|
356 | ------| components/
|
357 | ---------| Alert.vue
|
358 | ---------| Button.vue
|
359 | ------| nuxt.js
|
360 | | pages/
|
361 | ---| index.vue
|
362 | | nuxt.config.js
|
363 | ```
|
364 |
|
365 | Then in `awesome-ui/nuxt.js` you can use the `components:dir` hook:
|
366 |
|
367 | ```js
|
368 | import { join } from 'path'
|
369 |
|
370 | export default function () {
|
371 | this.nuxt.hook('components:dirs', (dirs) => {
|
372 | // Add ./components dir to the list
|
373 | dirs.push({
|
374 | path: join(__dirname, 'components'),
|
375 | prefix: 'awesome'
|
376 | })
|
377 | })
|
378 | }
|
379 | ```
|
380 |
|
381 | That's it! Now in your project, you can import your ui library as a Nuxt module in your `nuxt.config.js`:
|
382 |
|
383 | ```js
|
384 | export default {
|
385 | buildModules: [
|
386 | '@nuxt/components',
|
387 | 'awesome-ui/nuxt'
|
388 | ]
|
389 | }
|
390 | ```
|
391 |
|
392 | And directly use the module components (prefixed with `awesome-`), our `pages/index.vue`:
|
393 |
|
394 | ```vue
|
395 | <template>
|
396 | <div>
|
397 | My <AwesomeButton>UI button</AwesomeButton>!
|
398 | <awesome-alert>Here's an alert!</awesome-alert>
|
399 | </div>
|
400 | </template>
|
401 | ```
|
402 |
|
403 | It will automatically import the components only if used and also support HMR when updating your components in `node_modules/awesome-ui/components/`.
|
404 |
|
405 | Next: publish your `awesome-ui` module to [npm](https://www.npmjs.com) and share it with the other Nuxters ✨
|
406 |
|
407 | ## License
|
408 |
|
409 | [MIT](./LICENSE)
|
410 |
|
411 |
|
412 |
|
413 | [npm-version-src]: https://img.shields.io/npm/v/@nuxt/components/latest.svg?style=flat-square
|
414 | [npm-version-href]: https://npmjs.com/package/@nuxt/components
|
415 |
|
416 | [npm-downloads-src]: https://img.shields.io/npm/dt/@nuxt/components.svg?style=flat-square
|
417 | [npm-downloads-href]: https://npmjs.com/package/@nuxt/components
|
418 |
|
419 | [github-actions-ci-src]: https://img.shields.io/github/workflow/status/nuxt/typescript/test?label=ci&style=flat-square
|
420 | [github-actions-ci-href]: https://github.com/nuxt/components/actions?query=workflow%3Aci
|
421 |
|
422 | [codecov-src]: https://img.shields.io/codecov/c/github/nuxt/components.svg?style=flat-square
|
423 | [codecov-href]: https://codecov.io/gh/nuxt/components
|
424 |
|
425 | [license-src]: https://img.shields.io/npm/l/@nuxt/components.svg?style=flat-square
|
426 | [license-href]: https://npmjs.com/package/@nuxt/components
|