🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
* 打开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> ~~~