之前一个vue2的项目,其布局方式是使用一个layout组件为壳,其子组件为slot,具体代码为
<template>
<div :class="sectionsMeun">
<slot></slot>
</div>
</template>
<script>
import bem from "@/common/bem";
export default {
name: "TLayout",
props: {
//布局中是否有菜单
hasSider: {
type: Boolean,
default: false
}
},
computed: {
sectionsMeun() {
return [bem("hh", "layout"), this.hasSider ? bem("hh", "layout-has-sider") : ""].join(" ");
}
}
};
</script>
<style lang="less" scoped>
@import url("./layout.less");
</style>
同时其样式文件为layout.less文件
.tsl-layout {
.size(100%, 100%);
font-size: 14px;
user-select: none;
display: flex;
flex: auto;
flex-direction: column;
overflow: hidden;
position: relative;
&,
* {
box-sizing: border-box;
}
&&-has-sider {
flex-direction: row;
}
&-header,
&-footer {
flex: 0 0 auto;
}
&-header {
.size(auto, @layout-header-default-height);
position: relative;
padding: @layout-header-padding;
border: 1px solid red;
display: flex;
}
&-footer {
padding: @layout-footer-padding;
}
&-content {
overflow-x: hidden;
position: relative;
flex: 1;
.size(100%, auto);
}
&-sider {
.size(@layout-sider-defalut-width, 100%);
position: relative;
flex-direction: column;
align-items: center;
min-width: @layout-sider-defalut-width;
// border: 1px solid #F3F3F3;
transition: all 0.2s;
padding: 0 15px 0 10px;
overflow-x: hidden;
}
}
之后在文件中去使用方式如下
<template>
<TLayout>
<THeader></THeader>
<TLayout hasSider>
<TMenu></TMenu>
<TContent>
<router-view />
</TContent>
</TLayout>
<!-- <TFooter></TFooter> -->
</TLayout>
</template>
<script>
import { TLayout, THeader, TMenu, TContent } from "../components/layout";
export default {
name: "Home",
components: {
TLayout,
THeader,
TMenu,
TContent
}
};
</script>
注意虽然layout.vue文件中的style带了scoped,但是依然可以在less文件中直接去控制layout的子组件样式。 但是当使用vue3时,这种方法不生效了,需要在less文件中对子组件使用:deep()的方式才能控制子组件的样式。具体原因还没有搞太清楚,这里有一个思路是直接使用webpack配置vue-loader以及less-loader,将案例先简化,看其编译后的文件长什么样子。