vue封装tabs组件案例
木子石@ 人气:0回顾封装tabs组件
熟知运用$children,$parent
的案例
生成整个容器,通过$children
拿取子组件
<template> <div class="ll-tabs"> <div class="ll-tabs__header"> <div class="ll-tabs__header__wrapper" v-if="tabsArray && tabsArray.length > 0" > <div v-for="tab in tabsArray" :key="tab.name" :class="`ll-tab__item ${activeName === tab.name ? 'is-active' : ''}`" @click="clickTab(tab)" > {{ tab.label }} </div> </div> </div> <div class="ll-tabs__body"><slot></slot></div> </div> </template> <script> export default { name: "ll-tabs", props: ["value"], data() { return { tabsArray: [], activeName: this.value, }; }, watch: { value(val) { this.setCurrentName(val); }, }, mounted() { this.tabsArray = this.$children; }, methods: { clickTab(tab) { this.activeName = tab.name; this.updateTab(); this.$emit("change", tab); }, updateTab() { this.$children.map((ele) => { console.log(ele); if (ele.name === this.activeName) { ele.currentShow = true; ele.load = true; } else { ele.currentShow = false; } }); }, setCurrentName(val) { this.activeName = val; }, }, }; </script> <style lang="scss" scoped> .ll-tabs { width: 100%; height: auto; .ll-tabs__header { width: 100%; .is-active.ll-tab__item { background-color: aquamarine; } .ll-tabs__header__wrapper:before { color: white; } .ll-tabs__header__wrapper { width: 100%; display: flex; align-content: center; justify-content: flex-start; align-items: center; height: 30px; padding: 1px 0; } .ll-tab__item { width: fit-content; height: 30px; padding: 0 15px; font-size: 14px; background-color: transparent; z-index: 49; cursor: pointer; line-height: 30px; border: 1px rgba(100, 100, 100, 0.1) solid; border-right: none; &:last-of-type { border-right: 1px rgba(100, 100, 100, 0.1) solid; } } } } .ll-tabs__body { padding: 10px 0; height: auto; background-color: transparent; } </style>
生成子组件,展示每个tab。
<template> <div v-if="!lazy || loaded || currentShow" v-show="currentShow" :class="`ll-tab-pane tab-${name}`" > <slot></slot> </div> </template> <script> export default { name: "ll-tab-pane", props: { label: String, name: String, lazy: Boolean, }, data() { return { currentShow: false, loaded: false, }; }, mounted() { this.$parent.updateTab(); }, }; </script>
使用
<llTabs v-model="activeName"> <llTabsPane name="first" label="first">first</llTabsPane> <llTabsPane name="second" label="second">second</llTabsPane> <llTabsPane name="third" label="third">third</llTabsPane> </llTabs> import { llTabs, llTabsPane } from "@/components/tabs"; export default { components: { llTabs, llTabsPane }, }
展示
加载全部内容