diff --git a/doc/development/fe_guide/style/vue.md b/doc/development/fe_guide/style/vue.md index 4588117f51d0674d222a2957e682c5e2fc398773..6b6ca9a6c71ea3d2f44192a2cf3f3fb1641d5bb6 100644 --- a/doc/development/fe_guide/style/vue.md +++ b/doc/development/fe_guide/style/vue.md @@ -57,6 +57,66 @@ Please check this [rules](https://github.com/vuejs/eslint-plugin-vue#bulb-rules) 1. Use `.vue` for Vue templates. Do not use `%template` in HAML. +1. Explicitly define data being passed into the Vue app + + ```javascript + // bad + return new Vue({ + el: '#element', + components: { + componentName + }, + provide: { + ...someDataset + }, + props: { + ...anotherDataset + }, + render: createElement => createElement('component-name'), + })); + + // good + const { foobar, barfoo } = someDataset; + const { foo, bar } = anotherDataset; + + return new Vue({ + el: '#element', + components: { + componentName + }, + provide: { + foobar, + barfoo + }, + props: { + foo, + bar + }, + render: createElement => createElement('component-name'), + })); + ``` + + We discourage the use of the spread operator in this specific case in + order to keep our codebase explicit, discoverable, and searchable. + This applies in any place where we'll benefit from the above, such as + when [initializing Vuex state](../vuex.md#why-not-just-spread-the-initial-state). + The pattern above also enables us to easily parse non scalar values during + instantiation. + + ```javascript + return new Vue({ + el: '#element', + components: { + componentName + }, + props: { + foo, + bar: parseBoolean(bar) + }, + render: createElement => createElement('component-name'), + })); + ``` + ## Naming 1. **Extensions**: Use `.vue` extension for Vue components. Do not use `.js` as file extension ([#34371](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/34371)). diff --git a/doc/development/fe_guide/vue.md b/doc/development/fe_guide/vue.md index b90566bc2fcd4a297f4e593a4f53a6fbf16d59e9..578c364052e455eacc6fde4f9d742722a2942932 100644 --- a/doc/development/fe_guide/vue.md +++ b/doc/development/fe_guide/vue.md @@ -66,29 +66,32 @@ You should only do this while initializing the application, because the mounted The advantage of providing data from the DOM to the Vue instance through `props` in the `render` function instead of querying the DOM inside the main Vue component is avoiding the need to create a fixture or an HTML element in the unit test, -which will make the tests easier. See the following example: +which will make the tests easier. + +See the following example, also, please refer to our [Vue style guide](style/vue.md#basic-rules) for additional +information on why we explicitly declare the data being passed into the Vue app; ```javascript // haml #js-vue-app{ data: { endpoint: 'foo' }} // index.js -document.addEventListener('DOMContentLoaded', () => new Vue({ - el: '#js-vue-app', - data() { - const dataset = this.$options.el.dataset; - return { - endpoint: dataset.endpoint, - }; - }, +const el = document.getElementById('js-vue-app'); + +if (!el) return false; + +const { endpoint } = el.dataset; + +return new Vue({ + el, render(createElement) { return createElement('my-component', { props: { - endpoint: this.endpoint, + endpoint }, }); }, -})); +} ``` > When adding an `id` attribute to mount a Vue application, please make sure this `id` is unique across the codebase @@ -100,7 +103,7 @@ By following this practice, we can avoid the need to mock the `gl` object, which It should be done while initializing our Vue instance, and the data should be provided as `props` to the main component: ```javascript -document.addEventListener('DOMContentLoaded', () => new Vue({ +return new Vue({ el: '.js-vue-app', render(createElement) { return createElement('my-component', { @@ -109,7 +112,7 @@ document.addEventListener('DOMContentLoaded', () => new Vue({ }, }); }, -})); +}); ``` #### Accessing feature flags diff --git a/doc/development/fe_guide/vuex.md b/doc/development/fe_guide/vuex.md index fb64095bbaae1b20b78a987ceaf891432a0ad3b7..7765ba04d40cffef54b068c6c63d04d50c0d98b2 100644 --- a/doc/development/fe_guide/vuex.md +++ b/doc/development/fe_guide/vuex.md @@ -360,8 +360,8 @@ export default initialState => ({ ``` We've made the conscious decision to avoid this pattern to aid in the -discoverability and searchability of our frontend codebase. The reasoning for -this is described in [this +discoverability and searchability of our frontend codebase. The same applies +when [providing data to a Vue app](vue.md#providing-data-from-haml-to-javascript). The reasoning for this is described in [this discussion](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/56#note_302514865): > Consider a `someStateKey` is being used in the store state. You _may_ not be