* 打开vue antd官网`https://vue.ant.design`,找到layout布局组件,找到类似pro的模板,如下图
![](https://img.kancloud.cn/28/a7/28a7ee444ebf6e15197d54276069ca21_3332x1528.png)
* 打开代码赋值到我们项目中`src/layouts/BasicLayout.vue`中
> BasicLayout.vue
```
<template>
<div>
<a-layout id="components-layout-demo-side" style="min-height: 100vh">
<a-layout-sider
collapsible
v-model="collapsed"
>
<div class="logo" />
<SiderMenu />
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0" >
<Header />
</a-layout-header>
<a-layout-content style="margin: 0 16px">
<router-view></router-view>
</a-layout-content>
<a-layout-footer style="text-align: center">
<Footer />
</a-layout-footer>
</a-layout>
</a-layout>
</div>
</template>
<script>
import Header from "./Header";
import Footer from "./Footer";
import SiderMenu from "./SiderMenu";
export default {
data() {
return {
collapsed: false,
}
},
components: {
Header,
Footer,
SiderMenu
}
};
</script>
<style></style>
```
* 菜单切换trigger需要我们自己去自定义;
>首先隐藏trigger原始图标,Layout.Sider 有个trigger属性,自定义 trigger,设置为 null 时隐藏 trigger
>然后自定义a-icon 图片及位置
>最后图片添加click事件控制菜单切换
> BasicLayout.vue
```
<template>
<div>
<a-layout id="components-layout-demo-side" style="min-height: 100vh">
<a-layout-sider
collapsible
v-model="collapsed"
:trigger="null"
>
<div class="logo" />
<SiderMenu />
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0" >
<a-icon
class="trigger"
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="collapsed = !collapsed"
></a-icon>
<Header />
</a-layout-header>
<a-layout-content style="margin: 0 16px">
<router-view></router-view>
</a-layout-content>
<a-layout-footer style="text-align: center">
<Footer />
</a-layout-footer>
</a-layout>
</a-layout>
</div>
</template>
<script>
import Header from "./Header";
import Footer from "./Footer";
import SiderMenu from "./SiderMenu";
export default {
data() {
return {
collapsed: false,
}
},
components: {
Header,
Footer,
SiderMenu
}
};
</script>
<style lang="less" scoped>
.trigger{
padding: 0 20px;
line-height: 64px;
font-size: 20px;
}
.trigger:hover{
background-color: #eeeeee;
}
</style>
</style>
```
* 右侧抽屉动态改变页面布局,在`src/components/SettingDrawer/Index.vue`新建设置主题组件,找到官网`Drawer`基础抽屉组件
![](https://img.kancloud.cn/12/58/1258ab46a8313de9eb32a74722b69895_3358x1684.png)
>Index.vue
```
<template>
<div>
<a-button type="primary" @click="showDrawer">
Open
</a-button>
<a-drawer
title="Basic Drawer"
placement="right"
:closable="false"
@close="onClose"
:visible="visible"
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</a-drawer>
</div>
</template>
<script>
export default {
data() {
return {
visible: false,
}
},
methods: {
showDrawer() {
this.visible = true
},
onClose() {
this.visible = false
},
},
}
</script>
```
自定义抽屉按钮及抽屉样式
> 删除原始按钮及展示事件;
>把图标定位到右侧及样式,绑定展开收缩事件;
>动态布局设置项样式
为了能动态改变页面布局,我们暂时先把设置参数放到`router`中,然后`BasicLayout`通过`computed`计算属性从`router`中读取来动态修改布局
>Index.vue
```
<template>
<div>
<a-drawer
placement="right"
:closable="false"
@close="onClose"
:visible="visible"
width="300px"
>
<template v-slot:handle>
<div class="handle" @click="visible = !visible">
<a-icon :type="visible ? 'close' : 'setting'"></a-icon>
</div>
</template>
<div>
<h2>整体风格定制</h2>
<a-radio-group
:value="$route.query.navTheme || 'dark'"
@change="e => handleSettingChange('navTheme', e.target.value)"
>
<a-radio value="dark">黑色</a-radio>
<a-radio value="light">白色</a-radio>
</a-radio-group>
<h2>导航模式</h2>
<a-radio-group
:value="$route.query.navLayout || 'left'"
@change="e => handleSettingChange('navLayout', e.target.value)"
>
<a-radio value="left">左侧</a-radio>
<a-radio value="lighn">顶部</a-radio>
</a-radio-group>
</div>
</a-drawer>
</div>
</template>
<script>
export default {
data() {
return {
visible: false
};
},
methods: {
onClose() {
this.visible = false;
},
handleSettingChange(type, value) {
this.$router.push({ query: { ...this.$route.query, [type]: value } });
}
}
};
</script>
<style type="less" scoped>
.handle {
position: absolute;
top: 240px;
right: 300px;
width: 48px;
height: 48px;
background: #1890ff;
color: #fff;
font-size: 20px;
text-align: center;
line-height: 48px;
border-radius: 3px 0 0 3px;
}
</style>
```
> BasicLayout.vue
~~~
<template>
<div :class="[`nav-theme-${navTheme}`, `nav-layout-${navLayout}`]">
<a-layout id="components-layout-demo-side" style="min-height: 100vh">
<a-layout-sider
v-if="navLayout === 'left'"
:theme="navTheme"
:trigger="null"
collapsible
v-model="collapsed"
width="256px"
>
<div class="logo">
<h1>Ant Design Pro</h1>
</div>
<SiderMenu />
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0">
<a-icon
class="trigger"
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="collapsed = !collapsed"
></a-icon>
<Header />
</a-layout-header>
<a-layout-content style="margin: 0 16px">
<router-view></router-view>
</a-layout-content>
<a-layout-footer style="text-align: center">
<Footer />
</a-layout-footer>
</a-layout>
</a-layout>
<setting-drawer />
</div>
</template>
<script>
import Header from "./Header";
import Footer from "./Footer";
import SiderMenu from "./SiderMenu";
import SettingDrawer from "../components/SettingDrawer/Index";
export default {
data() {
return {
collapsed: false
};
},
computed: {
navTheme() {
return this.$route.query.navTheme || "dark";
},
navLayout() {
return this.$route.query.navLayout || "left";
}
},
components: {
Header,
Footer,
SiderMenu,
SettingDrawer
}
};
</script>
<style lang="less" scoped>
.trigger {
padding: 0 20px;
line-height: 64px;
font-size: 20px;
&:hover {
background: #eeeeee;
}
}
.logo {
position: relative;
height: 64px;
padding-left: 24px;
overflow: hidden;
line-height: 64px;
svg {
width: 32px;
height: 32px;
display: inline-block;
vertical-align: middle;
}
h1 {
display: inline-block;
margin: 0 0 0 12px;
font-size: 20px;
font-family: Avenir, "Helvetica Neue", Arial, Helvetica, sans-serif;
font-weight: 600;
vertical-align: middle;
}
}
.nav-theme-dark {
/deep/ .logo {
h1 {
color: #ffffff;
}
}
}
</style>
~~~