204 行
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			204 行
		
	
	
		
			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>
 |