Commit 9e01b914 by Sendya

add: drawer menu

parent 182bd1c3
<template>
<a-layout-header style="padding: 0px;">
<div class="header">
<a-icon class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click.native="toggle"/>
<a-icon class="trigger" v-if="device==='mobile'" :type="collapsed ? 'menu-fold' : 'menu-unfold'" @click.native="toggle"></a-icon>
<a-icon class="trigger" v-else :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click.native="toggle"/>
<div class="user-wrapper">
<span class="action">
<a-icon type="question-circle-o"></a-icon>
......@@ -56,6 +58,11 @@
required: false,
default: false
},
device: {
type: String,
required: false,
default: 'desktop'
}
},
data() {
return {
......
<template>
<a-layout class="layout">
<a-drawer v-if="device === 'mobile'"
wrapClassName="drawer-sider"
placement="left"
@close="() => this.collapsed = false"
:closable="false"
:visible="collapsed"
>
<sider-menu
mode="inline"
:menus="menus"
:theme="theme"
:collapsed="false"
:collapsible="true"></sider-menu>
</a-drawer>
<sider-menu
v-else
:menus="menus"
:theme="theme"
v-if="menuMode === 'inline'"
:mode="menuMode"
:collapsed="!siderOpen || collapsed"
:collapsible="true"></sider-menu>
<a-layout>
<!-- layout header -->
<layout-header :collapsed="collapsed" @toggle="toggle"/>
<layout-header :collapsed="collapsed" :device="device" @toggle="toggle"/>
<!-- layout content -->
<a-layout-content :style="{ margin: '24px 24px 0', height: '100%' }">
<!-- content -->
......@@ -51,11 +65,14 @@
},
created () {
this.menus = asyncRouterMap
console.log( this.collapsed )
},
computed: {
...mapState({
siderOpen: state => state.app.sidebar.opened,
theme: state => state.app.theme
theme: state => state.app.theme,
device: state => state.app.device,
})
},
methods: {
......@@ -93,6 +110,59 @@
}
}
.header {
height: 64px;
padding: 0 12px 0 0;
background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
position: relative;
.user-wrapper {
float: right;
height: 100%;
.action {
cursor: pointer;
padding: 0 12px;
display: inline-block;
transition: all .3s;
height: 100%;
&:hover {
background: #e6f7ff;
}
.avatar {
margin: 20px 8px 20px 0;
color: #1890ff;
background: hsla(0, 0%, 100%, .85);
vertical-align: middle;
}
.icon {
font-size: 16px;
padding: 4px;
}
}
}
}
// 内容区
.layout-content {
margin: 24px 24px 0px;
height: 100%;
}
}
// drawer-sider 自定义
.ant-drawer.drawer-sider {
.ant-drawer-body {
padding: 0
}
}
// 菜单样式
.sider {
box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
position: relative;
......@@ -146,51 +216,6 @@
}
.header {
height: 64px;
padding: 0 12px 0 0;
background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
position: relative;
.user-wrapper {
float: right;
height: 100%;
.action {
cursor: pointer;
padding: 0 12px;
display: inline-block;
transition: all .3s;
height: 100%;
&:hover {
background: #e6f7ff;
}
.avatar {
margin: 20px 8px 20px 0;
color: #1890ff;
background: hsla(0, 0%, 100%, .85);
vertical-align: middle;
}
.icon {
font-size: 16px;
padding: 4px;
}
}
}
}
// 内容区
.layout-content {
margin: 24px 24px 0px;
height: 100%;
}
}
// 外置的样式控制
.user-dropdown-menu-wrapper.ant-dropdown-menu {
padding: 4px 0;
......
<template>
<a-layout-sider
:class="['sider', isMobile ? null : 'shadow', theme ]"
width="256px"
:collapsible="collapsible"
v-model="collapsed"
:trigger="null">
<div class="logo">
<router-link :to="{name:'dashboard'}">
<img src="~@/assets/logo.svg" alt="logo">
<h1>Ant Design Pro</h1>
</router-link>
</div>
<s-menu
:collapsed="collapsed"
:menu="menus"
:theme="theme"
@select="onSelect"
:mode="mode"
style="padding: 16px 0px;"></s-menu>
</a-layout-sider>
</template>
<script>
import ALayoutSider from "ant-design-vue/es/layout/Sider"
import SMenu from './index'
export default {
name: "SiderMenu",
components: { ALayoutSider, SMenu },
props: {
mode: {
type: String,
required: false,
default: 'inline'
},
theme: {
type: String,
required: false,
default: 'dark'
},
collapsible: {
type: Boolean,
required: false,
default: false
},
collapsed: {
type: Boolean,
required: false,
default: false
},
menus: {
type: Array,
required: true
}
},
created () {
},
computed: {
isMobile () {
return this.$store.state.app.device !== 'desktop'
}
},
methods: {
onSelect (obj) {
this.$emit('menuSelect', obj)
}
}
}
</script>
\ No newline at end of file
......@@ -31,7 +31,7 @@ export default {
},
showAlertInfo: {
type: Boolean,
default: true
default: false
},
}),
watch: {
......
<template>
<div :class="['detail-list', size === 'small' ? 'small' : 'large', layout === 'vertical' ? 'vertical': 'horizontal']">
<div :class="['detail-list', size, layout === 'vertical' ? 'vertical': 'horizontal']">
<div v-if="title" class="title">{{ title }}</div>
<a-row>
<slot></slot>
......@@ -8,25 +8,140 @@
</template>
<script>
export default {
name: "DetailList",
import { Col } from 'ant-design-vue/es/grid/'
const Item = {
name: 'DetailListItem',
props: {
term: {
type: String,
default: null
}
default: '',
required: false
},
},
inject: {
col: {
type: Number
}
},
methods: {
render () {
return (
<Col {...{props: responsive[this.col]}}>
<div class="term">{this.$props.term}</div>
<div class="content">{this.$slots.default}</div>
</Col>
)
}
}
const responsive = {
1: { xs: 24 },
2: { xs: 24, sm: 12 },
3: { xs: 24, sm: 12, md: 8 },
4: { xs: 24, sm: 12, md: 6 }
}
export default {
name: "DetailList",
Item: Item,
components: {
Col
},
props: {
title: {
type: String,
default: '',
required: false
},
col: {
type: Number,
required: false,
default: 3
},
size: {
type: String,
required: false,
default: 'large'
},
layout: {
type: String,
required: false,
default: 'horizontal'
}
},
provide () {
return {
col: this.col > 4 ? 4 : this.col
}
}
}
</script>
<style scoped>
<style lang="scss">
.detail-list {
.title {
color: rgba(0,0,0,.85);
font-size: 14px;
font-weight: 500;
margin-bottom: 16px;
}
.term {
color: rgba(0,0,0,.85);
display: table-cell;
line-height: 20px;
margin-right: 8px;
padding-bottom: 16px;
white-space: nowrap;
&:after {
content: ":";
margin: 0 8px 0 2px;
position: relative;
top: -.5px;
}
}
.content {
color: rgba(0,0,0,.65);
display: table-cell;
line-height: 22px;
padding-bottom: 16px;
width: 100%;
}
&.small {
.title {
font-size: 14px;
color: rgba(0, 0, 0, .65);
font-weight: normal;
margin-bottom: 12px;
}
.term, .content {
padding-bottom: 8px;
}
}
&.large {
.term, .content {
padding-bottom: 16px;
}
.title {
font-size: 16px;
}
}
&.vertical {
.term {
padding-bottom: 8px;
}
.term, .content {
display: block;
}
}
}
</style>
\ No newline at end of file
......@@ -164,7 +164,7 @@ export const asyncRouterMap = [
},
{
path: '/profile',
component: LayoutBase,
component: Layout,
name: 'profile',
redirect: '/profile/basic',
meta: { title: '详情页', icon: 'profile' },
......@@ -172,13 +172,13 @@ export const asyncRouterMap = [
{
path: '/profile/basic',
name: 'ProfileBasic',
component: () => import('../views/profile/basic/Index'),
component: () => import('@/views/profile/basic/Index'),
meta: { title: '基础详情页' }
},
{
path: '/profile/advanced',
name: 'ProfileAdvanced',
component: () => import('../views/list/TableList'),
component: () => import('@/views/profile/advanced/Advanced'),
meta: { title: '高级详情页' }
}
]
......
<template>
<page-layout>
<a-card :bordered="false">
basic
<detail-list title="退款申请">
<detail-list-item term="取货单号">1000000000</detail-list-item>
<detail-list-item term="状态">已取货</detail-list-item>
<detail-list-item term="销售单号">1234123421</detail-list-item>
<detail-list-item term="子订单">3214321432</detail-list-item>
</detail-list>
<a-divider style="margin-bottom: 32px"/>
<detail-list title="用户信息">
<detail-list-item term="用户姓名">付小小</detail-list-item>
<detail-list-item term="联系电话">18100000000</detail-list-item>
<detail-list-item term="常用快递">菜鸟仓储</detail-list-item>
<detail-list-item term="取货地址">浙江省杭州市西湖区万塘路18号</detail-list-item>
<detail-list-item term="备注"></detail-list-item>
</detail-list>
<a-divider style="margin-bottom: 32px"/>
<div class="title">退货商品</div>
<s-table
style="margin-bottom: 24px" :columns="goodsColumns" :data="loadGoodsData">
</s-table>
<div class="title">退货进度</div>
<s-table
style="margin-bottom: 24px" :columns="scheduleColumns" :data="loadScheduleData">
<template
slot="status"
slot-scope="status">
<a-badge :status="status" :text="status | statusFilter"/>
</template>
</s-table>
</a-card>
</page-layout>
</template>
<script>
export default {}
</script>
import PageLayout from '@/components/layout/PageLayout'
import STable from '@/components/table/'
import DetailList from '@/components/tools/DetailList'
import ABadge from "ant-design-vue/es/badge/Badge";
const DetailListItem = DetailList.Item
export default {
components: {
PageLayout,
ABadge,
DetailList,
DetailListItem,
STable
},
data () {
return {
goodsColumns: [
{
title: '商品编号',
dataIndex: 'id',
key: 'id'
},
{
title: '商品名称',
dataIndex: 'name',
key: 'name'
},
{
title: '商品条码',
dataIndex: 'barcode',
key: 'barcode'
},
{
title: '单价',
dataIndex: 'price',
key: 'price',
align: 'right'
},
{
title: '数量(件)',
dataIndex: 'num',
key: 'num',
align: 'right'
},
{
title: '金额',
dataIndex: 'amount',
key: 'amount',
align: 'right'
}
],
// 加载数据方法 必须为 Promise 对象
loadGoodsData: parameter => {
return new Promise((resolve => {
resolve({
data: [
{
id: '1234561',
name: '矿泉水 550ml',
barcode: '12421432143214321',
price: '2.00',
num: '1',
amount: '2.00'
},
{
id: '1234562',
name: '凉茶 300ml',
barcode: '12421432143214322',
price: '3.00',
num: '2',
amount: '6.00'
},
{
id: '1234563',
name: '好吃的薯片',
barcode: '12421432143214323',
price: '7.00',
num: '4',
amount: '28.00'
},
{
id: '1234564',
name: '特别好吃的蛋卷',
barcode: '12421432143214324',
price: '8.50',
num: '3',
amount: '25.50'
}
],
pageSize: 10,
pageNo: 1,
totalPage: 1,
totalCount: 10
})
})).then(res => {
return res
})
},
<style scoped>
scheduleColumns: [
{
title: '时间',
dataIndex: 'time',
key: 'time'
},
{
title: '当前进度',
dataIndex: 'rate',
key: 'rate'
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
scopedSlots: { customRender: 'status' },
},
{
title: '操作员ID',
dataIndex: 'operator',
key: 'operator'
},
{
title: '耗时',
dataIndex: 'cost',
key: 'cost'
}
],
loadScheduleData: parameter => {
return new Promise((resolve => {
resolve({
data: [
{
key: '1',
time: '2017-10-01 14:10',
rate: '联系客户',
status: 'processing',
operator: '取货员 ID1234',
cost: '5mins'
},
{
key: '2',
time: '2017-10-01 14:05',
rate: '取货员出发',
status: 'success',
operator: '取货员 ID1234',
cost: '1h'
},
{
key: '3',
time: '2017-10-01 13:05',
rate: '取货员接单',
status: 'success',
operator: '取货员 ID1234',
cost: '5mins'
},
{
key: '4',
time: '2017-10-01 13:00',
rate: '申请审批通过',
status: 'success',
operator: '系统',
cost: '1h'
},
{
key: '5',
time: '2017-10-01 12:00',
rate: '发起退货申请',
status: 'success',
operator: '用户',
cost: '5mins'
}
],
pageSize: 10,
pageNo: 1,
totalPage: 1,
totalCount: 10
})
})).then(res => {
return res
})
},
}
},
filters: {
statusFilter(status) {
const statusMap = {
'processing': '进行中',
'success': '完成',
'failed': '失败'
}
return statusMap[status]
}
}
}
</script>
<style lang="scss" scoped>
.title {
color: rgba(0,0,0,.85);
font-size: 16px;
font-weight: 500;
margin-bottom: 16px;
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment