组件化

组件化概念:
把重复的代码提取出来合并成为一个个组件,组件最重要的就是重用(复用),位于框架最底层,其他功能都依赖于组件,可供不同功能使用,独立性强,方便维护。

既然有这么多好处,我们就开始行动吧!
首页的文章列表并不会涉及到这么多优点,但是为了统一,我们还是要进行文章列表的组件化。

第一步,我们把原来frontend/src/views/Home.vue修改成这样:

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
<!--frontend/src/views/Home.vue-->
<template>
<!--div v-for="article in articles" :key="article.id">
<h3>{{ article.title }}</h3>
{{ article.main }}
<hr>
</div-->
</template>

<script>
import axios from 'axios';
export default {
name: 'Home',
data () {
return {
articles: '',
}
},
/*methods: {
getArticles () {
axios.get('http://127.0.0.1:8000/api/articles/')
.then(this.getArticlesSucc)
},
getArticlesSucc (res) {
this.articles = res.data
}
},
mounted () {
this.getArticles()
},*/
}
</script>

这里,我们把前两章的获取文章列表的代码注释掉了。
第二步,我们在frontend/src/compoments目录下创建ArticleList.vue文件。

这里再一次提醒读者,在第一章搭建项目目录的时候必须是cnpm install -g @vue/cli,也就是安装了vue-cli4,否则到时候会前功尽弃。

第三步,我们把frontend/src/views/Home.vue改成这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!--frontend/src/views/Home.vue-->
<template>
<div id="app">
<ArticleList/>
</div>
</template>

<script>
// @ is an alias to /src
// import HelloWorld from '@/components/HelloWorld.vue'
import ArticleList from '@/components/ArticleList.vue'

export default {
name: 'Home',
components: {
// HelloWorld
ArticleList,
},
}

</script>

这里我们简单粗爆的根据例子引入了组件。
第四部,我们把之前的代码写入到frontend/src/compoments/ArticleList.vue文件里:

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
<!--frontend/src/compoments/ArticleList.vue-->
<template>
<div v-for="article in articles" :key="article.id">
<h3>{{ article.title }}</h3>
{{ article.main }}
<hr>
</div>
</template>

<script>
import axios from 'axios';
export default {
name: 'ArticleList',
data () {
return {
articles: '',
}
},
methods: {
getArticles () {
axios.get('http://127.0.0.1:8000/api/articles/')
.then(this.getArticlesSucc)
},
getArticlesSucc (res) {
this.articles = res.data
}
},
mounted () {
this.getArticles()
},
}
</script>

再次刷新页面,正常情况下就可以看到和原来一样的界面啦!

美化文章列表

我们原来的文章列表是十分简陋的,所以,我们要对他进行拓展。这是我们第一次做美化,在此推荐一个从react上面移植过来的库,叫做ant-design-vue,安装它:

1
cnpm install ant-design-vue

