├── .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 | [![Vue Patterns](docs/.vuepress/public/vue-patterns-hero.png?raw=true 'Vue Patterns')](https://learn-vuejs.github.io/vue-patterns/) 6 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ErrorBoundary.vue: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /docs/.vuepress/components/GithubStarButton.vue: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /docs/.vuepress/components/PassedProps.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 27 | -------------------------------------------------------------------------------- /docs/.vuepress/components/PassingProps.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 24 | -------------------------------------------------------------------------------- /docs/.vuepress/components/PassingPropsChild.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /docs/.vuepress/components/SFCButton.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 24 | 25 | 38 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ThemeButton.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 28 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ThemeProvider.vue: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /docs/.vuepress/components/ThrowError.vue: -------------------------------------------------------------------------------- 1 | 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 |
9 |

10 | 11 |

12 | 13 | 14 | Fullstack Vue Book 15 | 16 |
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 | 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 | 92 | ); 93 | }, 94 | }); 95 | ``` 96 | 97 | ### [vue-class-component](https://github.com/vuejs/vue-class-component) 98 | 99 | ```vue 100 | 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 | 147 | 148 | 156 | ``` 157 | 158 | ```vue 159 | 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 `