3.如何编写自定义组件
2024年11月27日大约 2 分钟约 473 字...
3.如何编写自定义组件
如何编写自定义组件啊,这个教程是真的很难写,会就是会,不会的话要学习的知识是很多的。但我还是尽力去讲解吧。
我这里用一个最简单的组件来举例子:
src/.vuepress/components/CommentHideBtn.vue
<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { mStorage } from '../utils/tools.js';
const ShowComments = () => {
const CommentElm = document.getElementById('comment') as HTMLElement;
if (!CommentElm) {
return;
}
CommentElm.classList.add('show');
CommentElm.classList.remove('hide');
mStorage.set('CommentIsDisplay', true);
};
const HideComments = () => {
const CommentElm = document.getElementById('comment') as HTMLElement;
if (!CommentElm) {
return;
}
CommentElm.classList.add('hide');
CommentElm.classList.remove('show');
mStorage.set('CommentIsDisplay', false);
};
const ReadeCommentIsDisplay = () => {
const CommentElm = document.getElementById('comment') as HTMLElement;
if (!CommentElm) {
return;
}
const CommentIsDisplay = mStorage.get('CommentIsDisplay');
if (CommentIsDisplay) {
ShowComments();
} else {
HideComments();
}
CommentElm.style.opacity = '1';
};
const CreateCommentBtn = () => {
const CommentElm = document.getElementById('comment');
if (!CommentElm) {
return;
}
if (!document.getElementById('ShowComment')) {
const BtnElm = document.createElement('button');
BtnElm.id = 'ShowComment';
BtnElm.classList.add('primary');
BtnElm.classList.add('wl-btn');
BtnElm.innerHTML = '显示评论区';
CommentElm.appendChild(BtnElm);
}
if (!document.getElementById('HideComment')) {
const BtnElm = document.createElement('button');
BtnElm.id = 'HideComment';
BtnElm.classList.add('primary');
BtnElm.classList.add('wl-btn');
BtnElm.innerHTML = '隐藏评论区';
CommentElm.appendChild(BtnElm);
}
const showBtn = document.getElementById('ShowComment');
const hideBtn = document.getElementById('HideComment');
if (showBtn && hideBtn) {
showBtn.onclick = ShowComments;
hideBtn.onclick = HideComments;
}
};
onMounted(() => {
nextTick(() => {
CreateCommentBtn();
ReadeCommentIsDisplay();
});
const router = useRouter();
router.afterEach((to) => {
nextTick(() => {
setTimeout(() => {
CreateCommentBtn();
ReadeCommentIsDisplay();
}, 500);
});
});
});
</script>
<template>
<ClientOnly>
<div class="none">评论区隐藏按钮</div>
</ClientOnly>
</template>
<style lang="scss">
// 评论插件的样式修改
.wl-card .wl-meta > span {
background: transparent;
}
.vp-comment {
position: relative;
overflow: hidden;
opacity: 0;
transition: 0.3s;
margin-bottom: 2rem;
[provider='Waline'] {
opacity: 0;
margin-bottom: 5rem;
}
&.hide {
max-height: 0;
[provider='Waline'] {
opacity: 0;
transition: 0.3s;
}
#ShowComment {
display: block;
}
#HideComment {
display: none;
}
}
&.show {
max-height: 9999px;
[provider='Waline'] {
opacity: 1;
transition: 0.3s;
}
#ShowComment {
display: none;
}
#HideComment {
display: block;
}
}
}
#ShowComment {
top: 0;
}
#HideComment {
bottom: 0;
}
#ShowComment,
#HideComment {
display: none;
position: absolute;
left: 50%;
margin-left: -4em;
width: 8em;
z-index: 5;
user-select: none;
transition: 0.3s;
font-size: 0.9rem;
}
</style>
他的引用方式如下:
在 src/.vuepress/client.ts
文件中
import { defineClientConfig } from 'vuepress/client';
import { defineAsyncComponent } from 'vue';
const PrintVersion = defineAsyncComponent(() => import('./components/PrintVersion.vue'));
export default defineClientConfig({
// ...
rootComponents: [PrintVersion],
// ...
});
他干的事情很简单,就是在控制栏中打印当前的版本号。
一般组件的结构如下:
<script setup lang="ts">
// 这里是 js 部分,
// setup 表示 vue 的生命周期,具体的可以查看 vue3 的文档。
// lang="ts" 表示这里的代码会以 typescript 的形式进行解析和编译。
import { onMounted, nextTick } from 'vue';
import { useRouter } from 'vue-router';
onMounted(() => {
// vue3 生命周期钩子,这里会等到所有同步组件全部挂载完毕之后才会调用
// 这里就可以对 DOM 树进行相关的操作了。
nextTick(() => {
// nextTick 函数则是在DOM 更新完成之后才会触发,这里进行 DOM 操作更加安全
});
const router = useRouter();
router.afterEach((to) => {
// 这里是 路由变化监听,每次路由变化 就会触发。
});
});
</script>
<template>
<ClientOnly>
<!--
这里是 HTML 部分;
"ClientOnly" 标签表示 这部分内容只会在客户端的时候才会被渲染。不会在编译期进行解析。
vuepress 对 SEO 的优化很到位,所以我们的魔改基本上只需要在客户端生效即可
-->
</ClientOnly>
</template>
<style lang="scss">
// css 部分,这里的css 将会在组件加载的时候对全局生效。
// lang="scss" 表示这里的代码是以 scss 的标准去解析和编译。
</style>
如果想知道更多细节,可能得学习 vue3 相关的知识了。
vue3 官方文档:
https://cn.vuejs.org/
贡献者
墨七