本站 - 记录曾阅读位置模块原创
笔记
本站实现了一个记住阅读文章的本地插件,方便下次访问本站时,可选择跳转曾经阅读的文章。
2022-01-04 @Young Kbt
# 前言
目前适用版本是 Vdoing v1.x。
不需要安装任何插件,只需要在本地添加三段代码即可。
# 组件添加
建议:本内容代码块比较长,可以点击代码块的右侧箭头来折叠,然后点击复制图标进行复制即可。
在 docs/.vuepress/components 文件夹下创建 LastReadingPopup.vue 文件,如果没有 components 文件夹,请创建。
添加如下内容:
<template>
<transition name="sw-update-popup">
<div v-if="show" class="sw-update-popup">
{{ message }}
<br />
<button @click="goto">
{{ sureButtonText }}
</button>
<button @click="dontgoto">
{{ cancelButtonText }}
</button>
</div>
</transition>
</template>
<script>
export default {
name: "LastReadingPopup",
data() {
return {
lastReading: null,
show: false,
};
},
computed: {
popupConfig() {
const popupConfig = {
"/": {
// message: "Go back to the last reading.",
// buttonText: "Go to",
message: "检测到您上一次阅读的位置,是否移至该位置?",
sureButtonText: "确定",
cancelButtonText: "取消",
},
"/zh/": {
message: "检测到您上一次阅读的位置,是否移至该位置?",
sureButtonText: "前往",
cancelButtonText: "取消",
},
};
const lang = this.$lang.split("-")[0];
return (
popupConfig[`/${lang}/`] || popupConfig[this.$localePath] || popupConfig
);
},
// 提示消息
message() {
const c = this.popupConfig;
return (c && c.message) || c["/"].message;
},
// 确认按钮
sureButtonText() {
const c = this.popupConfig;
return (c && c.sureButtonText) || c["/"].sureButtonText;
},
// 取消按钮
cancelButtonText() {
const c = this.popupConfig;
return (c && c.cancelButtonText) || c["/"].cancelButtonText;
},
},
// 如果不想使用该文件的效果,注释掉即可 mouted 函数的所有内容即可
mounted() {
if (!!window.ActiveXObject || "ActiveXObject" in window) {
setTimeout(() => {
window.addEventListener("load", this.init()); // for IE
}, 1000);
} else {
setTimeout(() => {
window.addEventListener("load", this.init);
}, 1000);
}
},
methods: {
init() {
this.lastReading = JSON.parse(localStorage.getItem("lastReading"));
if (this.lastReading) {
if (this.$route.path === this.lastReading.path) {
this.goto();
} else {
this.show = true;
10000 && setTimeout(this.clean, 10000);
}
}
},
goto() {
if (this.$route.path !== this.lastReading.path) {
this.$router.replace(this.lastReading.path).then(() => {
document.documentElement.scrollTop = this.lastReading.scrollTop;
this.clean();
});
} else {
this.$nextTick(() => {
document.documentElement.scrollTop = this.lastReading.scrollTop;
// this.clean();
});
}
},
dontgoto() {
this.clean();
},
clean() {
this.show = false;
localStorage.removeItem("lastReading");
},
},
};
</script>
<style scoped>
.sw-update-popup {
position: fixed;
right: 1em;
bottom: 1em;
padding: 1em;
border: 1px solid #3eaf7c;
border-radius: 3px;
background: #fff;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
text-align: center;
z-index: 12;
}
.sw-update-popup > button {
margin-top: 0.5em;
padding: 0.25em 2em;
}
.sw-update-popup-enter-active,
.sw-update-popup-leave-active {
transition: opacity 0.3s, transform 0.3s;
}
.sw-update-popup-enter,
.sw-update-popup-leave-to {
opacity: 0;
transform: translate(0, 50%) scale(0.5);
}
</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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
单语言你可以修改 35 - 37 的代码,多语言则包括了 40 - 42 行代码。
# 路由监听
在 docs/.vuepress/enhanceApp.js 文件里添加如下内容:
import LastReadingPopup from './components/LastReadingPopup.vue'
export default ({
Vue, // VuePress 正在使用的 Vue 构造函数
options, // 附加到根实例的一些选项
router, // 当前应用的路由实例
siteData, // 站点元数据
isServer // 当前应用配置是处于 服务端渲染 或 客户端
}) => {
// 判断是否绑定时间是否绑定成功
let isMounted = false;
// 最后一次阅读位置跳转
Vue.component(LastReadingPopup.name, LastReadingPopup);
Vue.mixin({
// 有多少个 Vue 组件(md 文档),就执行多少次 mounted(),所以利用 if 判断只允许执行一次
mounted() {
if (!isMounted) {
window.addEventListener('unload', this.saveLastReading); // 卸载窗口前,将数据存储,方便下次可以直接跳转位置
isMounted = true;
}
},
methods: {
saveLastReading() {
localStorage.setItem('lastReading', JSON.stringify({
path: this.$route.path,
scrollTop: document.documentElement.scrollTop,
timestamp: new Date().getTime(),
}))
}
}
});
}
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
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
# 本地插件配置
添加插件配置,在 docs/.vuepress/config.js(新版是 config.ts)的 plugins 中添加如下内容:
2.x 版本 globalUIComponents
改名为 clientAppRootComponentFiles
。
# 结束语
添加完三步的代码后,如何测试呢?
首先随便进入一个文章页里,然后关闭浏览器,然后重新打开浏览器访问主页,就会看到右下角出现提示,是否跳转过去。如果重新访问的是原来的文章页,则会自动移到之前的阅读位置。
参考:https://github.com/tolking/vuepress-plugin-last-reading
如果你还有疑惑,可以去我的 GitHub 仓库或者 Gitee 仓库查看源码。
如果你有更好的方式,评论区留言告诉我,或者加入 Vdoing 主题的 QQ 群:694387113。谢谢!
编辑此页 (opens new window)
更新时间: 2023/09/18, 16:34:13