Skip to content

Commit f36cdc5

Browse files
author
Pablo Henrique
authored
Update README.md
1 parent 9388043 commit f36cdc5

File tree

1 file changed

+17
-244
lines changed

1 file changed

+17
-244
lines changed

README.md

Lines changed: 17 additions & 244 deletions
Original file line numberDiff line numberDiff line change
@@ -339,202 +339,38 @@ Component structure:
339339
export default {
340340
// compose new components
341341
extends: {},
342+
// component properties
343+
props: {},
342344
// variables
343345
data() {},
344346
computed: {},
347+
// when component uses other components
348+
components: {},
349+
// methods
345350
watch: {},
346351
methods: {},
352+
// component Lifecycle hooks
353+
beforeCreate() {},
347354
mounted() {},
348355
};
349356
```
350357

351358
[↑ back to Table of Contents](#table-of-contents)
352359

360+
## Avoid `this.$parent`
353361

354-
## Avoid fake ES6 syntax
355-
356-
Vue.js supports a [shorthand *ES6 like* method syntax](http://vuejs.org/guide/#component-syntax). Vue.js compiles the shorthand syntax `methodName() { }` into `this.methodName = function() {}.bind(this)`. Since this is non-standard you should **avoid fake ES6 method shorthand syntax**.
357-
358-
### Why?
359-
360-
* The fake ES6 shorthand syntax is non-standard and can therefore confuse developers.
361-
* The component scripts are not actual ES6 classes, so IDEs won't be able to interpret the fake ES6 class method syntax.
362-
* It should always be clear which methods are bound to the component and thus available in the markup. The shorthand syntax obscures the principle of writing code which is transparent and easy to understand.
363-
364-
### How?
365-
366-
Use `component.methodName =` instead of magic `methodName() { }` syntax:
367-
368-
```javascript
369-
/* recommended */
370-
var component = this;
371-
component.todos = [];
372-
component.add = add;
373-
374-
function add() {
375-
if (component.text) {
376-
component.todos.push({ title: component.text });
377-
component.text = component.input.value = '';
378-
}
379-
}
380-
381-
/* avoid */
382-
todos = [];
383-
384-
add() {
385-
if (this.text) {
386-
this.todos.push({ title: this.text });
387-
this.text = this.input.value = '';
388-
}
389-
}
390-
```
391-
392-
**Tip**: [Disable transformation of the fake ES6 syntax](http://vuejs.org/guide/compiler/#no-transformation) during pre-compilation by setting `type` to `none`:
393-
394-
```bash
395-
vue --type none
396-
```
397-
398-
[↑ back to Table of Contents](#table-of-contents)
399-
400-
401-
## Avoid `component.parent`
402-
403-
Vue.js supports [nested components](http://vuejs.org/guide/#nested-components) which have access to their parent context through `component.parent`. Accessing context outside your vue component violates the [FIRST](https://addyosmani.com/first/) rule of [module based development](#module-based-development). Therefore you should **avoid using `component.parent`**.
404-
405-
The exception to this rule are anonymous child components in a [for each loop](http://vuejs.org/guide/#loops) as they are defined directly inside the vue component.
362+
Vue.js supports nested components which have access to their parent context. Accessing context outside your vue component violates the [FIRST](https://addyosmani.com/first/) rule of [module based development](#module-based-development). Therefore you should **avoid using `this.$parent`**.
406363

407364
### Why?
408365

409366
* A vue component, like any module, must work in isolation. If a component needs to access its parent, this rule is broken.
410367
* If a component needs access to its parent, it can no longer be reused in a different context.
411-
* By accessing its parent a child component can modify properties on its parent. This can lead to unexpected behaviour.
412368

413369
### How?
414370

415-
* Pass values from the parent to the child component using attribute expressions.
371+
* Pass values from the parent to the child component using attribute/properties.
416372
* Pass methods defined on the parent component to the child component using callbacks in attribute expressions.
417373

418-
```html
419-
<!-- recommended -->
420-
<parent-component>
421-
<child-component value="{ value }" /> <!-- pass parent value to child -->
422-
</parent-component>
423-
424-
<child-component>
425-
<span>{ opts.value }</span> <!-- use value passed by parent -->
426-
</child-component>
427-
428-
<!-- avoid -->
429-
<parent-component>
430-
<child-component />
431-
</parent-component>
432-
433-
<child-component>
434-
<span>value: { parent.value }</span> <!-- don't do this -->
435-
</child-component>
436-
```
437-
```html
438-
<!-- recommended -->
439-
<parent-component>
440-
<child-component on-event="{ methodToCallOnEvent }" /> <!-- use method as callback -->
441-
<script>this.methodToCallOnEvent = () => { /*...*/ };</script>
442-
<parent-component>
443-
444-
<child-component>
445-
<button onclick="{ opts.onEvent }"></button> <!-- call method passed by parent -->
446-
</child-component>
447-
448-
<!-- avoid -->
449-
<parent-component>
450-
<child-component />
451-
<script>this.methodToCallOnEvent = () => { /*...*/ };</script>
452-
<parent-component>
453-
454-
<child-component>
455-
<button onclick="{ parent.methodToCallOnEvent }"></button> <!-- don't do this -->
456-
</child-component>
457-
```
458-
```html
459-
<!-- allowed exception -->
460-
<parent-component>
461-
<button each="{ item in items }"
462-
onclick="{ parent.onEvent }"> <!-- okay, because button is not a vue component -->
463-
{ item.text }
464-
</button>
465-
<script>this.onEvent = (e) => { alert(e.item.text); }</script>
466-
</parent-component>
467-
```
468-
469-
[↑ back to Table of Contents](#table-of-contents)
470-
471-
472-
## Use `each ... in` syntax
473-
474-
Vue.js supports multiple notations for [loops](http://vuejs.org/guide/#loops): item in array (`each="{ item in items }"`); key, value in object (`each="{ key, value in items }"`) and a shorthand (`each="{ items }"`) notation. This shorthand can lead to confusion. Therefore you should **use the `each ... in` syntax**.
475-
476-
### Why?
477-
478-
Vue.js creates a new component instance for each item the `each` directive loops through. When using the shorthand notation, the methods and properties of the current item are bound to the current component instance (local `this`). This is not obvious when looking at the markup and may thus confuse other developers. Therefore you should **use the `each ... in` syntax**.
479-
480-
### How?
481-
482-
Use `each="{ item in items }"` or `each="{ key, value in items }"` instead of `each="{ items }"` syntax:
483-
484-
```html
485-
<!-- recommended: -->
486-
<ul>
487-
<li each="{ item in items }">
488-
<label class="{ completed: item.done }">
489-
<input type="checkbox" checked="{ item.done }"> { item.title }
490-
</label>
491-
</li>
492-
</ul>
493-
494-
<!-- recommended: -->
495-
<ul>
496-
<li each="{ key, item in items }">
497-
<label class="{ completed: item.done }">
498-
<input type="checkbox" checked="{ item.done }"> { key }. { item.title }
499-
</label>
500-
</li>
501-
</ul>
502-
503-
<!-- avoid: -->
504-
<ul>
505-
<li each="{ items }">
506-
<label class="{ completed: done }">
507-
<input type="checkbox" checked="{ done }"> { title }
508-
</label>
509-
</li>
510-
</ul>
511-
```
512-
513-
[↑ back to Table of Contents](#table-of-contents)
514-
515-
516-
## Put styles in external files
517-
518-
For developer convenience, Vue.js allows you to define a component element's style in a [nested `<style>` component](http://vuejs.org/guide/#component-styling). While you can [scope](http://vuejs.org/guide/#scoped-css) these styles to the component element, Vue.js does not provide true encapsulation. Instead Vue.js extracts these styles from the components (JavaScript) and injects them into the document on runtime. Since Vue.js compiles nested styles to JavaScript and doesn't have true encapsulation, you should instead **put styles in external files**.
519-
520-
### Why?
521-
522-
* External stylesheets can be handled by the browser independently of Vue.js and component files. This means styles can be applied to initial markup even if JavaScript errors occur or isn't loaded (yet).
523-
* External stylesheets can be used in combination with pre-processors (Less, Sass, PostCSS, etc) and your own (existing) build tools.
524-
* External stylesheets can be minified, served and cached separately. This improves performance.
525-
* Vue.js expressions are not supported in nested `<style>`s so there's no added benefit in using them.
526-
527-
### How?
528-
529-
Styles related to the component and its markup, should be placed in a separate stylesheet file next to the component file, inside its module directory:
530-
531-
```
532-
my-example/
533-
├── my-example.vue
534-
├── my-example.(css|less|scss) <-- external stylesheet next to component file
535-
└── ...
536-
```
537-
538374
[↑ back to Table of Contents](#table-of-contents)
539375

540376

@@ -550,22 +386,18 @@ Alternatively the module name can be used as CSS class namespace.
550386

551387
### How?
552388

553-
Use the component name as selector, as parent selector or as namespace prefix (depending on your CSS naming strategy).
389+
Use the component name as a namespace prefix based on BEM and OOCSS.
554390

555391
```css
556392
/* recommended */
557-
my-example { }
558-
my-example li { }
559-
.my-example__item { }
393+
.MyExample { }
394+
.MyExample li { }
395+
.MyExample__item { }
560396

