Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
5cb48d36
Commit
5cb48d36
authored
Jul 12, 2018
by
Winnie Hellmann
Committed by
Filipa Lacerda
Jul 12, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove old service architecture from Vue docs
parent
0399b644
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
11 additions
and
228 deletions
+11
-228
doc/development/fe_guide/img/vue_arch.png
doc/development/fe_guide/img/vue_arch.png
+0
-0
doc/development/fe_guide/vue.md
doc/development/fe_guide/vue.md
+11
-228
No files found.
doc/development/fe_guide/img/vue_arch.png
deleted
100644 → 0
View file @
0399b644
9.62 KB
doc/development/fe_guide/vue.md
View file @
5cb48d36
...
@@ -2,27 +2,24 @@
...
@@ -2,27 +2,24 @@
To get started with Vue, read through
[
their documentation
][
vue-docs
]
.
To get started with Vue, read through
[
their documentation
][
vue-docs
]
.
##
Vue architecture
##
Examples
All new features built with Vue.js must follow a
[
Flux architecture
][
flux
]
.
What is described in the following sections can be found in these examples:
The main goal we are trying to achieve is to have only one data flow and only one data entry.
In order to achieve this goal, you can either use
[
vuex
](
#vuex
)
or use the
[
store pattern
][
state-management
]
, explained below:
Each Vue bundle needs a Store - where we keep all the data -, a Service - that we use to communicate with the server - and a main Vue component.
-
web ide: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/assets/javascripts/ide/stores
-
security products: https://gitlab.com/gitlab-org/gitlab-ee/tree/master/ee/app/assets/javascripts/vue_shared/security_reports
-
registry: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/assets/javascripts/registry/stores
Think of the Main Vue Component as the entry point of your application. This is the only smart
## Vue architecture
component that should exist in each Vue feature.
This component is responsible for:
1.
Calling the Service to get data from the server
1.
Calling the Store to store the data received
1.
Mounting all the other components
![
Vue Architecture
](
img/vue_arch.png
)
All new features built with Vue.js must follow a
[
Flux architecture
][
flux
]
.
The main goal we are trying to achieve is to have only one data flow and only one data entry.
In order to achieve this goal we use
[
vuex
](
#vuex
)
.
You can also read about this architecture in vue docs about
[
state management
][
state-management
]
You can also read about this architecture in vue docs about
[
state management
][
state-management
]
and about
[
one way data flow
][
one-way-data-flow
]
.
and about
[
one way data flow
][
one-way-data-flow
]
.
### Components
, Stores and Services
### Components
and Store
In some features implemented with Vue.js, like the
[
issue board
][
issue-boards
]
In some features implemented with Vue.js, like the
[
issue board
][
issue-boards
]
or
[
environments table
][
environments-table
]
or
[
environments table
][
environments-table
]
...
@@ -33,10 +30,8 @@ new_feature
...
@@ -33,10 +30,8 @@ new_feature
├── components
├── components
│ └── component.vue
│ └── component.vue
│ └── ...
│ └── ...
├── store
s
├── store
│ └── new_feature_store.js
│ └── new_feature_store.js
├── services # only when not using vuex
│ └── new_feature_service.js
├── index.js
├── index.js
```
```
_For consistency purposes, we recommend you to follow the same structure._
_For consistency purposes, we recommend you to follow the same structure._
...
@@ -125,217 +120,6 @@ You can read more about components in Vue.js site, [Component System][component-
...
@@ -125,217 +120,6 @@ You can read more about components in Vue.js site, [Component System][component-
#### Vuex
#### Vuex
Check this
[
page
](
vuex.md
)
for more details.
Check this
[
page
](
vuex.md
)
for more details.
#### Flux like state management
The Store is a class that allows us to manage the state in a single
source of truth. It is not aware of the service or the components.
The concept we are trying to follow is better explained by Vue documentation
itself, please read this guide:
[
State Management
][
state-management
]
### A folder for the Service
**If you are using Vuex you won't need this step**
The Service is a class used only to communicate with the server.
It does not store or manipulate any data. It is not aware of the store or the components.
We use
[
axios
][
axios
]
to communicate with the server.
Refer to
[
axios
](
axios.md
)
for more details.
Axios instance should only be imported in the service file.
```
javascript
import
axios
from
'
~/lib/utils/axios_utils
'
;
```
### End Result
The following example shows an application:
```
javascript
// store.js
export
default
class
Store
{
/**
* This is where we will iniatialize the state of our data.
* Usually in a small SPA you don't need any options when starting the store.
* In that case you do need guarantee it's an Object and it's documented.
*
* @param {Object} options
*/
constructor
(
options
)
{
this
.
options
=
options
;
// Create a state object to handle all our data in the same place
this
.
todos
=
[];
}
setTodos
(
todos
=
[])
{
this
.
todos
=
todos
;
}
addTodo
(
todo
)
{
this
.
todos
.
push
(
todo
);
}
removeTodo
(
todoID
)
{
const
state
=
this
.
todos
;
const
newState
=
state
.
filter
((
element
)
=>
{
element
.
id
!==
todoID
});
this
.
todos
=
newState
;
}
}
// service.js
import
axios
from
'
~/lib/utils/axios_utils
'
export
default
class
Service
{
constructor
(
options
)
{
this
.
todos
=
axios
.
create
({
baseURL
:
endpoint
.
todosEndpoint
});
}
getTodos
()
{
return
this
.
todos
.
get
();
}
addTodo
(
todo
)
{
return
this
.
todos
.
put
(
todo
);
}
}
// todo_component.vue
<
script
>
export
default
{
props
:
{
data
:
{
type
:
Object
,
required
:
true
,
},
},
};
<
/script
>
<
template
>
<
div
>
<
h1
>
Title
:
{{
data
.
title
}}
<
/h1
>
<
p
>
{{
data
.
text
}}
<
/p
>
<
/div
>
<
/template
>
// todos_main_component.vue
<
script
>
import
Store
from
'
store
'
;
import
Service
from
'
service
'
;
import
TodoComponent
from
'
todoComponent
'
;
export
default
{
components
:
{
todo
:
TodoComponent
,
},
/**
* Although most data belongs in the store, each component it's own state.
* We want to show a loading spinner while we are fetching the todos, this state belong
* in the component.
*
* We need to access the store methods through all methods of our component.
* We need to access the state of our store.
*/
data
()
{
const
store
=
new
Store
();
return
{
isLoading
:
false
,
store
:
store
,
todos
:
store
.
todos
,
};
},
created
()
{
this
.
service
=
new
Service
(
'
/todos
'
);
this
.
getTodos
();
},
methods
:
{
getTodos
()
{
this
.
isLoading
=
true
;
this
.
service
.
getTodos
()
.
then
(
response
=>
{
this
.
store
.
setTodos
(
response
);
this
.
isLoading
=
false
;
})
.
catch
(()
=>
{
this
.
isLoading
=
false
;
// Show an error
});
},
addTodo
(
event
)
{
this
.
service
.
addTodo
({
title
:
'
New entry
'
,
text
:
`You clicked on
${
event
.
target
.
tagName
}
`
,
})
.
then
(
response
=>
{
this
.
store
.
addTodo
(
response
);
})
.
catch
(()
=>
{
// Show an error
});
},
},
};
<
/script
>
<
template
>
<
div
class
=
"
container
"
>
<
div
v
-
if
=
"
isLoading
"
>
<
i
class
=
"
fa fa-spin fa-spinner
"
aria
-
hidden
=
"
true
"
/>
<
/div
>
<
div
v
-
if
=
"
!isLoading
"
class
=
"
js-todo-list
"
>
<
template
v
-
for
=
'
todo in todos
'
>
<
todo
:
data
=
"
todo
"
/>
<
/template
>
<
button
@
click
=
"
addTodo
"
class
=
"
js-add-todo
"
>
Add
Todo
<
/button
>
<
/div
>
<
div
>
<
/template
>
// index.js
import
todoComponent
from
'
todos_main_component.vue
'
;
new
Vue
({
el
:
'
.js-todo-app
'
,
components
:
{
todoComponent
,
},
render
:
createElement
=>
createElement
(
'
todo-component
'
{
props
:
{
someProp
:
[],
}
}),
});
```
The
[
issue boards service
][
issue-boards-service
]
is a good example of this pattern.
## Style guide
## Style guide
Please refer to the Vue section of our
[
style guide
](
style_guide_js.md#vue-js
)
Please refer to the Vue section of our
[
style guide
](
style_guide_js.md#vue-js
)
...
@@ -446,6 +230,5 @@ need to test the rendered output. [Vue][vue-test] guide's to unit test show us e
...
@@ -446,6 +230,5 @@ need to test the rendered output. [Vue][vue-test] guide's to unit test show us e
[
state-management
]:
https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch
[
state-management
]:
https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch
[
one-way-data-flow
]:
https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow
[
one-way-data-flow
]:
https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow
[
vue-test
]:
https://vuejs.org/v2/guide/unit-testing.html
[
vue-test
]:
https://vuejs.org/v2/guide/unit-testing.html
[
issue-boards-service
]:
https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/boards/services/board_service.js.es6
[
flux
]:
https://facebook.github.io/flux
[
flux
]:
https://facebook.github.io/flux
[
axios
]:
https://github.com/axios/axios
[
axios
]:
https://github.com/axios/axios
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment