1
1
上一章做好了文章列表,紧接着就是实现** 文章详情页面** 了。
2
2
3
- 从列表到详情,毫无疑问首当其冲的问题就是页面如何跳转 。
3
+ 从列表到详情,首当其冲的问题就是页面如何跳转 。
4
4
5
5
传统模式的跳转是由 Django 后端分配路由。不过本教程既然采用了前后端分离的模式,那就打算抛弃后端路由,采用** 前端路由** 的方式来实现页面跳转。
6
6
17
17
added 1 package in 9. 143s
18
18
```
19
19
20
- 笔者这里安装到的 4.0.2 版本。
20
+ > 笔者这里安装到的 4.0.2 版本。
21
21
22
22
因为 vue-router 会用到文章的 id 作为动态地址,所以对 ** Django 后端** 做一点小更改:
23
23
@@ -48,11 +48,11 @@ import router from './router'
48
48
createApp (App).use (router).mount (' #app' );
49
49
```
50
50
51
- 和 ** Vue 2** 不同的是,挂载实例时 ** Vue 3** 采用函数式的写法,变得更加美观了。
51
+ > 和 ** Vue 2** 不同的是,挂载路由实例时 ** Vue 3** 采用函数式的写法,变得更加美观了。
52
52
53
53
由于后续页面会越来越多,为了避免 ` App.vue ` 越发臃肿,因此必须优化文件结构。
54
54
55
- 新建 ` frontend/src/views/ ` 目录用来存放现在及将来所有的页面文件 。在此目录新建 ` Home.vue ` 文件,把之前的首页代码稍加修改搬运过来:
55
+ 新建 ` frontend/src/views/ ` 目录,用来存放现在及将来所有的页面文件 。在此目录新建 ` Home.vue ` 文件,把之前的首页代码稍加修改搬运过来:
56
56
57
57
``` html
58
58
<!-- frontend/src/views/Home.vue -->
@@ -127,7 +127,7 @@ createApp(App).use(router).mount('#app');
127
127
</style >
128
128
```
129
129
130
- `App.vue` 文件中大部分内容都搬走了,只剩一个新增的 `<router-view > ` 标签,它就是各路径所代表的页面的实际渲染位置。
130
+ `App.vue` 文件中大部分内容都搬走了,只剩一个新增的 `<router-view > ` 标签,它就是各路径所代表的页面的实际渲染位置。比如你现在在 Home 页面,那么 `< router-view > ` 则渲染的是 Home 中的内容。
131
131
132
132
> 一套组合拳,App.vue 看起来干净多了。
133
133
@@ -161,7 +161,7 @@ const router = createRouter({
161
161
export default router;
162
162
```
163
163
164
- - 列表 `routes` 定义了所有需要挂载到路由中的路径,成员为** 路径 url** 、路径名和 ** 路径的 vue 对象** 。详情页面的动态路由采用冒号 `:id` 的形式来定义。
164
+ - 列表 `routes` 定义了所有需要挂载到路由中的路径,成员为** 路径 url** 、** 路径名 ** 和 ** 路径的 vue 对象** 。详情页面的动态路由采用冒号 `:id` 的形式来定义。
165
165
- 接着就用 `createRouter()` 创建 router。参数里的 `history` 定义具体的路由形式,`createWebHashHistory()` 为哈希模式(具体路径在 # 符号后面);`createWebHistory()` 为 HTML5 模式(路径中没有丑陋的 # 符号),此为** 推荐模式** ,但是** 部署时需要额外的配置** 。
166
166
167
167
> 各模式的详细介绍看[文档 ](https://next.router.vuejs .org/guide/essentials/history-mode .html )。
@@ -196,6 +196,8 @@ export default router;
196
196
197
197
`:to` 属性指定了跳转位置,注意看** 动态参数 id** 是如何传递的。
198
198
199
+ 在 Vue 中,属性前面的冒号 `:` 表示此属性被”绑定“了。”绑定“的对象可以是某个动态的参数(比如这里的 id 值),也可以是 Vue 所管理的 data,也可以是 methods。总之,看到冒号就要明白这个属性后面跟着个变量或者表达式,没有冒号就是普通的字符串。冒号 `:` 实际上是 `v-bind :` 的缩写。
200
+
199
201
> 有一个小问题是由于 router 内部机制,之前给 `class="article-title "` 写的 padding 样式会失效。解决方式是将其包裹在一个 div 元素中,在此 div 上重新定义 padding。想了解做法的见 Github 仓库中的源码。
200
202
201
203
Router 骨架就搭建完毕了。此时点击首页的文章标题链接后,应该就顺利跳转到一个只有页眉页脚的详情页面了。
@@ -302,7 +304,7 @@ Router 骨架就搭建完毕了。此时点击首页的文章标题链接后,
302
304
先看** 模板** 部分:
303
305
304
306
- 在渲染文章前,逻辑控制语句 ` v-if ` 先确认数据是否存在,避免出现** 潜在的** 调用数据不存在的 bug。
305
- - 由于 ` body_html ` 、` toc_html ` 都是后端渲染好的 markdown 文本,需要将其渲染为 HTML ,所以需要用 ` v-html ` 标注。
307
+ - 由于 ` body_html ` 、` toc_html ` 都是后端渲染好的 markdown 文本,需要将其直接转换为 HTML ,所以需要用 ` v-html ` 标注。
306
308
307
309
再看脚本:
308
310
@@ -321,6 +323,6 @@ Router 骨架就搭建完毕了。此时点击首页的文章标题链接后,
321
323
322
324
用很少的、漂亮的代码完成了看起来还不错的详情页,并且摆脱了手动操作 DOM 的繁琐。
323
325
324
- 不知客观您的感受如何呢 。
326
+ 感受如何呢 。
325
327
326
328
> Django 的 Markdown 渲染只负责把文章转换为 HTML 文本。如果你仍然觉得其排版简陋,那就需要自己定义对应的 CSS 样式,调整为自己喜欢的外观。不过这就不在本文的讨论范畴内了,进一步了解可参考笔者[ 另一篇文章] ( https://www.dusaiphoto.com/article/20/ ) 。
0 commit comments