今天小编给大家分享一下怎么使用vue3+ts实现树形组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
文件结构:
---mTree
---index.ts
---mTree.vue
在index.ts文件中引入组件然后注册,并最后在main.ts文件中引入并且使用app.use
import mTree from "./mTree.vue"
mTree.install = app => {
app.component(mTree.name,mTree)
}
export default mTree
首先我们先要创建一个树状的数据,分清楚层级关系
const state = reactive({
treeOptions: [
{
label: '一级',
children: [
...
{
label: '一级-3',
children: [
....
],
},
],
},
...
})
就像这样的层级关系,当然这里面我们只是模拟数据,真实的项目开发过程中应该是后端给前端数据,然后前端在根据数据进行渲染
<template>
<li v-for="item in options"
:key="item.label">
{{ item.label }}
<ul v-if="item.children&&item.children.length>0">
<mTree :options="item.children"></mTree>
</ul>
</li>
</template>
如图:
解释一下这个组件的这个结构:
首先使用li组件渲染第一层结构,然后在ul里面重新嵌套mTree树形组件,并且判断当前item元素是否有children属性,如果有这个属性,那么就进行渲染,否则的话就不渲染。这样就不停的递归,到最后一个children都渲染结束之后结束了。这样在不确定有多少层级时就可以使用,可以实现无限的层级嵌套。
<li v-for...
@click.stop="toggleisOpen(item)">
{{ item.label }}
<transition name="slide-fade">
<ul v-show="item.isOpen">...</ul>
</transition>
</li>
这里只展示了新增的代码,给li添加了一个点击事件:
interface optionsProp {
label: string
isOpen?: boolean
children?: optionsProp[]
}
const props = defineProps({
options: {
type: Array as PropType<optionsProp[]>,
default() {
return []
},
},
})
const toggleisOpen = (item: any) => {
item.isOpen = !item.isOpen
}
注意ul通过v-show来控制显示或者隐藏,当第一次点击的时候由于源数据中没有isOpen,所以这个时候取反就是true,就会显示点击元素的子级。还有一点要注意的时,由于冒泡会导致出现一些问题,所以在点击事件后面加上.stop来阻止冒泡。
这里我们使用了Vue3官方中的过渡,不是很了解的小伙伴可以去官网查看,简单来说就是使用transition包裹要使用过渡效果的部分,然后定义name属性,本文中的name为slide-fade所以下面的样式就是这样的:
v-enter-from
:进入动画的起始状态。
v-enter-active
:进入动画的生效状态。
v-leave-active
:离开动画的生效状态
v-leave-to
:离开动画的结束状态。
.slide-fade-enter-active {
transition: all 0.3s ease-out;
}
.slide-fade-leave-active {
transition: all 0.2s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter-from,
.slide-fade-leave-to {
transform: translateY(20px);
opacity: 0;
}
以上就是“怎么使用vue3+ts实现树形组件”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://juejin.cn/post/7228960291303047227