# Rules I Follow
When it comes to JS and VueJS components, I make sure to keep them simple and clean.
I keep my components small to make development and debugging easier.
Structuring is everything! Click here for image
I am against dependencies when it comes to small implementations that can take a couple of hours to make. Adding 500KB to the APP just to use 1 feature from the library doesn't make any sense.
I use tools such as NuxtJS to make sure that my APP is fast and follows all the desired techniques to reduce size and provide a faster experience (SSR, minification, modular architecture, etc.)
# VueJS Card component
<template>
<div class="card">
<d-header
:question="question">
</d-header>
<d-body
:question="question">
</d-body>
<d-footer
v-if="question.attachedFiles.length > 0"
:attachedFiles="question.attachedFiles">
</d-footer>
</div>
</template>
<script>
import dHeader from './Header'
import dBody from './Body'
import dFooter from './Footer'
export default {
props: ['question'],
components: {dHeader, dBody, dFooter}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# VueJS Header component
<template>
<div class="card-header">
<edit-question-modal
v-if="showEditQuestionModal"
@close="showEditQuestionModal = false"
:attachedFiles="question.attachedFiles">
</edit-question-modal>
<div class="row">
<div
:class="question.owner ? 'col-11' : 'col-12'">
<h5 class="text-center">
{{ question.question }}
</h5>
</div>
<div class="col-1"
v-if="question.owner">
<div class="btn-group dropleft float-right">
<i class="ellipsis" data-toggle="dropdown"></i>
<div class="dropdown-menu">
<button class="dropdown-item cursor-pointer"
@click="editMode()">
Edit
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item cursor-pointer"
@click="destroy()">
Delete
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {deleteForumQuestionMutation} from '../../../../graphql/requests/mutations/forumQuestion'
import EditQuestionModal from '../../../../components/Forum/modals/Question/Modal'
import {deletePopUp, toast} from '../../../../utilities/swal'
export default {
props: ['question'],
components: {EditQuestionModal},
data() {
return {
showEditQuestionModal: false
}
},
methods: {
editMode() {
this.showEditQuestionModal = true
this.$store.dispatch('setFormForumQuestion', {
editing: true,
question: this.question.question,
content: this.question.content,
tags: this.question.tags
})
},
destroy() {
deletePopUp('Are you sure you want to delete this forum question?').then(willDelete => {
if (willDelete.value)
deleteForumQuestionMutation(this, {variables: {slug: this.$route.params.slug}}).then(() => {
this.$router.push('/forum')
toast({type: 'success', title: 'Forum question has been deleted!'})
})
})
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# VueJS Body component
<template>
<div class="card-body">
<pre class="white-space-normal"
v-html="question.markdown_content"></pre>
<div class="float-right">
<span class="badge badge-dark"
:class="index > 0 ? 'ml-3': ''"
v-for="(tag, index) in question.tags">
{{ tag.tag }}
</span>
</div>
</div>
</template>
<script>
export default {
props: ['question']
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# VueJS Footer component
<template>
<div class="card-footer">
<attached-source-code
v-if="showAttachedSourceCodeModal"
@close="showAttachedSourceCodeModal = false">
</attached-source-code>
<div class="text-center">
<h6>
Attached files
</h6>
<span class="p-2 border-radius-0-25 border cursor-pointer d-inline-block mr-3 mt-3" id="attachedFileText"
data-toggle="modal" data-target="#attachedSourceCodeModal"
v-for="attachedFile of attachedFiles"
@click="setCurrentSourceCodeFile(attachedFile)">
{{ attachedFile.name }}
</span>
</div>
</div>
</template>
<script>
import AttachedSourceCode from './modals/AttachedSourceCode/Modal'
export default {
props: ['attachedFiles'],
components: {AttachedSourceCode},
data() {
return {
showAttachedSourceCodeModal: false
}
},
methods: {
setCurrentSourceCodeFile(attachedFile) {
this.showAttachedSourceCodeModal = true
fetch(`${process.env.DEVLOB_URL}/highlight`, {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({id: attachedFile.id})
}).
then(response => response.json()).
then(data => {
this.$store.dispatch('setCurrentAttachedSourceCodeFile',
{attachedFile: attachedFile, highlighted: data.highlighted})
})
}
}
}
</script>
<style scoped>
#attachedFileText:hover {
background-color: #FC503C;
color: white;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64