204 lines
3.5 KiB
Vue
204 lines
3.5 KiB
Vue
<!--
|
||
filename: design.vue
|
||
author: liubin
|
||
date: 2023-10-07 13:14:40
|
||
description: 设计打印模板
|
||
-->
|
||
|
||
<template>
|
||
<div class="print-design">
|
||
<section id="menu">
|
||
<NavMenu @action="handleAction" :menu="menu" />
|
||
</section>
|
||
<section id="main-panel">
|
||
<section id="left-panel"></section>
|
||
<section id="edit-panel"></section>
|
||
<section id="right-panel"></section>
|
||
</section>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
const NavSelector = {
|
||
name: 'NavSelector',
|
||
props: ['name', 'options'],
|
||
data() {
|
||
return {
|
||
open: false,
|
||
};
|
||
},
|
||
methods: {
|
||
handleOpen() {
|
||
this.$emit('closeOtherMenu', this)
|
||
this.open = !this.open;
|
||
},
|
||
handleClickItem(e) {
|
||
this.$emit('click', e.target.innerText)
|
||
},
|
||
// 暴露一个close方法,供父组件调用
|
||
closeSubMenu() {
|
||
this.open = false;
|
||
},
|
||
},
|
||
render: function (h) {
|
||
return (
|
||
<li class={'nav-selector__item'} onClick={this.handleOpen}>
|
||
<span class={'nav-selector__name'}>{this.name}</span>
|
||
<ul class={`${this.open ? '' : 'hidden'} nav-selector__submenu-items`}>
|
||
{this.options.map((item) => {
|
||
return <li onClick={this.handleClickItem}>{item}</li>;
|
||
})}
|
||
</ul>
|
||
</li>
|
||
);
|
||
},
|
||
};
|
||
|
||
const NavMenu = {
|
||
name: 'NavMenu',
|
||
props: ['menu'],
|
||
components: { NavSelector },
|
||
data() {
|
||
return {}
|
||
},
|
||
methods: {
|
||
handleCloseOtherMenu(vueInstance) {
|
||
this.$children.forEach(vm => {
|
||
if (vm != vueInstance) {
|
||
vm.closeSubMenu()
|
||
}
|
||
})
|
||
},
|
||
handleItemClicked(e) {
|
||
this.$emit('action', e);
|
||
}
|
||
},
|
||
render: function (h) {
|
||
return (
|
||
<ul class={'nav-menu'}>
|
||
{this.menu.map((item) => {
|
||
return <NavSelector onClick={this.handleItemClicked} onCloseOtherMenu={this.handleCloseOtherMenu} name={item.name} options={item.options} />;
|
||
})}
|
||
</ul>
|
||
);
|
||
},
|
||
};
|
||
|
||
export default {
|
||
name: 'PrintDesignPage ',
|
||
components: { NavMenu },
|
||
props: {},
|
||
data() {
|
||
return {
|
||
menu: [
|
||
{
|
||
name: '菜单',
|
||
options: ['新建', '打开', '保存', '另存为', '导出', '打印', '退出'],
|
||
},
|
||
{
|
||
name: '视图',
|
||
options: ['编辑', '布局'],
|
||
},
|
||
],
|
||
};
|
||
},
|
||
computed: {},
|
||
methods: {
|
||
handleAction(name) {
|
||
console.log('name', name)
|
||
}
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.print-design {
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
#main-panel {
|
||
height: 1px;
|
||
flex: 1;
|
||
display: grid;
|
||
grid-template-columns: 200px 1fr 200px;
|
||
grid-auto-rows: 1fr;
|
||
grid-template-areas: 'left main right';
|
||
}
|
||
|
||
#menu {
|
||
// background: black;
|
||
// color: white;
|
||
background: #fff;
|
||
border-bottom: 1px solid #ccc;
|
||
|
||
> ul {
|
||
// background: #32aa32;
|
||
list-style: none;
|
||
padding: 6px;
|
||
margin: 0;
|
||
display: flex;
|
||
|
||
li {
|
||
padding: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
#left-panel {
|
||
grid-area: left;
|
||
background: #f1f1f1;
|
||
}
|
||
|
||
#edit-panel {
|
||
grid-area: main;
|
||
background: #e1e1e1;
|
||
}
|
||
|
||
#right-panel {
|
||
grid-area: right;
|
||
background: #f1f1f1;
|
||
}
|
||
</style>
|
||
|
||
<style lang="scss">
|
||
// 子组件的样式
|
||
.nav-selector__item {
|
||
position: relative;
|
||
cursor: pointer;
|
||
|
||
&:not(:last-child) {
|
||
margin-right: 12px;
|
||
}
|
||
|
||
ul {
|
||
list-style: none;
|
||
margin: 0;
|
||
padding: 0;
|
||
position: absolute;
|
||
top: 128%;
|
||
min-width: 128px;
|
||
left: -6px;
|
||
background: #fff;
|
||
border: 1px solid #ccc;
|
||
// border-radius: 4px;
|
||
margin: 0;
|
||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
|
||
z-index: 100;
|
||
|
||
li {
|
||
padding: 2px 6px;
|
||
cursor: pointer;
|
||
&:hover {
|
||
background: #f1f1f1;
|
||
}
|
||
}
|
||
}
|
||
|
||
.hidden {
|
||
display: none;
|
||
}
|
||
}
|
||
</style>
|