├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── docs
├── .vuepress
│ ├── components
│ │ ├── ErrorBoundary.vue
│ │ ├── GithubStarButton.vue
│ │ ├── PassedProps.vue
│ │ ├── PassingProps.vue
│ │ ├── PassingPropsChild.vue
│ │ ├── SFCButton.vue
│ │ ├── ThemeButton.vue
│ │ ├── ThemeProvider.vue
│ │ └── ThrowError.vue
│ ├── config.js
│ ├── override.styl
│ └── public
│ │ ├── browserconfig.xml
│ │ ├── icons
│ │ ├── android-icon-144x144.png
│ │ ├── android-icon-192x192.png
│ │ ├── android-icon-36x36.png
│ │ ├── android-icon-48x48.png
│ │ ├── android-icon-72x72.png
│ │ ├── android-icon-96x96.png
│ │ ├── apple-icon-114x114.png
│ │ ├── apple-icon-120x120.png
│ │ ├── apple-icon-144x144.png
│ │ ├── apple-icon-152x152.png
│ │ ├── apple-icon-180x180.png
│ │ ├── apple-icon-57x57.png
│ │ ├── apple-icon-60x60.png
│ │ ├── apple-icon-72x72.png
│ │ ├── apple-icon-76x76.png
│ │ ├── apple-icon-precomposed.png
│ │ ├── apple-icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon-96x96.png
│ │ ├── favicon.ico
│ │ ├── ms-icon-144x144.png
│ │ ├── ms-icon-150x150.png
│ │ ├── ms-icon-310x310.png
│ │ └── ms-icon-70x70.png
│ │ ├── learn-vue-logo.png
│ │ ├── manifest.json
│ │ └── vue-patterns-hero.png
├── README.md
├── patterns
│ └── README.md
├── ru
│ ├── README.md
│ ├── patterns
│ │ └── README.md
│ ├── sponsors
│ │ └── README.md
│ ├── translations
│ │ └── README.md
│ └── useful-links
│ │ └── README.md
├── sponsors
│ └── README.md
├── translations
│ └── README.md
└── useful-links
│ └── README.md
├── package.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | *.log
4 | .temp
5 | docs/.vuepress/dist
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - 10
5 |
6 | cache:
7 | directories:
8 | - node_modules
9 |
10 | script:
11 | - npm run docs:build
12 |
13 | after_success:
14 | - npm run docs:deploy
15 |
16 | deploy:
17 | provider: pages
18 | skip_cleanup: true
19 | github-token: $GITHUB_TOKEN
20 | keep-history: true
21 | email: simsim0709@gmail.com
22 | name: Ilkwon Sim
23 | local-dir: docs/.vuepress/dist
24 | repo: learn-vuejs/vue-patterns
25 | on:
26 | branch: master
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Ilkwon Sim
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [vue-patterns](https://learn-vuejs.github.io/vue-patterns/)
2 |
3 | > Useful Vue patterns, techniques, tips and tricks and helpful curated links.
4 |
5 | [](https://learn-vuejs.github.io/vue-patterns/)
6 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/ErrorBoundary.vue:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/GithubStarButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/PassedProps.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
27 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/PassingProps.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
24 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/PassingPropsChild.vue:
--------------------------------------------------------------------------------
1 |
2 | {{childPropA}}
3 |
4 |
5 |
12 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/SFCButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | (clicked - {{count}})
5 |
6 |
7 |
8 |
9 |
24 |
25 |
38 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/ThemeButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
28 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/ThemeProvider.vue:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/ThrowError.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Error Thrown Button ({{count}})
4 |
5 |
6 |
7 |
26 |
--------------------------------------------------------------------------------
/docs/.vuepress/config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | base: '/vue-patterns/',
3 | locales: {
4 | '/': {
5 | lang: 'en-US',
6 | title: 'Vue Patterns',
7 | description:
8 | 'Useful Vue patterns, techniques, tips and tricks and curated helpful links.',
9 | },
10 | '/ru/': {
11 | lang: 'ru',
12 | title: 'Паттерны Vue',
13 | description: 'Полезные паттерны, методы, советы и рекомендации, а также тщательно подобранный список ссылок по Vue'
14 | }
15 | },
16 | serviceWorker: true,
17 | head: [
18 | [
19 | 'link',
20 | {
21 | rel: 'apple-touch-icon',
22 | sizes: '57x57',
23 | href: '/icons/apple-icon-57x57.png',
24 | },
25 | ],
26 | [
27 | 'link',
28 | {
29 | rel: 'apple-touch-icon',
30 | sizes: '60x60',
31 | href: '/icons/apple-icon-60x60.png',
32 | },
33 | ],
34 | [
35 | 'link',
36 | {
37 | rel: 'apple-touch-icon',
38 | sizes: '72x72',
39 | href: '/icons/apple-icon-72x72.png',
40 | },
41 | ],
42 | [
43 | 'link',
44 | {
45 | rel: 'apple-touch-icon',
46 | sizes: '76x76',
47 | href: '/icons/apple-icon-76x76.png',
48 | },
49 | ],
50 | [
51 | 'link',
52 | {
53 | rel: 'apple-touch-icon',
54 | sizes: '114x114',
55 | href: '/icons/apple-icon-114x114.png',
56 | },
57 | ],
58 | [
59 | 'link',
60 | {
61 | rel: 'apple-touch-icon',
62 | sizes: '120x120',
63 | href: '/icons/apple-icon-120x120.png',
64 | },
65 | ],
66 | [
67 | 'link',
68 | {
69 | rel: 'apple-touch-icon',
70 | sizes: '144x144',
71 | href: '/icons/apple-icon-144x144.png',
72 | },
73 | ],
74 | [
75 | 'link',
76 | {
77 | rel: 'apple-touch-icon',
78 | sizes: '152x152',
79 | href: '/icons/apple-icon-152x152.png',
80 | },
81 | ],
82 | [
83 | 'link',
84 | {
85 | rel: 'apple-touch-icon',
86 | sizes: '180x180',
87 | href: '/icons/apple-icon-180x180.png',
88 | },
89 | ],
90 | [
91 | 'link',
92 | {
93 | rel: 'icon',
94 | type: 'image/png',
95 | sizes: '192x192',
96 | href: '/icons/android-icon-192x192.png',
97 | },
98 | ],
99 | [
100 | 'link',
101 | {
102 | rel: 'icon',
103 | type: 'image/png',
104 | sizes: '32x32',
105 | href: '/icons/favicon-32x32.png',
106 | },
107 | ],
108 | [
109 | 'link',
110 | {
111 | rel: 'icon',
112 | type: 'image/png',
113 | sizes: '96x96',
114 | href: '/icons/favicon-96x96.png',
115 | },
116 | ],
117 | [
118 | 'link',
119 | {
120 | rel: 'icon',
121 | type: 'image/png',
122 | sizes: '16x16',
123 | href: '/icons/favicon-16x16.png',
124 | },
125 | ],
126 | ['link', { rel: 'manifest', href: '/manifest.json' }],
127 | [
128 | 'script',
129 | { defer: true, async: true, src: 'https://buttons.github.io/buttons.js' },
130 | ],
131 | ],
132 | themeConfig: {
133 | displayAllHeaders: true,
134 | lastUpdated: 'Last Updated',
135 | repo: 'learn-vuejs/vue-patterns',
136 | editLinks: true,
137 | locales: {
138 | '/': {
139 | lastUpdated: 'Last Updated',
140 | nav: [
141 | { text: 'Home', link: '/' },
142 | { text: 'Docs', link: '/patterns/' },
143 | {
144 | text: 'Translations',
145 | items: [
146 | {
147 | text: '简体中文',
148 | link: 'https://github.com/ZYSzys/vue-patterns-cn',
149 | },
150 | {
151 | text: '繁體中文',
152 | link: 'https://github.com/yoyoys/vue-patterns-cht',
153 | },
154 | ],
155 | },
156 | ],
157 | sidebar: [
158 | ['/patterns/', 'Patterns'],
159 | ['/useful-links/', 'Useful Links'],
160 | ['/sponsors/', 'Fullstack Vue Book'],
161 | ['/translations/', 'Translations'],
162 | ],
163 | },
164 | '/ru/': {
165 | label: 'Русский',
166 | selectText: 'Переводы',
167 | lastUpdated: 'Последнее обновление',
168 | editLinkText: 'Изменить эту страницу на GitHub',
169 | nav: [
170 | { text: 'Главная', link: '/ru/' },
171 | { text: 'Документация', link: '/ru/patterns/' },
172 | {
173 | text: 'Внешние переводы',
174 | items: [
175 | {
176 | text: '简体中文',
177 | link: 'https://github.com/ZYSzys/vue-patterns-cn',
178 | },
179 | {
180 | text: '繁體中文',
181 | link: 'https://github.com/yoyoys/vue-patterns-cht',
182 | },
183 | ],
184 | },
185 | ],
186 | sidebar: [
187 | ['/ru/patterns/', 'Паттерны'],
188 | ['/ru/useful-links/', 'Полезные ссылки'],
189 | ['/ru/sponsors/', 'Книга Fullstack Vue'],
190 | ['/ru/translations/', 'Переводы'],
191 | ],
192 | },
193 | },
194 | },
195 | };
196 |
--------------------------------------------------------------------------------
/docs/.vuepress/override.styl:
--------------------------------------------------------------------------------
1 | .btn {
2 | display: inline-block;
3 | font-size: 1.2rem;
4 | color: #212121;
5 | padding: 0.8rem 1.6rem;
6 | border-radius: 4px;
7 | transition: background-color 0.1s ease;
8 | box-sizing: border-box;
9 | }
10 |
11 | .btn-primary {
12 | color: #fff;
13 | background-color: #3eaf7c;
14 | }
15 |
16 | .btn-danger {
17 | color: #fff;
18 | background-color: #da5961;
19 | }
20 |
21 | .bg-danger {
22 | color: #fff;
23 | background-color: #da5961;
24 | }
25 |
--------------------------------------------------------------------------------
/docs/.vuepress/public/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 | #ffffff
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/android-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/android-icon-144x144.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/android-icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/android-icon-192x192.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/android-icon-36x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/android-icon-36x36.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/android-icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/android-icon-48x48.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/android-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/android-icon-72x72.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/android-icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/android-icon-96x96.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-114x114.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-120x120.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-144x144.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-152x152.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-180x180.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-57x57.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-60x60.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-72x72.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-76x76.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon-precomposed.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/apple-icon.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/favicon-96x96.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/favicon.ico
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/ms-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/ms-icon-144x144.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/ms-icon-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/ms-icon-150x150.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/ms-icon-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/ms-icon-310x310.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/icons/ms-icon-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/icons/ms-icon-70x70.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/learn-vue-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/learn-vue-logo.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Vue Patterns",
3 | "short_name": "Vue Patterns",
4 | "start_url": "/index.html",
5 | "display": "standalone",
6 | "background_color": "#fff",
7 | "theme_color": "#3eaf7c",
8 | "icons": [
9 | {
10 | "src": "/android-icon-36x36.png",
11 | "sizes": "36x36",
12 | "type": "image/png",
13 | "density": "0.75"
14 | },
15 | {
16 | "src": "/android-icon-48x48.png",
17 | "sizes": "48x48",
18 | "type": "image/png",
19 | "density": "1.0"
20 | },
21 | {
22 | "src": "/android-icon-72x72.png",
23 | "sizes": "72x72",
24 | "type": "image/png",
25 | "density": "1.5"
26 | },
27 | {
28 | "src": "/android-icon-96x96.png",
29 | "sizes": "96x96",
30 | "type": "image/png",
31 | "density": "2.0"
32 | },
33 | {
34 | "src": "/android-icon-144x144.png",
35 | "sizes": "144x144",
36 | "type": "image/png",
37 | "density": "3.0"
38 | },
39 | {
40 | "src": "/android-icon-192x192.png",
41 | "sizes": "192x192",
42 | "type": "image/png",
43 | "density": "4.0"
44 | }
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/docs/.vuepress/public/vue-patterns-hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/translation-gang/vue-patterns/38353fbbd347f2cc62224f00b7687533d377e91c/docs/.vuepress/public/vue-patterns-hero.png
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | heroImage: /learn-vue-logo.png
4 | actionText: Get Started →
5 | actionLink: /patterns/
6 | ---
7 |
8 |
17 |
--------------------------------------------------------------------------------
/docs/patterns/README.md:
--------------------------------------------------------------------------------
1 | ## Component Declaration
2 |
3 | ### [Single File Component (a.k.a. SFC)](https://vuejs.org/v2/guide/single-file-components.html) - Most Common
4 |
5 | <<< @/docs/.vuepress/components/SFCButton.vue
6 |
7 | SFC
8 |
9 | ### String Template (or ES6 Template Literal)
10 |
11 | ```js
12 | Vue.component('my-btn', {
13 | template: `
14 |
15 | (clicked - {{count}})
16 |
17 | `,
18 | data() {
19 | return {
20 | text: 'Click me',
21 | };
22 | },
23 | methods: {
24 | data() {
25 | return {
26 | count: 0,
27 | };
28 | },
29 | methods: {
30 | handleClick() {
31 | this.count++;
32 | console.log('clicked', this.count);
33 | },
34 | },
35 | },
36 | });
37 | ```
38 |
39 | ### [Render Function](https://vuejs.org/v2/guide/render-function.html)
40 |
41 | ```js
42 | Vue.component('my-btn', {
43 | methods: {
44 | data() {
45 | return {
46 | count: 0,
47 | };
48 | },
49 | methods: {
50 | handleClick() {
51 | this.count++;
52 | console.log('clicked', this.count);
53 | },
54 | },
55 | },
56 | render(h) {
57 | return h(
58 | 'button',
59 | {
60 | attrs: {
61 | class: 'btn-primary',
62 | },
63 | on: {
64 | click: this.handleClick,
65 | },
66 | },
67 | this.$slots.default
68 | );
69 | },
70 | });
71 | ```
72 |
73 | ### [JSX](https://vuejs.org/v2/guide/render-function.html#JSX)
74 |
75 | ```jsx
76 | Vue.component('my-btn', {
77 | data() {
78 | return {
79 | text: 'Click me',
80 | };
81 | },
82 | methods: {
83 | handleClick() {
84 | console.log('clicked');
85 | },
86 | },
87 | render() {
88 | return (
89 |
90 | {this.$slots.default}(clicked - {{count}})
91 |
92 | );
93 | },
94 | });
95 | ```
96 |
97 | ### [vue-class-component](https://github.com/vuejs/vue-class-component)
98 |
99 | ```vue
100 |
101 |
102 | (clicked - {{count}})
103 |
104 |
105 |
106 |
120 |
121 |
126 | ```
127 |
128 | #### References:
129 |
130 | - [Official - Single File Component](https://vuejs.org/v2/guide/single-file-components.html)
131 | - [Official - Render Functions & JSX](https://vuejs.org/v2/guide/render-function.html)
132 | - [7 Ways To Define A Component Template in VueJS](https://medium.com/js-dojo/7-ways-to-define-a-component-template-in-vuejs-c04e0c72900d)
133 |
134 | ## Component Communication
135 |
136 | ### Props and Events
137 |
138 | Basically, vue component follows one-way data flow, that is props down([See official guide](https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow)) and event up.
139 | Props are read-only data, so it's impossible to change props from child components.
140 | When props changes, child components will be rerendered automatically(props are reactive data source).
141 | Child components can only emit event to direct parent, so that the parent component may change `data`, mapped to the child component's `props`.
142 |
143 | ```vue
144 |
145 | {{text}}
146 |
147 |
148 |
156 | ```
157 |
158 | ```vue
159 |
160 |
161 |
162 |
163 |
179 | ```
180 |
181 | #### References:
182 |
183 | - [Official - Props](https://vuejs.org/v2/guide/components-props.html)
184 | - [Vue.js Component Communication Patterns](https://alligator.io/vuejs/component-communication/)
185 | - [Creating Custom Inputs With Vue.js](https://www.smashingmagazine.com/2017/08/creating-custom-inputs-vue-js/)
186 | - [Vue Sibling Component Communication](https://vegibit.com/vue-sibling-component-communication/)
187 | - [Managing State in Vue.js](https://medium.com/fullstackio/managing-state-in-vue-js-23a0352b1c87)
188 | - [Vue.js communication part 2: parent-child components](https://gambardella.info/2017/09/13/vue-js-communication-part-2-parent-child-components/)
189 |
190 | ## Component Events Handling
191 |
192 | #### References:
193 |
194 | - [Official - Custom Events](https://vuejs.org/v2/guide/components-custom-events.html)
195 | - [Leveraging Vue events to reduce prop declarations](https://itnext.io/leveraging-vue-events-to-reduce-prop-declarations-e38f5dce2aaf)
196 | - [Vue.js Component Hooks as Events](https://alligator.io/vuejs/component-event-hooks/)
197 | - [Creating a Global Event Bus with Vue.js](https://alligator.io/vuejs/global-event-bus/)
198 | - [Vue.js Event Bus + Promises](https://medium.com/@jesusgalvan/vue-js-event-bus-promises-f83e73a81d72)
199 |
200 | ## Component Conditional Rendering
201 |
202 | ### Directives (`v-if` / `v-else` / `v-else-if` / `v-show`)
203 |
204 | `v-if`
205 |
206 | ```vue
207 | Render only if v-if condition is true
208 | ```
209 |
210 | `v-if` and `v-else`
211 |
212 | ```vue
213 | Render only if v-if condition is true
214 | Render only if v-if condition is false
215 | ```
216 |
217 | `v-else-if`
218 |
219 | ```vue
220 | Render only if `type` is equal to `A`
221 | Render only if `type` is equal to `B`
222 | Render only if `type` is equal to `C`
223 | Render if `type` is not `A` or `B` or `C`
224 | ```
225 |
226 | `v-show`
227 |
228 | ```vue
229 | Always rendered, but it should be visible only if `v-show` conditions is true
230 | ```
231 |
232 | If you want to conditionally render more than one element,
233 | you can use directives(`v-if` / `v-else` / `v-else-if` /`v-show`) on a `` element.
234 | Notice that `` element is not actually rendered into DOM. It is an invisible wrapper.
235 |
236 | ```vue
237 |
238 | All the elements
239 | will be rendered into DOM
240 | except `template` element
241 |
242 | ```
243 |
244 | ### Render Function or JSX
245 |
246 | If you use render function or JSX in your vue application, you can apply all the techniques such as `if else` and `switch case` statement and `ternary` and `logical` operator.
247 |
248 | `if else` statement
249 |
250 | ```jsx
251 | export default {
252 | data() {
253 | return {
254 | isTruthy: true,
255 | };
256 | },
257 | render(h) {
258 | if (this.isTruthy) {
259 | return Render value is true ;
260 | } else {
261 | return Render value is false ;
262 | }
263 | },
264 | };
265 | ```
266 |
267 | `switch case` statement
268 |
269 | ```jsx
270 | import Info from './Info';
271 | import Warning from './Warning';
272 | import Error from './Error';
273 | import Success from './Success';
274 |
275 | export default {
276 | data() {
277 | return {
278 | type: 'error',
279 | };
280 | },
281 | render(h) {
282 | switch (this.type) {
283 | case 'info':
284 | return ;
285 | case 'warning':
286 | return ;
287 | case 'error':
288 | return ;
289 | default:
290 | return ;
291 | }
292 | },
293 | };
294 | ```
295 |
296 | or you can use `object` map to simplify `switch case`
297 |
298 | ```jsx
299 | import Info from './Info';
300 | import Warning from './Warning';
301 | import Error from './Error';
302 | import Success from './Success';
303 |
304 | const COMPONENT_MAP = {
305 | info: Info,
306 | warning: Warning,
307 | error: Error,
308 | success: Success,
309 | };
310 |
311 | export default {
312 | data() {
313 | return {
314 | type: 'error',
315 | };
316 | },
317 | render(h) {
318 | const Comp = COMPONENT_MAP[this.type || 'success'];
319 |
320 | return ;
321 | },
322 | };
323 | ```
324 |
325 | `ternary` operator
326 |
327 | ```jsx
328 | export default {
329 | data() {
330 | return {
331 | isTruthy: true,
332 | };
333 | },
334 | render(h) {
335 | return (
336 |
337 | {this.isTruthy ? (
338 |
Render value is true
339 | ) : (
340 | Render value is false
341 | )}
342 |
343 | );
344 | },
345 | };
346 | ```
347 |
348 | `logical` operator
349 |
350 | ```jsx
351 | export default {
352 | data() {
353 | return {
354 | isLoading: true,
355 | };
356 | },
357 | render(h) {
358 | return {this.isLoading &&
Loading ... };
359 | },
360 | };
361 | ```
362 |
363 | #### References
364 |
365 | - [Official - Conditional Rendering](https://vuejs.org/v2/guide/conditional.html)
366 | - [Difference Between v-if and v-show [With Video at End]](https://dzone.com/articles/difference-between-v-if-and-v-show-with-a-video)
367 |
368 | ## Dynamic Component
369 |
370 | ### `` with `is` attribute
371 |
372 | - [Example 1](https://jsfiddle.net/chrisvfritz/o3nycadu/)
373 | - [Example 2](https://jsfiddle.net/chrisvfritz/b2qj69o1/)
374 | - [Example 3](https://alligator.io/vuejs/dynamic-components/)
375 |
376 | ```vue
377 |
378 | ```
379 |
380 | With the above code example, rendered component will be destroyed if a different component is rendered in ``. If you want components to keep their instances without being destroyed within `` tag, you can wrap the `` tag in a `` tag like so:
381 |
382 | ```vue
383 |
384 |
385 |
386 | ```
387 |
388 | #### References
389 |
390 | - [Official - Dynamic Components](https://vuejs.org/v2/guide/components.html#Dynamic-Components)
391 | - [Official - Dynamic & Async Components](https://vuejs.org/v2/guide/components-dynamic-async.html)
392 | - [Dynamic Component Templates with Vue.js](https://medium.com/scrumpy/dynamic-component-templates-with-vue-js-d9236ab183bb)
393 |
394 | ## Composition
395 |
396 | #### Library
397 |
398 | - [Proppy - Functional props composition for components](https://proppyjs.com/)
399 |
400 | ### Basic Composition
401 |
402 | ```vue
403 |
404 |
405 |
406 |
407 |
408 |
409 |
418 | ```
419 |
420 | #### References
421 |
422 | - [Official - Composing with Components](https://vuejs.org/v2/guide/#Composing-with-Components)
423 |
424 | ### Extends
425 |
426 | When you want to extend a single vue component
427 |
428 | ```vue
429 |
430 |
431 | {{buttonText}}
432 |
433 |
434 |
435 |
443 | ```
444 |
445 | #### References:
446 |
447 | - [Official - extends](https://vuejs.org/v2/api/#extends)
448 | - [Extending VueJS Components](https://medium.com/js-dojo/extending-vuejs-components-42fefefc688b)
449 |
450 | ### Mixins
451 |
452 | ```js
453 | // closableMixin.js
454 | export default {
455 | props: {
456 | isOpen: {
457 | default: true,
458 | },
459 | },
460 | data: function() {
461 | return {
462 | shown: this.isOpen,
463 | };
464 | },
465 | methods: {
466 | hide: function() {
467 | this.shown = false;
468 | },
469 | show: function() {
470 | this.shown = true;
471 | },
472 | toggle: function() {
473 | this.shown = !this.shown;
474 | },
475 | },
476 | };
477 | ```
478 |
479 | ```vue
480 |
481 |
482 | {{text}}
483 |
484 |
485 |
486 |
487 |
495 | ```
496 |
497 | #### References:
498 |
499 | - [Official - mixins](https://vuejs.org/v2/guide/mixins.html)
500 | - [Practical use of Components and Mixins in Vue JS](http://www.qcode.in/practical-use-of-components-and-mixins-in-vue-js/)
501 |
502 | ### Slots (Default)
503 |
504 | ```vue
505 |
506 |
507 |
508 |
509 |
510 |
511 |
516 | ```
517 |
518 | ```vue
519 |
520 |
521 |
522 | Login
523 |
524 |
525 |
526 |
535 | ```
536 |
537 | #### References:
538 |
539 | - [Official - Slot Content](https://vuejs.org/v2/guide/components-slots.html#Slot-Content)
540 | - [Understanding Component Slots with Vue.js](https://alligator.io/vuejs/component-slots/)
541 | - [Composing Custom Elements With Slots And Named Slots](https://alligator.io/web-components/composing-slots-named-slots/)
542 | - [Writing Abstract Components with Vue.js](https://alligator.io/vuejs/vue-abstract-components/)
543 |
544 | ### Named Slots
545 |
546 | BaseLayout.vue
547 |
548 | ```vue
549 |
550 |
553 |
554 |
555 |
556 |
559 |
560 | ```
561 |
562 | App.vue
563 |
564 | ```vue
565 |
566 |
567 | Here might be a page title
568 |
569 |
570 | A paragraph for the main content.
571 | And another one.
572 |
573 |
574 | Here's some contact info
575 |
576 |
577 | ```
578 |
579 | #### References
580 |
581 | - [Official - Named Slots](https://vuejs.org/v2/guide/components-slots.html#Named-Slots)
582 |
583 | ### Scoped Slots
584 |
585 | ```vue
586 |
587 |
588 |
592 |
593 |
594 |
595 | {{ todo.text }}
596 |
597 |
598 |
599 |
600 |
601 |
612 | ```
613 |
614 | ```vue
615 |
616 |
617 |
618 | ✓
619 | {{ todo.text }}
620 |
621 |
622 |
623 |
624 |
643 | ```
644 |
645 | #### References:
646 |
647 | - [Official - Scoped Slots](https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots)
648 | - [Getting Your Head Around Vue.js Scoped Slots](https://medium.com/js-dojo/getting-your-head-around-vue-js-scoped-slots-281bf82a1e4e)
649 | - [Understanding scoped slots in Vue.js](https://medium.com/corebuild-software/understanding-scoped-slots-in-vue-js-db5315a42391)
650 | - [Scoped Component Slots in Vue.js](https://alligator.io/vuejs/scoped-component-slots/)
651 | - [The Trick to Understanding Scoped Slots in Vue.js](https://adamwathan.me/the-trick-to-understanding-scoped-slots-in-vuejs/)
652 | - [The Power of Scoped Slots in Vue](https://pineco.de/power-scoped-slots-vue/)
653 | - [Building a list keyboard control component with Vue.js and scoped slots](https://medium.com/@tkwebdev/building-a-list-keyboard-control-component-with-vue-js-and-scoped-slots-c74db4fcf84f)
654 |
655 | ### Render Props
656 |
657 | In most cases, you can use scoped slots instead of render props. But, it might be useful in some case.
658 |
659 | with `SFC`
660 |
661 | ```vue
662 |
663 |
664 |
665 |
666 |
667 |
668 |
686 |
693 | ```
694 |
695 | with `JSX`
696 |
697 | ```js
698 | const Mouse = {
699 | name: 'Mouse',
700 | props: {
701 | render: {
702 | type: Function,
703 | required: true,
704 | },
705 | },
706 | data() {
707 | return {
708 | x: 0,
709 | y: 0,
710 | };
711 | },
712 | methods: {
713 | handleMouseMove(event) {
714 | this.x = event.clientX;
715 | this.y = event.clientY;
716 | },
717 | },
718 | render(h) {
719 | return (
720 |
721 | {this.$props.render(this)}
722 |
723 | );
724 | },
725 | };
726 |
727 | export default Mouse;
728 | ```
729 |
730 | #### References:
731 |
732 | - [Official - Render Functions & JSX](https://vuejs.org/v2/guide/render-function.html)
733 | - [Leveraging Render Props in Vue](https://medium.com/@dillonchanis/leveraging-render-props-in-vue-7eb9a19c262d)
734 | - [Use a Vue.js Render Prop!](https://medium.com/js-dojo/use-a-vue-js-render-prop-98880bc44e05)
735 |
736 | ## Passing Props & Listeners
737 |
738 | Sometimes, you may want to pass props and listeners to child component without having to declare all child component's props.
739 | You can bind `$attrs` and `$listeners` in child component and set [`inheritAttrs` to `false`](https://vuejs.org/v2/api/#inheritAttrs) (otherwise both, `div` and `child-component` will receive the attributes)
740 |
741 | #### PassingProps.vue
742 |
743 | <<< @/docs/.vuepress/components/PassingProps.vue
744 |
745 | From parent component, you can do like this:
746 |
747 | #### PassedProps.vue
748 |
749 | <<< @/docs/.vuepress/components/PassedProps.vue
750 |
751 | #### Working Example:
752 |
753 |
754 |
755 | #### References:
756 |
757 | - [Transparent Wrapper Components in Vue](https://zendev.com/2018/05/31/transparent-wrapper-components-in-vue.html)
758 |
759 | ## Higher Order Component (a.k.a. HOC)
760 |
761 | #### References:
762 |
763 | - [Higher Order Components in Vue.js](https://medium.com/bethink-pl/higher-order-components-in-vue-js-a79951ac9176)
764 | - [Do we need Higher Order Components in Vue.js?](https://medium.com/bethink-pl/do-we-need-higher-order-components-in-vue-js-87c0aa608f48)
765 | - [Higher-Order Components in Vue.js](https://medium.com/tldr-tech/higher-order-components-in-vue-js-38b500c6d49f)
766 |
767 | ## Dependency injection
768 |
769 | Vue supports provide / inject mechanism to provide `object` into all its descendants, regardless of how deep the component hierarchy is, as long as they are in the same parent chain. Notice that `provide` and `inject` bindings are **not** reactive, unless you pass down an observed object.
770 |
771 | ```vue
772 |
773 |
774 |
775 |
776 |
777 | ```
778 |
779 | With above example component hierarchy, in order to derive data from `parent-component`, you should pass down data(object) as `props` to `child-component` and `grand-child-component`. However, if `parent-component` `provide` data(object), `grand-child-component` can just define `inject` provided object from `parent-component`.
780 |
781 | #### References:
782 |
783 | - [Official API](https://vuejs.org/v2/api/#provide-inject)
784 | - [Official Guide](https://vuejs.org/v2/guide/components-edge-cases.html#Dependency-Injection)
785 | - [Component Communication](https://alligator.io/vuejs/component-communication/#provide--inject)
786 | - [Dependency Injection in Vue.js App with TypeScript](https://blog.kloud.com.au/2017/03/22/dependency-injection-in-vuejs-app-with-typescript/)
787 |
788 | ### Provide / Inject
789 |
790 | ::: tip
791 | You can also use [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator)'s `@Provide`, `@Inject`
792 | :::
793 |
794 | #### ThemeProvider.vue
795 |
796 | <<< @/docs/.vuepress/components/ThemeProvider.vue
797 |
798 | #### ThemeButton.vue
799 |
800 | <<< @/docs/.vuepress/components/ThemeButton.vue
801 |
802 | ```vue
803 |
804 | Themed Button
805 |
806 | ```
807 |
808 | #### Working Example:
809 |
810 |
811 | Themed Button
812 |
813 |
814 | ## Handling Errors
815 |
816 | ### `errorCaptured` Hook
817 |
818 | #### ErrorBoundary.vue
819 |
820 | <<< @/docs/.vuepress/components/ErrorBoundary.vue
821 |
822 | #### ThrowError.vue
823 |
824 | <<< @/docs/.vuepress/components/ThrowError.vue
825 |
826 | ```vue
827 |
828 |
829 |
830 | ```
831 |
832 | #### Working Example:
833 |
834 |
835 |
836 |
837 |
838 | #### References
839 |
840 | - [Handling Errors in Vue with Error Boundaries](https://medium.com/@dillonchanis/handling-errors-in-vue-with-error-boundaries-91f6ead0093b)
841 | - [Example 1](https://jsfiddle.net/Linusborg/z84wspcg/)
842 |
843 | ## Productivity Tips
844 |
845 | watch on create
846 |
847 | ```js
848 | // don't
849 | created() {
850 | this.fetchUserList();
851 | },
852 | watch: {
853 | searchText: 'fetchUserList',
854 | }
855 | ```
856 |
857 | ```js
858 | // do
859 | watch: {
860 | searchText: {
861 | handler: 'fetchUserList',
862 | immediate: true,
863 | }
864 | }
865 | ```
866 |
--------------------------------------------------------------------------------
/docs/ru/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | heroImage: /learn-vue-logo.png
4 | actionText: Начать →
5 | actionLink: /ru/patterns/
6 | ---
7 |
8 |
17 |
--------------------------------------------------------------------------------
/docs/ru/patterns/README.md:
--------------------------------------------------------------------------------
1 | ## Объявление компонентов
2 |
3 | ### [Однофайловый компонент (сокращенно — SFC)](https://ru.vuejs.org/v2/guide/single-file-components.html) — наиболее распространённый
4 |
5 | <<< @/docs/.vuepress/components/SFCButton.vue
6 |
7 | SFC
8 |
9 | ### Шаблонные строки (или литералы шаблонов в ES6)
10 |
11 | ```js
12 | Vue.component('my-btn', {
13 | template: `
14 |
15 | (clicked - {{count}})
16 |
17 | `,
18 | data() {
19 | return {
20 | text: 'Click me',
21 | };
22 | },
23 | methods: {
24 | data() {
25 | return {
26 | count: 0,
27 | };
28 | },
29 | methods: {
30 | handleClick() {
31 | this.count++;
32 | console.log('clicked', this.count);
33 | },
34 | },
35 | },
36 | });
37 | ```
38 |
39 | ### [Render-функция](https://ru.vuejs.org/v2/guide/render-function.html)
40 |
41 | ```js
42 | Vue.component('my-btn', {
43 | methods: {
44 | data() {
45 | return {
46 | count: 0,
47 | };
48 | },
49 | methods: {
50 | handleClick() {
51 | this.count++;
52 | console.log('clicked', this.count);
53 | },
54 | },
55 | },
56 | render(h) {
57 | return h(
58 | 'button',
59 | {
60 | attrs: {
61 | class: 'btn-primary',
62 | },
63 | on: {
64 | click: this.handleClick,
65 | },
66 | },
67 | this.$slots.default
68 | );
69 | },
70 | });
71 | ```
72 |
73 | ### [JSX](https://ru.vuejs.org/v2/guide/render-function.html#JSX)
74 |
75 | ```jsx
76 | Vue.component('my-btn', {
77 | data() {
78 | return {
79 | text: 'Click me',
80 | };
81 | },
82 | methods: {
83 | handleClick() {
84 | console.log('clicked');
85 | },
86 | },
87 | render() {
88 | return (
89 |
90 | {this.$slots.default}(clicked - {{count}})
91 |
92 | );
93 | },
94 | });
95 | ```
96 |
97 | ### [vue-class-component](https://github.com/vuejs/vue-class-component)
98 |
99 | ```vue
100 |
101 |
102 | (clicked - {{count}})
103 |
104 |
105 |
106 |
120 |
121 |
126 | ```
127 |
128 | #### Ссылки:
129 |
130 | - [🇷🇺 Официальная документация — Однофайловые компоненты](https://ru.vuejs.org/v2/guide/single-file-components.html)
131 | - [🇷🇺 Официальная документация — Render-функции и JSX](https://ru.vuejs.org/v2/guide/render-function.html)
132 | - [🇺🇸 7 способов определения шаблона компонента в VueJS ](https://medium.com/js-dojo/7-ways-to-define-a-component-template-in-vuejs-c04e0c72900d)
133 |
134 | ## Взаимодействие компонента
135 |
136 | ### Входные параметры и события
137 |
138 | В целом, компонент Vue следует однонаправленному потоку данных, то есть входные параметры передаются вниз ([см. официальное руководство](https://ru.vuejs.org/v2/guide/components-props.html#%D0%9E%D0%B4%D0%BD%D0%BE%D0%BD%D0%B0%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9-%D0%BF%D0%BE%D1%82%D0%BE%D0%BA-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85)), а события — наверх. Входные параметры — это данные только для чтения, поэтому невозможно изменить входные параметры дочерних компонентов. При изменении входных параметров, дочерние компоненты будут автоматически повторно отрендерены (входные параметры являются реактивными источниками данных). Дочерние компоненты могут генерировать событие только к непосредственному родительскому компоненту, так что он может изменять `data`, сопоставляемые с `props` дочернего компонента.
139 |
140 | ```vue
141 |
142 | {{text}}
143 |
144 |
145 |
153 | ```
154 |
155 | ```vue
156 |
157 |
158 |
159 |
160 |
176 | ```
177 |
178 | #### Ссылки:
179 |
180 | - [🇷🇺 Официальная документация — Входные параметры](https://vuejs.org/v2/guide/components-props.html)
181 | - [🇺🇸 Паттерны взаимодействия компонента Vue.js](https://alligator.io/vuejs/component-communication/)
182 | - [🇺🇸 Создание пользовательских полей ввода с помощью Vue.js](https://www.smashingmagazine.com/2017/08/creating-custom-inputs-vue-js/)
183 | - [🇺🇸 Взаимодействие дочерних компонентов Vue](https://vegibit.com/vue-sibling-component-communication/)
184 | - [🇺🇸 Управление состоянием во Vue.js](https://medium.com/fullstackio/managing-state-in-vue-js-23a0352b1c87)
185 | - [🇺🇸 Взаимодействие во Vue.js, часть 2: родительский и дочерний компоненты](https://gambardella.info/2017/09/13/vue-js-communication-part-2-parent-child-components/)
186 |
187 | ## Обработка событий компонента
188 |
189 | #### Ссылки:
190 |
191 | - [🇷🇺 Официальная документация — Пользовательские события](https://ru.vuejs.org/v2/guide/components-custom-events.html)
192 | - [🇺🇸 Использование событий Vue для сокращения объявлений входных параметров](https://itnext.io/leveraging-vue-events-to-reduce-prop-declarations-e38f5dce2aaf)
193 | - [🇺🇸 Хуки компонента Vue.js как события](https://alligator.io/vuejs/component-event-hooks/)
194 | - [🇺🇸 Создание глобальной шины событий с помощью Vue.js](https://alligator.io/vuejs/global-event-bus/)
195 | - [🇺🇸 Шина событий Vue.js + Промисы](https://medium.com/@jesusgalvan/vue-js-event-bus-promises-f83e73a81d72)
196 |
197 | ## Условный рендеринг компонента
198 |
199 | ### Директивы (`v-if` / `v-else` / `v-else-if` / `v-show`)
200 |
201 | `v-if`
202 |
203 | ```html
204 | Рендеринг только, если условие v-if равняется true
205 | ```
206 |
207 | Использование `v-if` и `v-else`
208 |
209 | ```html
210 | Рендеринг только, если условие v-if равняется true
211 | Рендеринг только, если условие v-if равняется false
212 | ```
213 |
214 | Использование `v-else-if`
215 |
216 | ```html
217 | Рендеринг только, если `type` равняется `A`
218 | Рендеринг только, если `type` равняется `B`
219 | Рендеринг только, если `type` равняется `C`
220 | Рендеринг если `type` не равен ни `A`, ни `B`, ни `C`
221 | ```
222 |
223 | Использование `v-show`
224 |
225 | ```html
226 | Всегда рендерится, но виден только в том случае, если условия `v-show` равняются true
227 | ```
228 |
229 | Если вы хотите по условию отобразить более одного элемента, вы можете использовать директивы (`v-if` / `v-else` / `v-else-if` /`v-show`) на элементе ``. Обратите внимание, что элемент `` фактические не будет отображаться в DOM. Это как невидимая обёртка.
230 |
231 | ```html
232 |
233 | Все элементы
234 | будут отрендерены в DOM,
235 | за исключением элемента `template`
236 |
237 | ```
238 |
239 | ### Render-функция или JSX
240 |
241 | Если вы используете JSX в своем Vue-приложении, то можете применять все техники, например использования выражения `if else` и `switch case`, а также тернарные и логические операторы.
242 |
243 | Использование выражения `if else`
244 |
245 | ```jsx
246 | export default {
247 | data() {
248 | return {
249 | isTruthy: true,
250 | };
251 | },
252 | render(h) {
253 | if (this.isTruthy) {
254 | return Рендеринг, если значение равно true ;
255 | } else {
256 | return Рендеринг, если значение равно false ;
257 | }
258 | },
259 | };
260 | ```
261 |
262 | Использование выражения `switch case`
263 |
264 | ```jsx
265 | import Info from './Info';
266 | import Warning from './Warning';
267 | import Error from './Error';
268 | import Success from './Success';
269 |
270 | export default {
271 | data() {
272 | return {
273 | type: 'error',
274 | };
275 | },
276 | render(h) {
277 | switch (this.type) {
278 | case 'info':
279 | return ;
280 | case 'warning':
281 | return ;
282 | case 'error':
283 | return ;
284 | default:
285 | return ;
286 | }
287 | },
288 | };
289 | ```
290 |
291 | Или можно использовать сопоставление с помощью объекта для упрощения выражений `switch case`
292 |
293 | ```jsx
294 | import Info from './Info';
295 | import Warning from './Warning';
296 | import Error from './Error';
297 | import Success from './Success';
298 |
299 | const COMPONENT_MAP = {
300 | info: Info,
301 | warning: Warning,
302 | error: Error,
303 | success: Success,
304 | };
305 |
306 | export default {
307 | data() {
308 | return {
309 | type: 'error',
310 | };
311 | },
312 | render(h) {
313 | const Comp = COMPONENT_MAP[this.type || 'success'];
314 |
315 | return ;
316 | },
317 | };
318 | ```
319 |
320 | Использование тернарного оператора
321 |
322 | ```jsx
323 | export default {
324 | data() {
325 | return {
326 | isTruthy: true,
327 | };
328 | },
329 | render(h) {
330 | return (
331 |
332 | {this.isTruthy ? (
333 |
Рендеринг, если значение равно true
334 | ) : (
335 | Рендеринг, если значение равно false
336 | )}
337 |
338 | );
339 | },
340 | };
341 | ```
342 |
343 | Использование логического оператора
344 |
345 | ```jsx
346 | export default {
347 | data() {
348 | return {
349 | isLoading: true,
350 | };
351 | },
352 | render(h) {
353 | return {this.isLoading &&
Загрузка ... };
354 | },
355 | };
356 | ```
357 | #### Ссылки
358 |
359 | - [🇷🇺 Официальная документация — Условный рендеринг](https://vuejs.org/v2/guide/conditional.html)
360 | - [🇺🇸 Разница между v-if и v-show [с видео в конце]](https://dzone.com/articles/difference-between-v-if-and-v-show-with-a-video)
361 |
362 | ## Динамический компонент
363 |
364 | ### `` с атрибутом `is`
365 |
366 | - [Пример 1](https://jsfiddle.net/chrisvfritz/o3nycadu/)
367 | - [Пример 2](https://jsfiddle.net/chrisvfritz/b2qj69o1/)
368 | - [Пример 3](https://alligator.io/vuejs/dynamic-components/)
369 |
370 | ```html
371 |
372 | ```
373 |
374 | В приведённом выше примере отрендеренный компонент будет уничтожаться, если другой компонент должен будет рендериться в ``. Если необходимо, чтобы компоненты сохраняли свои экземпляры без их уничтожения в теге ``, можно обернуть `` в тег ``:
375 |
376 | ```html
377 |
378 |
379 |
380 | ```
381 |
382 | #### Ссылки
383 |
384 | - [🇷🇺 Официальная документация — Динамические компоненты](https://vuejs.org/v2/guide/components.html#Dynamic-Components)
385 | - [🇷🇺 Официальная документация — Динамические и асинхронные компоненты](https://vuejs.org/v2/guide/components-dynamic-async.html)
386 | - [🇺🇸 Шаблоны динамических компонентов с Vue.js](https://medium.com/scrumpy/dynamic-component-templates-with-vue-js-d9236ab183bb)
387 |
388 | ## Композиция
389 |
390 | #### Библиотека
391 |
392 | - [Proppy - Functional props composition for components](https://proppyjs.com/)
393 |
394 | ### Простой пример композиции
395 |
396 | ```html
397 |
398 |
399 |
400 |
401 |
402 |
403 |
412 | ```
413 |
414 | #### Ссылки
415 |
416 | - [🇷🇺 Официальная документация — Разбиение приложения на компоненты](https://ru.vuejs.org/v2/guide/index.html#%D0%A0%D0%B0%D0%B7%D0%B1%D0%B8%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BD%D0%B0-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82%D1%8B)
417 |
418 | ### Расширение компонента
419 |
420 | Если вы хотите расширить один Vue-компонент, можно поступить следующим образом:
421 |
422 | ```html
423 |
424 |
425 | {{buttonText}}
426 |
427 |
428 |
429 |
437 | ```
438 |
439 | #### Ссылки:
440 |
441 | - [🇷🇺 Официальная документация — extends](https://ru.vuejs.org/v2/api/#extends)
442 | - [🇺🇸 Расширение компонентов VueJS](https://medium.com/js-dojo/extending-vuejs-components-42fefefc688b)
443 |
444 | ### Примеси
445 |
446 | ```js
447 | // closableMixin.js
448 | export default {
449 | props: {
450 | isOpen: {
451 | default: true
452 | }
453 | },
454 | data: function() {
455 | return {
456 | shown: this.isOpen
457 | }
458 | },
459 | methods: {
460 | hide: function() {
461 | this.shown = false;
462 | },
463 | show: function() {
464 | this.shown = true;
465 | },
466 | toggle: function() {
467 | this.shown = !this.shown;
468 | }
469 | }
470 | }
471 | ```
472 |
473 | ```html
474 |
475 |
476 | {{ text }}
477 |
478 |
479 |
480 |
481 |
489 | ```
490 |
491 | #### Ссылки:
492 |
493 | - [🇷🇺 Официальная документация — mixins](https://ru.vuejs.org/v2/guide/mixins.html)
494 | - [🇺🇸 Практическое использование компонентов и примисей в Vue JS](http://www.qcode.in/practical-use-of-components-and-mixins-in-vue-js/)
495 |
496 | ### Слоты (по умолчанию)
497 |
498 | ```html
499 |
500 |
501 |
502 |
503 |
504 |
505 |
510 | ```
511 |
512 | ```html
513 |
514 |
515 |
516 | Логин
517 |
518 |
519 |
520 |
529 | ```
530 |
531 | #### Ссылки:
532 |
533 | - [🇷🇺 Официальная документация — Содержимое слотов](https://ru.vuejs.org/v2/guide/components-slots.html#%D0%A1%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%BC%D0%BE%D0%B5-%D1%81%D0%BB%D0%BE%D1%82%D0%BE%D0%B2)
534 | - [🇺🇸 Понимание слотов компонентов с помощью Vue.js](https://alligator.io/vuejs/component-slots/)
535 | - [🇺🇸 Составление пользовательских элементов с помощью слотов и именованными слотами](https://alligator.io/web-components/composing-slots-named-slots/)
536 | - [🇺🇸 Написание абстрактных компонентов во Vue.js](https://alligator.io/vuejs/vue-abstract-components/)
537 | ([🇷🇺 перевод](https://medium.com/devschacht/vue-abstract-components-bc4bc2b89baf))
538 |
539 | ### Именованные слоты
540 |
541 | BaseLayout.vue
542 |
543 | ```html
544 |
545 |
548 |
549 |
550 |
551 |
554 |
555 | ```
556 |
557 | App.vue
558 |
559 | ```html
560 |
561 |
562 | Здесь может быть заголовок страницы
563 |
564 |
565 | Абзац для основного контента.
566 | И еще один.
567 |
568 |
569 | Здесь некоторые контактные данные
570 |
571 |
572 | ```
573 |
574 | #### Ссылки
575 |
576 | - [🇷🇺 Официальная документация — Именованные слоты](https://ru.vuejs.org/v2/guide/components-slots.html#%D0%98%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D1%81%D0%BB%D0%BE%D1%82%D1%8B)
577 |
578 | ### Слоты с ограниченной областью видимости
579 |
580 | ```html
581 |
582 |
583 |
587 |
588 |
589 |
590 | {{ todo.text }}
591 |
592 |
593 |
594 |
595 |
596 |
607 | ```
608 |
609 | ```html
610 |
611 |
612 |
613 | ✓
614 | {{ todo.text }}
615 |
616 |
617 |
618 |
619 |
638 | ```
639 |
640 | #### Ссылки:
641 |
642 | - [🇷🇺 Официальная документация — Слоты с ограниченной областью видимости](https://ru.vuejs.org/v2/guide/components-slots.html#%D0%A1%D0%BB%D0%BE%D1%82%D1%8B-%D1%81-%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9-%D0%BE%D0%B1%D0%BB%D0%B0%D1%81%D1%82%D1%8C%D1%8E-%D0%B2%D0%B8%D0%B4%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8)
643 | - [🇺🇸 Разбираемся со слотами с ограниченной областью видимости](https://medium.com/js-dojo/getting-your-head-around-vue-js-scoped-slots-281bf82a1e4e)
644 | - [🇺🇸 Понимание слотов с ограниченной областью видимости во Vue.js](https://medium.com/corebuild-software/understanding-scoped-slots-in-vue-js-db5315a42391)
645 | - [🇺🇸 Слоты с ограниченной областью видимости компонента во Vue.js](https://alligator.io/vuejs/scoped-component-slots/)
646 | - [🇺🇸 Трюк к пониманию слотов с ограниченной областью видимости во Vue.js](https://adamwathan.me/the-trick-to-understanding-scoped-slots-in-vuejs/)
647 | - [🇺🇸 Мощность слотов в Vue](https://pineco.de/power-scoped-slots-vue/)
648 | - [🇺🇸 Создание компонента, управляемого с клавиатуры, списка с помощью Vue.js и слотов с ограниченной областью видимости](https://medium.com/@tkwebdev/building-a-list-keyboard-control-component-with-vue-js-and-scoped-slots-c74db4fcf84f)
649 |
650 | ### Render Props
651 |
652 | В большинстве случаев вы можете использовать слоты с ограниченной областью видимости вместо рендеринга входных параметров. Но в некоторых случаях это может быть полезно.
653 |
654 | С однофайловым компонентом `SFC`
655 |
656 | ```vue
657 |
658 |
659 |
660 |
661 |
662 |
663 |
681 |
688 | ```
689 |
690 | С использованием `JSX`
691 |
692 | ```js
693 | const Mouse = {
694 | name: 'Mouse',
695 | props: {
696 | render: {
697 | type: Function,
698 | required: true,
699 | },
700 | },
701 | data() {
702 | return {
703 | x: 0,
704 | y: 0,
705 | };
706 | },
707 | methods: {
708 | handleMouseMove(event) {
709 | this.x = event.clientX;
710 | this.y = event.clientY;
711 | },
712 | },
713 | render(h) {
714 | return (
715 |
716 | {this.$props.render(this)}
717 |
718 | );
719 | },
720 | };
721 |
722 | export default Mouse;
723 | ```
724 |
725 | #### Ссылки:
726 |
727 | - [🇷🇺 Официальная документация — Render Functions & JSX](https://vuejs.org/v2/guide/render-function.html)
728 | - [🇺🇸 Использование рендеринга входных параметров в Vue](https://medium.com/@dillonchanis/leveraging-render-props-in-vue-7eb9a19c262d)
729 | - [🇺🇸 Использование рендеринга входных параметров Vue.js!](https://medium.com/js-dojo/use-a-vue-js-render-prop-98880bc44e05)
730 |
731 | ## Передача входных параметров
732 |
733 | Иногда вам может понадобиться передать входные параметры и обработчики дочернему компоненту, не объявляя всех входных параметров дочернего компонента. Вы можете привязать `$attrs` и `$listeners` в дочернем компоненте и установить [`inheritAttrs` на `false`](https://ru.vuejs.org/v2/api/#inheritAttrs) (в противном случае `div` и `child-component` получат атрибуты).
734 |
735 | #### PassingProps.vue
736 |
737 | <<< @/docs/.vuepress/components/PassingProps.vue
738 |
739 | Из родительского компонента вы можете сделать следующее:
740 |
741 | #### PassedProps.vue
742 |
743 | <<< @/docs/.vuepress/components/PassedProps.vue
744 |
745 | #### Рабочий пример:
746 |
747 |
748 |
749 | #### Ссылки:
750 |
751 | - [🇺🇸 Прозрачные компоненты-обёртки во Vue](https://zendev.com/2018/05/31/transparent-wrapper-components-in-vue.html)
752 |
753 | ## Компоненты высшего порядка (они же HOC)
754 |
755 | #### Ссылки:
756 |
757 | - [🇺🇸 Компоненты высшего порядка Vue.js](https://medium.com/bethink-pl/higher-order-components-in-vue-js-a79951ac9176)
758 | - [🇺🇸 Нужны ли нам компоненты высшего порядка порядка во Vue.js?](https://medium.com/bethink-pl/do-we-need-higher-order-components-in-vue-js-87c0aa608f48)
759 | - [🇺🇸 Компоненты высшего порядка во Vue.js](https://medium.com/tldr-tech/higher-order-components-in-vue-js-38b500c6d49f)
760 |
761 |
762 | ## Внедрение зависимостей
763 |
764 | Vue поддерживает механизм предоставления и внедрения объекта во всех потомки, независимо от глубины иерархии компонентов, при условии, что компоненты находятся в одной и той же цепочке родителей. Обратите внимание, что привязки `provide` и `inject` **не являются*- реактивными, пока вы не передадите наблюдаемый объект.
765 |
766 | ```vue
767 |
768 |
769 |
770 |
771 |
772 | ```
773 |
774 | С приведенной выше иерархией компонентов в качестве примера для получения данных из `parent-component` вам нужно передавать данные (объект) в качестве `props` компоненту `child-component` и компоненту `grand-child-component`. Однако, если `parent-component` предоставляет (`provide`) данные (объект), `grand-child-component` может просто определить свойство `inject` для получения объекта, предоставляемого `parent-component`.
775 |
776 | #### Ссылки:
777 |
778 | - [🇷🇺 Официальный API](https://vuejs.org/v2/api/#provide-inject)
779 | - [🇷🇺 Официальное руководство](https://ru.vuejs.org/v2/guide/components-edge-cases.html#%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B5%D0%B9)
780 | - [🇺🇸 Взаимодействие компонента](https://alligator.io/vuejs/component-communication/#provide--inject)
781 | - [🇺🇸 Внедрение зависимостей в приложении Vue.js с TypeScript](https://blog.kloud.com.au/2017/03/22/dependency-injection-in-vuejs-app-with-typescript/)
782 |
783 |
784 | ### Provide / Inject
785 |
786 | ::: tip
787 | Вы также можете использовать `@Provide`, `@Inject` из [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator)
788 | :::
789 |
790 | #### ThemeProvider.vue
791 |
792 | <<< @/docs/.vuepress/components/ThemeProvider.vue
793 |
794 | #### ThemeButton.vue
795 |
796 | <<< @/docs/.vuepress/components/ThemeButton.vue
797 |
798 | ```vue
799 |
800 | Themed Button
801 |
802 | ```
803 |
804 | #### Working Example:
805 |
806 |
807 | Themed Button
808 |
809 |
810 | ## Обработка ошибок
811 |
812 | ### Хук `errorCaptured`
813 |
814 | #### ErrorBoundary.vue
815 |
816 | <<< @/docs/.vuepress/components/ErrorBoundary.vue
817 |
818 | #### ThrowError.vue
819 |
820 | <<< @/docs/.vuepress/components/ThrowError.vue
821 |
822 | ```vue
823 |
824 |
825 |
826 | ```
827 |
828 | #### Рабочий пример:
829 |
830 |
831 |
832 |
833 |
834 | #### References
835 |
836 | - [🇺🇸 Обработка ошибок в Vue с границами ошибок](https://medium.com/@dillonchanis/handling-errors-in-vue-with-error-boundaries-91f6ead0093b)
837 | - [Пример 1](https://jsfiddle.net/Linusborg/z84wspcg/)
838 |
839 | ## Советы по продуктивности
840 |
841 | Наблюдение при создании
842 |
843 | ```js
844 | // don't
845 | created() {
846 | this.fetchUserList();
847 | },
848 | watch: {
849 | searchText: 'fetchUserList',
850 | }
851 | ```
852 |
853 | ```js
854 | // do
855 | watch: {
856 | searchText: {
857 | handler: 'fetchUserList',
858 | immediate: true,
859 | }
860 | }
861 | ```
862 |
--------------------------------------------------------------------------------
/docs/ru/sponsors/README.md:
--------------------------------------------------------------------------------
1 | [](https://gumroad.com/a/462206067)
2 |
--------------------------------------------------------------------------------
/docs/ru/translations/README.md:
--------------------------------------------------------------------------------
1 | - [简体中文](https://github.com/ZYSzys/vue-patterns-cn)
2 | - [繁體中文](https://github.com/yoyoys/vue-patterns-cht)
3 |
--------------------------------------------------------------------------------
/docs/ru/useful-links/README.md:
--------------------------------------------------------------------------------
1 | ### Руководство по стилю
2 |
3 | - [🇷🇺 Официальная документация — Рекомендации](https://ru.vuejs.org/v2/style-guide/)
4 | - [🇷🇺 Руководство по разработке компонентов Vue.js](https://github.com/pablohpsilva/vuejs-component-style-guide/blob/master/README-RU.md)
5 |
6 | ### Рефакторинг
7 |
8 | - [🇺🇸 Рефакторинг Vue: очистка списка сообщений с лучшим разделением компонентов и с большим количеством ES6](https://mattstauffer.com/blog/refactoring-vue-cleaning-up-a-list-of-posts-with-better-component-splitting-and-more-es6/)
9 | - [🇺🇸 Очистка модулей Vue с помощью стрелочных функций ES6](https://gist.github.com/JacobBennett/7b32b4914311c0ac0f28a1fdc411b9a7)
10 | - [🇺🇸 Примеры чистого кода Vue](https://webdesign.tutsplus.com/tutorials/examples-of-vues-clean-code--cms-29619)
11 | - [🇺🇸 Оптимизация производительности с помощью вычисляемых свойств](https://codingexplained.com/coding/front-end/vue-js/optimizing-performance-computed-properties)
12 | - [🇺🇸 Упрощение компонентов с помощью вычисляемых сеттеров](https://tahazsh.com/vuebyte-computed-setters)
13 |
14 | ### Управление состоянием
15 |
16 | - [🇺🇸 Управление состоянием во Vue.js](https://medium.com/fullstackio/managing-state-in-vue-js-23a0352b1c87)
17 |
18 | ### Vuex
19 |
20 | - [🇺🇸 Разделение модулей Vuex с паттерном «Посредник»](https://itnext.io/decouple-vuex-actions-with-the-mediator-pattern-58a8879de1b4)
21 | - [🇺🇸 Геттеры Vuex великолепны, но не злоупотребляйте ими](https://codeburst.io/vuex-getters-are-great-but-dont-overuse-them-9c946689b414)
22 | - [🇺🇸 Повторное использование функций-мутаций Vuex](https://itnext.io/reusable-vuex-mutation-functions-9b4920aa737b)
23 | - [🇺🇸 Паттерн для обработки AJAX-запросов в Vuex](https://medium.com/@lachlanmiller_52885/a-pattern-to-handle-ajax-requests-in-vuex-2d69bc2f8984)
24 | - [🇺🇸 Одиночные изменения мутацией Vuex vs. принципа единственной ответственности](https://forum.vuejs.org/t/vuex-mutations-single-changes-vs-single-responsibility/16396)
25 | - [🇺🇸 Компоненты и способы взаимодействия в Vue и Vuex](https://dzone.com/articles/how-do-components-interact-in-vue-and-what-is-vuex)
26 | - [🇺🇸 Почему VueX — идеальный интерфейс между фронтендом и API](https://codeburst.io/why-vuex-is-the-perfect-interface-between-frontend-and-api-271d92161709)
27 | - [🇺🇸 Композиция действий с Vuex](https://codeburst.io/composing-actions-with-vuex-b63466264a37)
28 | - [🇺🇸 Как создавать сложные, крупномасштабные приложения Vue.js с Vuex](https://code.tutsplus.com/tutorials/how-to-build-complex-large-scale-vuejs-applications-with-vuex--cms-30952)
29 | - [🇺🇸 Должен ли я хранить данные в Vuex?](https://markus.oberlehner.net/blog/should-i-store-this-data-in-vuex/)
30 | - [🇺🇸 В общем, это как использовать v-model с Vuex. Вычисляемый сеттер в действии.](https://itnext.io/anyway-this-is-how-to-use-v-model-with-vuex-computed-setter-in-action-320eb682c976)
31 | - [🇺🇸 5 Vuex-плагинов для вашего следующего проекта на VueJS](https://medium.com/js-dojo/5-vuex-plugins-for-your-next-vuejs-project-df9902a70de2)
32 |
33 | ### MobX
34 |
35 | - [🇺🇸 Создайте уровень данных представления без фреймворка на основе MobX — интеграция с Vue (1)](https://itnext.io/build-a-view-framework-free-data-layer-based-on-mobx-integration-with-vue-1-8b524b86c7b8)
36 |
37 | ### Компоненты без рендеринга
38 |
39 | - [🇺🇸 Компоненты без рендеринга во Vue.js](https://adamwathan.me/renderless-components-in-vuejs/) ([🇷🇺 перевод](https://webformyself.com/renderless-components-rabota-s-komponentami-vo-vue-js/))
40 | - [🇺🇸 Создание компонентов без рендеринга для обработки CRUD-операций во Vue.js](https://markus.oberlehner.net/blog/building-renderless-components-to-handle-crud-operations-in-vue/)
41 |
42 | #### Примеры
43 |
44 | - [Компонент календаря без рендеринга](https://codesandbox.io/s/v65lx0xvy5)
45 |
46 | ### Структура каталогов
47 |
48 | - [🇺🇸 Как улучшить рабочий процесс с помощью консоли JavaScript](https://medium.freecodecamp.org/how-you-can-improve-your-workflow-using-the-javascript-console-bdd7823a9472) ([🇷🇺 перевод](https://habr.com/company/ruvds/blog/414375/))
49 | - [🇺🇸 Как структурировать проект Vue.js](https://itnext.io/how-to-structure-a-vue-js-project-29e4ddc1aeeb)
50 | - [🇺🇸 Крупномасштабная структура приложения Vuex](https://medium.com/3yourmind/large-scale-vuex-application-structures-651e44863e2f)
51 | - [🇺🇸 Структура приложения Vue.js и архитектура CSS](https://markus.oberlehner.net/blog/vue-application-structure-and-css-architecture/)
52 | - [🇺🇸 Создание структуры Vue-компонентов](https://vueschool.io/articles/vuejs-tutorials/structuring-vue-components/)
53 |
54 | ### Советы и хитрости
55 |
56 | - [🇺🇸 Как создать Vue-компоненты, как и профессионал 😎](https://blog.bitsrc.io/how-to-build-vue-components-like-a-pro-fd89fd4d524d)
57 | - [🇺🇸 4 совета по работе с Vue.js](https://itnext.io/four-tips-for-working-with-vue-js-b362d97de852) ([🇷🇺 перевод](https://habr.com/post/352540/))
58 | - [🇺🇸 Советы для непритязательного разработчика VueJS](https://medium.com/@denny.headrick/tips-from-a-lowly-vuejs-developer-381b6956aece)
59 | - [🇺🇸 Throttle и debounce событий с помощью Vue и lodash](https://alligator.io/vuejs/lodash-throttle-debounce/)
60 | - [🇺🇸 Возможны ли частично применимые функции в обработчиках событий?](https://forum.vuejs.org/t/are-partially-applied-functions-in-event-handlers-possible/10187)
61 | - [🇺🇸 Vue.js — соображения и трюки](https://blog.webf.zone/vue-js-considerations-and-tricks-fa7e0e4bb7bb) ([🇷🇺 перевод](https://medium.com/devschacht/vue-js-considerations-and-tricks-58ec768ac237
62 | ))
63 | - [🇺🇸 Шесть случайных пробел и их решения в VueJS](https://medium.com/@stijlbreuk/six-random-issues-and-their-solutions-in-vuejs-b16d470a6462)
64 | - [🇺🇸 Когда VueJS не может помочь вам](https://vuejsdevelopers.com/2017/05/01/vue-js-cant-help-head-body/)
65 | - [🇺🇸 То, что не будет работать с использованием Vue](https://winnercrespo.com/things-that-wont-work-using-vue/)
66 | - [🇺🇸 Трюк#15 Отложенное выполнение с _.debounce](https://medium.com/vuejs-tips/tip-15-delay-execution-with-debounce-6a93b759bb06)
67 | - [🇺🇸 Обработка API-вызовов во Vue](https://medium.com/@imanhodjaev/handling-api-calls-in-vue-cf39747656ba)
68 | - [🇺🇸 Слайды - Паттерны Vue & REST API](https://speakerdeck.com/imanhodjaev/vue-and-rest-api-patterns)
69 |
70 | ### Маршрутизатор
71 |
72 | - [🇺🇸 Навигационные хуки - Официальная документация](https://router.vuejs.org/ru/guide/advanced/navigation-guards.html#%D0%B3n%D0%BE%D0%B1%D0%B0n%D1%8C%D0%BD%D1%8B%D0%B5-%D1%85%D1%83%D0%BA%D0%B8)
73 | - [🇺🇸 Навигационные хуки Vue-маршрутизатора с Vuex](https://serversideup.net/vue-router-navigation-guards-vuex/)
74 |
75 | ### Антипаттерны
76 |
77 | - [🇺🇸 Крис Фриц (Chris Fritz) - Антипаттерны Vue.js (и как их избежать)](http://www.fullstackradio.com/87)
78 | - [🇺🇸 Распространённые ошибки, которые следует избегать при работе с Vue.js](https://medium.freecodecamp.org/common-mistakes-to-avoid-while-working-with-vue-js-10e0b130925b)
79 | - [🇺🇸 Избегайте этого распространённого антипаттерна в приложениях с полным стеком Vue / Laravel](https://vuejsdevelopers.com/2017/08/06/vue-js-laravel-full-stack-ajax/)
80 | - [🇺🇸 [Видео] - VueNYC - Три запаха кода Vue, и что вы можете с ними поделать- Matt Rothenberg (@mattrothenberg)](https://www.youtube.com/watch?v=z5UWVOeIsUQ)
81 |
82 | ### Видео / Аудио
83 |
84 | - [🇺🇸 81: Evan You - Продвинутый дизайн Vue-компонента](https://player.fm/series/series-1401837/81-evan-you-advanced-vue-component-design)
85 | - [🇺🇸 7 секретных шаблонов, про которые Vue-консультанты не хотели бы, чтобы вы о них знали](https://www.youtube.com/watch?v=7YZ5DwlLSt8)
86 |
87 | ### Репозитории
88 |
89 | - [🇺🇸 vue-enterprise-boilerplate](https://github.com/chrisvfritz/vue-enterprise-boilerplate)
90 | - [🇺🇸 7-secret-patterns](https://github.com/chrisvfritz/7-secret-patterns)
91 | - [🇺🇸 Vue.js-2-Design-Patterns-and-Best-Practices](https://github.com/PacktPublishing/Vue.js-2-Design-Patterns-and-Best-Practices)
92 |
93 | ### Платное
94 |
95 | - [🇺🇸 Продвинутый дизайн Vue-компонентов](https://adamwathan.me/advanced-vue-component-design/)
96 | - [🇺🇸 Продвинутые возможности Vue.js с нуля](https://frontendmasters.com/courses/advanced-vue/)
97 |
98 | ### TypeScript
99 |
100 | - [🇺🇸 Vue + TypeScript: A Match Made in Your Code Editor](https://css-tricks.com/vue-typescript-a-match-made-in-your-code-editor/)
101 | - [🇺🇸 Написание компонентов на основе классов с помощью Vue.js и TypeScript](https://alligator.io/vuejs/typescript-class-components/)
102 | - [🇺🇸 Написание модулей Vuex в аккуратных классах Typescript](- )
103 |
104 | ### Flowtype
105 |
106 | ### GraphQL
107 |
108 | - [Основы GraphQL с Vue.js](https://medium.com/@lachlanmiller_52885/graphql-basics-and-practical-examples-with-vue-6b649b9685e0)
109 |
110 | ### Тестирование
111 |
112 | - [Корректное тестирование действий с помощью Jest](https://medium.com/js-dojo/testing-vuex-actions-correctly-with-jest-444c277be4fe)
113 |
114 | ---
115 |
116 | ### Разное
117 |
118 | - [🇺🇸 Создание Vue-компонента Interpose на основе реализации из React](https://itnext.io/creating-an-interpose-vue-component-from-a-react-implementation-80d367a695c6)
119 | - [🇺🇸 Составление вычисляемых свойств в Vue.js](https://medium.com/@kevin_peters/composing-computed-properties-in-vue-js-87b4507af079)
120 | - [🇺🇸 4 AJAX-паттерна для приложений Vue.js](https://medium.com/js-dojo/4-ajax-patterns-for-vue-js-apps-add915fc9168)
121 | - [🇺🇸 3 паттерна разделения кода для VueJS и Webpack](https://medium.com/js-dojo/3-code-splitting-patterns-for-vuejs-and-webpack-b8fff1ea0ba4)
122 | - [🇺🇸 Самый простой способ улучшить ваше приложение Vue.js. Часть 1](https://codeburst.io/the-easiest-way-to-improve-your-vue-js-application-part-1-51f068652872)
123 | - [🇺🇸 Использование JSX с Vue и почему вам должно быть не всё равно](https://scotch.io/tutorials/using-jsx-with-vue-and-why-you-should-care?utm_campaign=Revue%20newsletter&utm_medium=Newsletter&utm_source=Vue.js%20News)
124 | - [🇺🇸 Составные компоненты](https://forum.vuejs.org/t/compound-components/30139)
125 | - [🇺🇸 Создание многоуровневых компонентов Vue.js](https://zendev.com/2018/05/07/multi-root-vue-components.html)
126 | - [🇺🇸 Понимание реактивности Vue.js в подробностях с помощью Object.defineProperty()](https://www.timo-ernst.net/blog/2017/07/26/understanding-vue-js-reactivity-depth-object-defineproperty/)
127 | - [🇺🇸 Шаблонизация в Vue: разделение проблем или разделение технологий или что-то еще?](https://medium.com/@s.molinari/templating-separation-of-concerns-or-separation-of-technology-or-something-else-123a3d41f0b4)
128 | - [🇺🇸 Хранение данных компонентов Vue](https://medium.com/@kelin2025/components-stash-f2e14603a874)
129 | - [🇺🇸 Создание многоразовых переходов во Vue](https://vuejsdevelopers.com/2018/02/26/vue-js-reusable-transitions/)
130 | - [🇺🇸 vue-advanced-workshop](https://github.com/d-levin/vue-advanced-workshop)
131 | - [🇺🇸 Сделайте элегантно: Как создать пользовательские интерфейсы, основанные на данных во Vue](https://blog.rangle.io/how-to-create-data-driven-user-interfaces-in-vue/)
132 | - [🇺🇸 Создание экземпляров компонентов Vue.js программным путём](https://css-tricks.com/creating-vue-js-component-instances-programmatically/)
133 | - [🇺🇸 Управление разрешениями пользователей в приложении Vue.js](https://dzone.com/articles/managing-user-permissions-in-a-vuejs-app)
134 | - [🇺🇸 Рендеринг функциональных компонентов во Vue.js](https://alligator.io/vuejs/render-functional-components/)
135 | - [🇺🇸 Проход по свойствам объекта](https://codingexplained.com/coding/front-end/vue-js/looping-object-properties)
136 | - [🇺🇸 Отмена асинхронных операций в Vue.js](https://codeburst.io/cancelling-async-operations-in-vue-js-3d0f3c2de598)
137 | - [🇺🇸 Стили с ограниченной областью видимости с помощью v-html](https://medium.com/@brockreece/scoped-styles-with-v-html-c0f6d2dc5d8e)
138 | - [🇺🇸 Постраничная навигация с помощью с Vuejs](https://medium.com/@obapelumi/pagination-with-vuejs-1f505ce8d15b)
139 | - [🇺🇸 Функция render() — что такое аргумент h](https://css-tricks.com/what-does-the-h-stand-for-in-vues-render-method/) ([🇷🇺 перевод](https://medium.com/devschacht/функция-render-что-такое-аргумент-h-bfc357a82160))
140 | - [🇺🇸 Как писать Vue-компоненты, которые хорошо взаимодействуют](https://vuejsdevelopers.com/2018/06/18/vue-components-play-nicely/) ([🇷🇺 перевод](https://medium.com/devschacht/vue-components-play-nicely-cea6e41afe92))
141 | - [🇺🇸 Создание адаптивных компонентов Vue с помощью ResizeObserver](https://itnext.io/making-adaptive-vue-components-with-resizeobserver-123b5ebb20ae)
142 | - [🇺🇸 Обязательное руководство по формам во Vue.js](https://blog.logrocket.com/an-imperative-guide-to-forms-in-vue-js-7536bfa374e0)
143 | - [🇺🇸 Хороший, спорный, злой Vue.js](https://medium.com/@Pier/vue-js-the-good-the-meh-and-the-ugly-82800bbe6684) ([🇷🇺 перевод](https://proglib.io/p/from-react-to-vue/))
144 | - [🇺🇸 Динамические компоненты шаблона Vue.js](https://markus.oberlehner.net/blog/dynamic-vue-layout-components/)
145 | - [🇺🇸 Продвинутые концепты Vue.js: примиси, пользовательские директивы, фильтры, переходы и управление состоянием](https://blog.logrocket.com/advanced-vue-js-concepts-mixins-custom-directives-filters-transitions-and-state-management-ca6955905156)
146 | - [🇺🇸 Введение паттерна одиночного элемента](https://medium.freecodecamp.org/introducing-the-single-element-pattern-dfbd2c295c5d)
147 | - [🇺🇸 Управление DOM за пределами вашего приложения Vue.js с помощью portal-vue](https://alligator.io/vuejs/portal-vue/)
148 | - [🇺🇸 Добавление i18n и управление переводами сайта на Vue.js](https://medium.com/hypefactors/add-i18n-and-manage-translations-of-a-vue-js-powered-website-73b4511ca69c)
149 | - [🇺🇸 Управление сложными ожиданиями в пользовательских веб-интерфейсах](https://medium.com/@fkadev/managing-complex-waiting-experiences-on-web-uis-29534d2d92a8)
150 | - [🇺🇸 Vue.js — Формы, компоненты и соображения](https://blog.webf.zone/vue-js-forms-components-and-considerations-d81b3ffe9efb)
151 | - [🇺🇸 Повторно используемая логика во Vue-компонентах](https://vueschool.io/articles/vuejs-tutorials/reusing-logic-in-vue-components/)
152 | - [🇺🇸 Рекурсия вложенных с древовидной структурой компонентов во Vue](https://itnext.io/recursion-for-nested-tree-structure-components-in-vue-1cb600005475)
153 |
154 |
--------------------------------------------------------------------------------
/docs/sponsors/README.md:
--------------------------------------------------------------------------------
1 | [](https://gumroad.com/a/462206067)
2 |
--------------------------------------------------------------------------------
/docs/translations/README.md:
--------------------------------------------------------------------------------
1 | - [简体中文](https://github.com/ZYSzys/vue-patterns-cn)
2 | - [繁體中文](https://github.com/yoyoys/vue-patterns-cht)
3 |
--------------------------------------------------------------------------------
/docs/useful-links/README.md:
--------------------------------------------------------------------------------
1 | ### Style Guide
2 |
3 | - [Official - Style Guide](https://vuejs.org/v2/style-guide/)
4 | - [Vue.js Component Style Guide](https://github.com/pablohpsilva/vuejs-component-style-guide)
5 |
6 | ### Refactoring
7 |
8 | - [Refactoring Vue: Cleaning Up a List of Posts With Better Component Splitting and More ES6](https://mattstauffer.com/blog/refactoring-vue-cleaning-up-a-list-of-posts-with-better-component-splitting-and-more-es6/?utm_campaign=Revue%20newsletter&utm_medium=Newsletter&utm_source=Vue.js%20Feed)
9 | - [Clean up your Vue modules with ES6 Arrow Functions](https://gist.github.com/JacobBennett/7b32b4914311c0ac0f28a1fdc411b9a7)
10 | - [Examples of Vue’s Clean Code](https://webdesign.tutsplus.com/tutorials/examples-of-vues-clean-code--cms-29619)
11 | - [Optimizing Performance with Computed Properties](https://codingexplained.com/coding/front-end/vue-js/optimizing-performance-computed-properties)
12 | - [Simplify Your Components with Computed Setters](https://tahazsh.com/vuebyte-computed-setters)
13 |
14 | ### State Management
15 |
16 | - [Managing State in Vue.js](https://medium.com/fullstackio/managing-state-in-vue-js-23a0352b1c87)
17 |
18 | ### Vuex
19 |
20 | - [Decouple Vuex modules with the Mediator pattern](https://itnext.io/decouple-vuex-actions-with-the-mediator-pattern-58a8879de1b4)
21 | - [Vuex getters are great, but don’t overuse them](https://codeburst.io/vuex-getters-are-great-but-dont-overuse-them-9c946689b414)
22 | - [Reusable Vuex Mutation Functions](https://itnext.io/reusable-vuex-mutation-functions-9b4920aa737b)
23 | - [A pattern to handle ajax requests in Vuex](https://medium.com/@lachlanmiller_52885/a-pattern-to-handle-ajax-requests-in-vuex-2d69bc2f8984)
24 | - [[vuex Mutations] Single Changes vs. Single Responsibility](https://forum.vuejs.org/t/vuex-mutations-single-changes-vs-single-responsibility/16396)
25 | - [Components and How They Interact in Vue and Vuex](https://dzone.com/articles/how-do-components-interact-in-vue-and-what-is-vuex)
26 | - [Why VueX Is The Perfect Interface Between Frontend and API](https://codeburst.io/why-vuex-is-the-perfect-interface-between-frontend-and-api-271d92161709)
27 | - [Composing actions with Vuex](https://codeburst.io/composing-actions-with-vuex-b63466264a37)
28 | - [How to Build Complex, Large-Scale Vue.js Apps With Vuex](https://code.tutsplus.com/tutorials/how-to-build-complex-large-scale-vuejs-applications-with-vuex--cms-30952)
29 | - [Should I Store This Data in Vuex?](https://markus.oberlehner.net/blog/should-i-store-this-data-in-vuex/)
30 | - [Anyway, this is how to use v-model with Vuex. Computed setter in action.](https://itnext.io/anyway-this-is-how-to-use-v-model-with-vuex-computed-setter-in-action-320eb682c976)
31 | - [5 Vuex Plugins For Your Next VueJS Project](https://medium.com/js-dojo/5-vuex-plugins-for-your-next-vuejs-project-df9902a70de2)
32 | - [Writing Vuex modules in neat Typescript classes](https://medium.com/coding-blocks/writing-vuex-modules-in-neat-typescript-classes-9bf7b505e7b5)
33 |
34 | ### Mobx
35 |
36 | - [Build A View-Framework-Free Data Layer Based on MobX — Integration With Vue (1)](https://itnext.io/build-a-view-framework-free-data-layer-based-on-mobx-integration-with-vue-1-8b524b86c7b8)
37 |
38 | ### Renderless Component
39 |
40 | - [Renderless Components in Vue.js](https://adamwathan.me/renderless-components-in-vuejs/)
41 | - [Building Renderless Components to Handle CRUD Operations in Vue.js](https://markus.oberlehner.net/blog/building-renderless-components-to-handle-crud-operations-in-vue/)
42 | - [Building “Renderless” Vue Components](https://css-tricks.com/building-renderless-vue-components/)
43 |
44 | #### Examples
45 |
46 | - [Renderless Calendar component](https://codesandbox.io/s/v65lx0xvy5)
47 |
48 | ### Folder Structure
49 |
50 | - [How you can improve your workflow using the JavaScript console](https://medium.freecodecamp.org/how-you-can-improve-your-workflow-using-the-javascript-console-bdd7823a9472)
51 | - [How to Structure a Vue.js Project](https://itnext.io/how-to-structure-a-vue-js-project-29e4ddc1aeeb)
52 | - [Large-scale Vuex application structures](https://medium.com/3yourmind/large-scale-vuex-application-structures-651e44863e2f)
53 | - [Vue.js Application Structure and CSS Architecture](https://markus.oberlehner.net/blog/vue-application-structure-and-css-architecture/)
54 | - [Structuring Vue Components](https://vueschool.io/articles/vuejs-tutorials/structuring-vue-components/)
55 |
56 | ### Tips & Tricks
57 |
58 | - [How To Build Vue Components Like A Pro 😎](https://blog.bitsrc.io/how-to-build-vue-components-like-a-pro-fd89fd4d524d)
59 | - [Four tips for working with Vue.js](https://itnext.io/four-tips-for-working-with-vue-js-b362d97de852)
60 | - [Tips from a Lowly VueJS Developer](https://medium.com/@denny.headrick/tips-from-a-lowly-vuejs-developer-381b6956aece)
61 | - [Throttling and Debouncing Events with Vue.js and lodash](https://alligator.io/vuejs/lodash-throttle-debounce/)
62 | - [Are partially applied functions in event handlers possible?](https://forum.vuejs.org/t/are-partially-applied-functions-in-event-handlers-possible/10187)
63 | - [Vue.js — Considerations and Tricks](https://blog.webf.zone/vue-js-considerations-and-tricks-fa7e0e4bb7bb)
64 | - [Six random issues and their solutions in VueJS.](https://medium.com/@stijlbreuk/six-random-issues-and-their-solutions-in-vuejs-b16d470a6462)
65 | - [When VueJS Can't Help You](https://vuejsdevelopers.com/2017/05/01/vue-js-cant-help-head-body/)
66 | - [Things that won’t work using Vue](https://winnercrespo.com/things-that-wont-work-using-vue/)
67 | - [Tip#15 Delay execution with \_.debounce](https://medium.com/vuejs-tips/tip-15-delay-execution-with-debounce-6a93b759bb06)
68 | - [Handling API calls in Vue](https://medium.com/@imanhodjaev/handling-api-calls-in-vue-cf39747656ba)
69 | - [Slide - Vue & REST API Patterns](https://speakerdeck.com/imanhodjaev/vue-and-rest-api-patterns)
70 |
71 | ### Router
72 |
73 | - [Navigation Guards - Official](https://router.vuejs.org/guide/advanced/navigation-guards.html#global-guards)
74 | - [Vue Router Navigation Guards with Vuex](https://serversideup.net/vue-router-navigation-guards-vuex/)
75 |
76 | ### Anti Patterns
77 |
78 | - [Chris Fritz - Vue.js Anti-Patterns (and How to Avoid Them)](http://www.fullstackradio.com/87)
79 | - [Common mistakes to avoid while working with Vue.js](https://medium.freecodecamp.org/common-mistakes-to-avoid-while-working-with-vue-js-10e0b130925b)
80 | - [Avoid This Common Anti-Pattern In Full-Stack Vue/Laravel Apps](https://vuejsdevelopers.com/2017/08/06/vue-js-laravel-full-stack-ajax/)
81 | - [[Video] - VueNYC - Three Vue code smells, and what you can do about them - Matt Rothenberg (@mattrothenberg)](https://www.youtube.com/watch?v=z5UWVOeIsUQ)
82 |
83 | ### Videos / Audios
84 |
85 | - [81: Evan You - Advanced Vue Component Design](https://player.fm/series/series-1401837/81-evan-you-advanced-vue-component-design)
86 | - [7 Secret Patterns Vue Consultants Don’t Want You to Know](https://www.youtube.com/watch?v=7YZ5DwlLSt8)
87 |
88 | ### Repos
89 |
90 | - [vue-enterprise-boilerplate](https://github.com/chrisvfritz/vue-enterprise-boilerplate)
91 | - [7-secret-patterns](https://github.com/chrisvfritz/7-secret-patterns)
92 | - [Vue.js-2-Design-Patterns-and-Best-Practices](https://github.com/PacktPublishing/Vue.js-2-Design-Patterns-and-Best-Practices)
93 |
94 | ### Paid
95 |
96 | - [Advanced Vue Component Design](https://adamwathan.me/advanced-vue-component-design/)
97 | - [Advanced Vue.js Features from the Ground Up](https://frontendmasters.com/courses/advanced-vue/)
98 |
99 | ### Typescript
100 |
101 | - [Vue + TypeScript: A Match Made in Your Code Editor](https://css-tricks.com/vue-typescript-a-match-made-in-your-code-editor/)
102 | - [Writing Class-Based Components with Vue.js and TypeScript](https://alligator.io/vuejs/typescript-class-components/)
103 | - [Writing Vuex modules in neat Typescript classes](https://medium.com/coding-blocks/writing-vuex-modules-in-neat-typescript-classes-9bf7b505e7b5)
104 |
105 | ### Flowtype
106 |
107 | ### GraphQL
108 |
109 | - [Basics of GraphQL with Vue.js](https://medium.com/@lachlanmiller_52885/graphql-basics-and-practical-examples-with-vue-6b649b9685e0)
110 |
111 | ### Test
112 |
113 | - [Testing Vuex Actions Correctly with Jest](https://medium.com/js-dojo/testing-vuex-actions-correctly-with-jest-444c277be4fe)
114 |
115 | ---
116 |
117 | ### Misc
118 |
119 | - [Creating an Interpose Vue component from a React implementation](https://itnext.io/creating-an-interpose-vue-component-from-a-react-implementation-80d367a695c6)
120 | - [Composing computed properties in Vue.js](https://medium.com/@kevin_peters/composing-computed-properties-in-vue-js-87b4507af079)
121 | - [4 AJAX Patterns For Vue.js Apps](https://medium.com/js-dojo/4-ajax-patterns-for-vue-js-apps-add915fc9168)
122 | - [3 Code Splitting Patterns For VueJS and Webpack](https://medium.com/js-dojo/3-code-splitting-patterns-for-vuejs-and-webpack-b8fff1ea0ba4)
123 | - [The easiest way to improve your Vue.js application. Part 1](https://codeburst.io/the-easiest-way-to-improve-your-vue-js-application-part-1-51f068652872)
124 | - [Using JSX with Vue and Why You Should Care](https://scotch.io/tutorials/using-jsx-with-vue-and-why-you-should-care?utm_campaign=Revue%20newsletter&utm_medium=Newsletter&utm_source=Vue.js%20News)
125 | - [Compound components](https://forum.vuejs.org/t/compound-components/30139)
126 | - [Creating Multi-root Vue.js Components](https://zendev.com/2018/05/07/multi-root-vue-components.html)
127 | - [Understanding Vue.js Reactivity in Depth with Object.defineProperty()](https://www.timo-ernst.net/blog/2017/07/26/understanding-vue-js-reactivity-depth-object-defineproperty/)
128 | - [Templating in Vue: Separation of Concerns or Separation of Technology or something else?](https://medium.com/@s.molinari/templating-separation-of-concerns-or-separation-of-technology-or-something-else-123a3d41f0b4)
129 | - [Stashing Vue components data](https://medium.com/@kelin2025/components-stash-f2e14603a874)
130 | - [Creating Reusable Transitions in Vue](https://vuejsdevelopers.com/2018/02/26/vue-js-reusable-transitions/)
131 | - [vue-advanced-workshop](https://github.com/d-levin/vue-advanced-workshop)
132 | - [Do it with Elegance: How to Create Data-Driven User Interfaces in Vue](https://blog.rangle.io/how-to-create-data-driven-user-interfaces-in-vue/)
133 | - [Creating Vue.js Component Instances Programmatically](https://css-tricks.com/creating-vue-js-component-instances-programmatically/)
134 | - [Managing User Permissions in a Vue.js App](https://dzone.com/articles/managing-user-permissions-in-a-vuejs-app)
135 | - [Render Functional Components in Vue.js](https://alligator.io/vuejs/render-functional-components/)
136 | - [Looping through Object Properties](https://codingexplained.com/coding/front-end/vue-js/looping-object-properties)
137 | - [Cancelling async operations in Vue.js](https://codeburst.io/cancelling-async-operations-in-vue-js-3d0f3c2de598)
138 | - [Scoped styles with v-html](https://medium.com/@brockreece/scoped-styles-with-v-html-c0f6d2dc5d8e)
139 | - [Pagination With Vuejs](https://medium.com/@obapelumi/pagination-with-vuejs-1f505ce8d15b)
140 | - [What does the ‘h’ stand for in Vue’s render method?](https://css-tricks.com/what-does-the-h-stand-for-in-vues-render-method/)
141 | - [How To Build Vue Components That Play Nice](https://vuejsdevelopers.com/2018/06/18/vue-components-play-nicely/)
142 | - [Making responsive Vue components with ResizeObserver](https://itnext.io/making-adaptive-vue-components-with-resizeobserver-123b5ebb20ae)
143 | - [An imperative guide to forms in Vue.js](https://blog.logrocket.com/an-imperative-guide-to-forms-in-vue-js-7536bfa374e0)
144 | - [Vue.js: the good, the meh, and the ugly](https://medium.com/@Pier/vue-js-the-good-the-meh-and-the-ugly-82800bbe6684)
145 | - [Dynamic Vue.js Layout Components](https://markus.oberlehner.net/blog/dynamic-vue-layout-components/)
146 | - [Advanced Vue.js concepts: mixins, custom directives, filters, transitions, and state management](https://blog.logrocket.com/advanced-vue-js-concepts-mixins-custom-directives-filters-transitions-and-state-management-ca6955905156)
147 | - [Introducing the Single Element Pattern](https://medium.freecodecamp.org/introducing-the-single-element-pattern-dfbd2c295c5d)
148 | - [Control DOM Outside Your Vue.js App with portal-vue](https://alligator.io/vuejs/portal-vue/)
149 | - [Add i18n and manage translations of a Vue.js powered website](https://medium.com/hypefactors/add-i18n-and-manage-translations-of-a-vue-js-powered-website-73b4511ca69c)
150 | - [Managing Complex Waiting Experiences on Web UIs](https://medium.com/@fkadev/managing-complex-waiting-experiences-on-web-uis-29534d2d92a8)
151 | - [Vue.js — Forms, components and considerations](https://blog.webf.zone/vue-js-forms-components-and-considerations-d81b3ffe9efb)
152 | - [Reusing Logic in Vue Components](https://vueschool.io/articles/vuejs-tutorials/reusing-logic-in-vue-components/)
153 | - [Recursion for Nested, Tree-Structure Components in Vue](https://itnext.io/recursion-for-nested-tree-structure-components-in-vue-1cb600005475)
154 |
155 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-patterns",
3 | "version": "1.0.0",
4 | "description": "vue-patterns",
5 | "main": "",
6 | "repository": "https://github.com/learn-vuejs/vue-patterns.git",
7 | "author": "ilkwon sim ",
8 | "license": "MIT",
9 | "private": false,
10 | "scripts": {
11 | "docs:dev": "vuepress dev docs",
12 | "docs:build": "vuepress build docs",
13 | "docs:deploy": "gh-pages -d docs/.vuepress/dist"
14 | },
15 | "devDependencies": {
16 | "gh-pages": "^1.2.0",
17 | "vuepress": "^0.13.1"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------