561397
/* avoid */
562-
.my-alternative { } /* not scoped to component or module name */
563-
.my-parent .my-example { } /* .my-parent is outside scope, so should not be used in this file */
398+
.My-Example { } /* not scoped to component or module name, not BEM compliant */
564399
```
565400

566-
note: If you're using [`data-is=`](http://vuejs.org/guide/#html-elements-as-components) (introduced in [v2.3.17](http://vuejs.org/release-notes/#march-9-2016)) to initiate Vue.js components, you can use `[data-is="my-example"]` as CSS selector instead of `.my-example`.
567-
568-
569401
[↑ back to Table of Contents](#table-of-contents)
570402

571403

@@ -623,79 +455,20 @@ For customising the slider appearance see the [Styling section in the noUiSlider
623455

624456
## Add a component demo
625457

626-
Add a `*.demo.html` file with demos of the component with different configurations, showing how the component can be used.
458+
Add a `index.html` file with demos of the component with different configurations, showing how the component can be used.
627459

628460
### Why?
629461

630462
* A component demo proves the module works in isolation.
631463
* A component demo gives developers a preview before having to dig into the documentation or code.
632464
* Demos can illustrate all the possible configurations and variations a component can be used in.
633465

634-
### How?
635-
636-
Add a `*.demo.html` file to your module directory:
637-
638-
```
639-
city-map/
640-
├── city-map.vue
641-
├── city-map.demo.html
642-
├── city-map.css
643-
└── ...
644-
```
645-
646-
Inside the demo file:
647-
648-
* Include `vue+compiler.min.js` to also compile during runtime.
649-
* Include the component file (e.g. `./city-map.vue`).
650-
* Create a `demo` component (`<yield/>`) to embed your demos in (otherwise option attributes are not supported).
651-
* Write demos inside the `<demo>` components.
652-
* As a bonus add `aria-label`s to the `<demo>` components and style those as title bars.
653-
* Initialise using `vue.mount('demo', {})`.
654-
655-
Example demo file in `city-component` module:
656-
657-
```html
658-
<!-- modules/city-map/city-map.demo.html: -->
659-
<body>
660-
<h1>city-map demos</h1>
661-
662-
<demo aria-label="City map of London">
663-
<city-map location="London" />
664-
</demo>
665-
666-
<demo aria-label="City map of Paris">
667-
<city-map location="Paris" />
668-
</demo>
669-
670-
<link rel="stylesheet" href="./city-map.css">
671-
672-
<script src="path/to/vue+compiler.min.js"></script>
673-
<script type="vue/component" src="./city-map.vue"></script>
674-
<script>
675-
vue.component('demo','<yield/>');
676-
vue.mount('demo', {});
677-
</script>
678-
679-
<style>
680-
/* add a grey bar with the `aria-label` as demo title */
681-
demo:before {
682-
content: "Demo: " attr(aria-label);
683-
display: block;
684-
background: #F3F5F5;
685-
padding: .5em;
686-
clear: both;
687-
}
688-
</style>
689-
</body>
690-
```
691-
Note: this is a working concept, but could be much cleaner using build scripts.
692-
693466
[↑ back to Table of Contents](#table-of-contents)
694467

695468

696469
## Lint your component files
697470

698-
Linters improve code consistency and help trace syntax errors. With some extra configuration Vue.js component files can also be linted.
471+
Linters improve code consistency and help trace syntax errors. .vue files can be linted adding the `eslint-plugin-html` in your project. If you choose, you can start a project with ESLint enabled by default using `vue-cli`;
699472

700473
### Why?
701474

0 commit comments

Comments
 (0)