这里博主直接把我自己的代码放出来了,很乱,里面也包含了svg图标,后面会逐一讲述,这里暂时没有新的知识点,所以直接放代码啦:

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
<template>
<div>
<div v-for="article in articles" :key="article.id">
<!--文章循环里面的卡片-->
<a-card style="width: 100%;">
<div align="left"><!--位置在左侧-->
<!--文章标题,包含导航-->
<h6 style="font-weight:bold"><a :href="'#/article/detail/'+ article.id">
<div style="color: black;" v-if="article.course">{{ article.course }}:{{ article.title }}</div>
<div style="color: black;" v-else>{{ article.title }}</div>
</a></h6>
<!--文章meta-->
<span>
<span v-if="article.column">
<a-button size="small">{{ article.column }}</a-button>
</span>
&nbsp;&nbsp;
<span v-for="tag in article.tags" :key="tag">
<span v-if="tag">
<a-tag color="#108ee9">{{ tag }}</a-tag>
</span>
</span>
<br>
</span>
<!--svg图标构成的meta,图标很乱,请忽略-->
<span>
<svg t="1596876003462" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3872" width="16" height="16"><path d="M884.5 754.12c7.45-14.9 14.9-26.07 22.35-41 3.72-3.72 3.72-7.45 3.72-11.18 3.73-11.17 11.18-22.35 14.9-33.52 3.73-3.72 3.73-7.45 3.73-14.9 3.73-11.18 7.45-22.35 11.18-29.8 0-3.72 3.72-11.17 3.72-14.9 3.73-11.17 3.73-22.35 7.45-33.53 0-3.72 3.73-11.17 3.73-14.89C959 545.53 959 526.9 959 512c0-245.85-201.15-447-447-447S65 266.15 65 512c0 14.9 0 33.53 3.73 48.43 0 3.72 0 11.17 3.72 14.89 0 11.18 3.73 22.36 3.73 33.53 0 3.73 3.72 11.18 3.72 14.9 3.73 11.17 7.45 22.35 11.18 29.8 0 3.73 3.72 7.45 3.72 14.9 3.73 11.17 7.45 22.35 14.9 33.52 0 3.73 3.73 7.46 3.73 11.18 7.45 14.9 14.89 26.07 22.34 41C214 877.05 351.82 959 508.28 959s294.27-82 376.22-204.88z m-376.22-476.8c89.4 0 163.9 74.5 163.9 163.91s-74.5 163.9-163.9 163.9-163.9-74.51-163.9-163.9 74.5-163.91 163.9-163.91zM236.35 791.38c48.43-108 152.73-178.8 271.93-178.8s223.5 70.77 271.92 178.8c-70.77 67-167.62 111.74-271.92 111.74-104.28-3.72-201.15-44.7-271.93-111.74z" fill="#398885" p-id="3873"></path></svg>&nbsp;{{ article.author }}
&nbsp;
<svg t="1596876286076" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5391" width="16" height="16"><path d="M512 42.666667c259.2 0 469.333333 210.133333 469.333333 469.333333s-210.133333 469.333333-469.333333 469.333333S42.666667 771.2 42.666667 512 252.8 42.666667 512 42.666667z" fill="#FFEEEE" p-id="5392"></path><path d="M512 128a384 384 0 1 0 0 768 384 384 0 0 0 0-768z m0-85.333333c259.2 0 469.333333 210.133333 469.333333 469.333333s-210.133333 469.333333-469.333333 469.333333S42.666667 771.2 42.666667 512 252.8 42.666667 512 42.666667z" fill="#E73131" p-id="5393"></path><path d="M426.666667 256h85.333333v384h-85.333333z" fill="#E62C2C" p-id="5394"></path><path d="M726.101333 554.837333v85.333334h-298.666666v-85.333334z" fill="#E62C2C" p-id="5395"></path></svg>&nbsp;{{ article.created }}
</span>
<span v-if="article.course">
&nbsp;
<svg t="1597402885594" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2878" width="16" height="16"><path d="M0 0m102.4 0l819.2 0q102.4 0 102.4 102.4l0 819.2q0 102.4-102.4 102.4l-819.2 0q-102.4 0-102.4-102.4l0-819.2q0-102.4 102.4-102.4Z" fill="#51CF70" p-id="2879"></path><path d="M512 512L340.992 438.272 161.792 512V0H512v512z" fill="#D7FF3E" p-id="2880"></path></svg>
&nbsp;{{ article.course }}
</span>
<!--文章概览-->
<p style="color: grey">{{ article.main }}</p>
</div>
</a-card><br>
</div>
</div>
</template>

<script>
// @ is an alias to /src
// import HelloWorld from '@/components/HelloWorld.vue'
import axios from 'axios';
export default {
name: 'ArticleList',
data () {
return {
articles: '',
}
},
methods: {
getArticles () { // 获取文章列表
axios.get('http://127.0.0.1:8000/api/articles/')
.then(this.getArticlesSucc)
},
getArticlesSucc (res) { // 赋值文章列表
this.articles = res.data
}
},
mounted () {
this.getArticles() // 实际执行
},
}

</script>
  1. 会css的读者可以反馈一些意见,也可以自己定制
  2. 这里用到了很多ant-design-vue的样式,比如说卡片,按钮徽章等等,附上文档:https://antdv.com

如果完全按照博主的做,效果如下:
文章列表

好了,这里先讲这些,后面还会进一步构建导航栏,侧边栏等等,敬请期待。