Commit a37cdc3f authored by 郭铭瑶's avatar 郭铭瑶 🤘

map-btns

parent 9677f6a7
...@@ -32,6 +32,7 @@ $color-main = #5BD5FF ...@@ -32,6 +32,7 @@ $color-main = #5BD5FF
background rgba(0,0,0,0.4) background rgba(0,0,0,0.4)
border-radius 0 border-radius 0
font-size .08rem font-size .08rem
z-index 99999
.ant-select-item .ant-select-item
color #fff color #fff
font-size .08rem font-size .08rem
......
<template>
<teleport to="body">
<MyAnimate enter="fadeInRight" leave="fadeOutRight">
<div v-if="modelValue" class="my-drawer" :style="{ width: width }">
<img
src="@/assets/images/close-btn3.png"
class="close-btn"
draggable="false"
@click="closeDrawer"
/>
<div class="content"><slot /></div>
</div>
</MyAnimate>
</teleport>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue'
import MyAnimate from '../MyAnimate/my-animate.vue'
export default defineComponent({
name: 'MyDrawer',
displayName: 'm-drawer',
components: { MyAnimate },
props: {
modelValue: {
type: Boolean as PropType<boolean>,
default: false,
},
width: {
type: String as PropType<string>,
default: '49vw',
},
maskClosable: {
type: Boolean as PropType<boolean>,
default: true,
},
},
emits: ['update:modelValue', 'close'],
setup(props, ctx) {
const closeDrawer = () => {
ctx.emit('update:modelValue', false)
ctx.emit('close')
}
return {
closeDrawer,
}
},
})
</script>
<style lang="stylus" scoped>
@import '../main.styl'
.my-drawer
background url('@/assets/images/drawer-bg.png') 100% / 100% 100% no-repeat
position fixed
top .45rem
right .05rem
bottom .05rem
z-index 9999
padding .15rem .25rem
$blur()
color #fff
.close-btn
position absolute
top inherit
bottom inherit
margin auto
width .24rem
left -@width
cursor pointer
transition transform .3s ease
&:hover
transform scale(1.2)
</style>
<template>
<teleport to="body">
<MyAnimate :enter="enter" :leave="leave">
<div
v-if="modelValue"
class="my-modal-mask"
style="animation-duration: 300ms"
@click.prevent.self="
() => {
maskClosable ? closeModal() : null
}
"
>
<div
class="my-modal"
:style="`width:${width};transform: translateX(${offset})`"
>
<head>
<p>
{{ title }}
<span class="left" />
<span class="right" />
</p>
<div>
<img
src="@/assets/images/modal-flag.png"
draggable="false"
class="flag"
/>
<img
src="@/assets/images/close-btn.png"
draggable="false"
class="close-btn"
@click.prevent="closeModal"
/>
</div>
<img
src="@/assets/images/modal-title-left.png"
draggable="false"
class="left"
/>
</head>
<div class="content">
<slot />
</div>
</div>
</div>
</MyAnimate>
</teleport>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue'
import MyAnimate from '../MyAnimate/my-animate.vue'
export default defineComponent({
name: 'MyModal',
displayName: 'm-modal',
components: { MyAnimate },
props: {
modelValue: {
type: Boolean as PropType<boolean>,
default: false,
},
enter: {
type: String as PropType<string>,
default: 'fadeInDown',
},
leave: {
type: String as PropType<string>,
default: 'fadeOutUp',
},
title: {
type: String as PropType<string>,
default: '',
},
width: {
type: String as PropType<string>,
default: '32%',
},
offset: {
type: String as PropType<string>,
default: '0',
},
maskClosable: {
type: Boolean as PropType<boolean>,
default: true,
},
},
emits: ['update:modelValue', 'close'],
setup(props, context) {
const closeModal = () => {
context.emit('update:modelValue', false)
context.emit('close')
}
return {
closeModal,
}
},
})
</script>
<style lang="stylus" scoped>
@import '../main.styl'
.my-modal-mask
position fixed
top 0
right 0
bottom 0
left 0
background rgba(0,0,0,0.1)
z-index 9999
$center()
.my-modal
background rgba(0,0,0,0.1)
color #fff
$blur()
z-index 99999
head
position relative
height .4rem
display flex
align-items center
justify-content space-between
padding 0 .1rem
margin-bottom .05rem
background-image repeating-linear-gradient(45deg, $blue, $blue, .01rem, transparent .01rem, transparent .08rem)
$border($blue)
>p
font-size .12rem
font-weight bold
padding .02rem .05rem
position relative
border-bottom .01rem solid $blue
span
position absolute
width .04rem
height @width
background $edge
bottom -(@height / 2)
&.left
left -(@width / 2)
&.right
right -(@width / 2)
>div
display flex
align-items center
img
z-index 9
&.close-btn
width .2rem
height @width
cursor pointer
margin-left .05rem
transition transform .3s ease-in-out
&:hover
transform rotate(90deg)
&.flag
height .2rem
&.left
position absolute
left -0.01rem
height 80%
.content
min-height 30vh
max-height 80vh
padding .1rem
overflow-y auto
overflow-x hidden
$border($blue)
border-top none
font-size .1rem
</style>
...@@ -15,36 +15,26 @@ ...@@ -15,36 +15,26 @@
class="my-modal" class="my-modal"
:style="`width:${width};transform: translateX(${offset})`" :style="`width:${width};transform: translateX(${offset})`"
> >
<span class="edge left-top" />
<span class="edge right-top" />
<span class="edge left-bottom" />
<span class="edge right-bottom" />
<div class="inner">
<head> <head>
<p> <img draggable="false" src="@/assets/images/modal-head-tri.png" />
{{ title }} <p>{{ title }}</p>
<span class="left" />
<span class="right" />
</p>
<div>
<img <img
src="@/assets/images/modal-flag.png"
draggable="false" draggable="false"
class="flag" src="@/assets/images/close-btn2.png"
/>
<img
src="@/assets/images/close-btn.png"
draggable="false"
class="close-btn"
@click.prevent="closeModal" @click.prevent="closeModal"
/> />
</div>
<img
src="@/assets/images/modal-title-left.png"
draggable="false"
class="left"
/>
</head> </head>
<div class="content"> <div class="content">
<slot /> <slot />
</div> </div>
</div> </div>
</div> </div>
</div>
</MyAnimate> </MyAnimate>
</teleport> </teleport>
</template> </template>
...@@ -112,62 +102,72 @@ export default defineComponent({ ...@@ -112,62 +102,72 @@ export default defineComponent({
z-index 9999 z-index 9999
$center() $center()
.my-modal .my-modal
background rgba(0,0,0,0.1)
color #fff color #fff
$blur()
z-index 99999 z-index 99999
head padding .04rem
position relative background transparent
height .4rem
display flex
align-items center
justify-content space-between
padding 0 .1rem
margin-bottom .05rem
background-image repeating-linear-gradient(45deg, $blue, $blue, .01rem, transparent .01rem, transparent .08rem)
$border($blue)
>p
font-size .12rem
font-weight bold
padding .02rem .05rem
position relative position relative
border-bottom .01rem solid $blue $blur(0.01rem)
span .edge
display block
position absolute position absolute
width .04rem width .1rem
height @width height @width
background $edge border .01rem solid $secondary-color
bottom -(@height / 2) &.left-top
&.left top 0
left -(@width / 2) left 0
&.right border-right none
right -(@width / 2) border-bottom none
>div &.right-top
top 0
right 0
border-left none
border-bottom none
&.left-bottom
bottom 0
left 0
border-right none
border-top none
&.right-bottom
bottom 0
right 0
border-left none
border-top none
.inner
$blur()
background rgba(6,34,67,.8)
border .01rem solid rgba(91,213,255,.3)
head
height .28rem
background url('@/assets/images/modal-head-bg.png') 100% / 100% 100% no-repeat
display flex display flex
align-items center align-items center
img position relative
z-index 9 >p
&.close-btn font-size .14rem
width .2rem font-family $font-zcool
text-indent .14rem
line-height 1.5
>img
width .14rem
height @width height @width
position absolute
&:nth-of-type(1)
width .24rem
height @width
left -0.095rem
&:nth-of-type(2)
right .05rem
cursor pointer cursor pointer
margin-left .05rem
transition transform .3s ease-in-out transition transform .3s ease-in-out
&:hover &:hover
transform rotate(90deg) transform rotate(180deg)
&.flag
height .2rem
&.left
position absolute
left -0.01rem
height 80%
.content .content
min-height 30vh min-height 30vh
max-height 80vh max-height 80vh
padding .1rem padding .1rem
overflow-y auto overflow-y auto
overflow-x hidden overflow-x hidden
$border($blue)
border-top none
font-size .1rem font-size .1rem
</style> </style>
...@@ -21,6 +21,7 @@ import MyScatter from './MyChart/my-scatter.vue' ...@@ -21,6 +21,7 @@ import MyScatter from './MyChart/my-scatter.vue'
import MySub from './MySub/my-sub.vue' import MySub from './MySub/my-sub.vue'
import MyWaveBall from './MyWaveBall/my-wave-ball.vue' import MyWaveBall from './MyWaveBall/my-wave-ball.vue'
import MyProgress from './MyProgress/my-progress.vue' import MyProgress from './MyProgress/my-progress.vue'
import MyDrawer from './MyDrawer/my-drawer.vue'
// import { withInstall } from './util' // import { withInstall } from './util'
import 'normalize.css' import 'normalize.css'
...@@ -46,6 +47,7 @@ const components = [ ...@@ -46,6 +47,7 @@ const components = [
MySub, MySub,
MyWaveBall, MyWaveBall,
MyProgress, MyProgress,
MyDrawer,
] ]
const install = (app: App): App => { const install = (app: App): App => {
...@@ -80,6 +82,7 @@ export { ...@@ -80,6 +82,7 @@ export {
MySub, MySub,
MyWaveBall, MyWaveBall,
MyProgress, MyProgress,
MyDrawer,
} }
// 默认导出 —— 使用import MyComponent from './components/MyComponent'来引入所有组件 // 默认导出 —— 使用import MyComponent from './components/MyComponent'来引入所有组件
......
import { ref, Ref, onMounted, onUnmounted } from 'vue' import { ref, Ref, onMounted, onUnmounted } from 'vue'
export default function useClickOutside(elementRef: Ref<HTMLElement | null>) { export default function useClickOutside(
elementRef: Ref<HTMLElement | null>
): Ref<boolean> {
const isClickOutSide = ref(false) const isClickOutSide = ref(false)
const handler = (e: MouseEvent) => { const handler = (e: MouseEvent) => {
if (!elementRef || !elementRef.value) return if (!elementRef || !elementRef.value) return
...@@ -12,5 +14,5 @@ export default function useClickOutside(elementRef: Ref<HTMLElement | null>) { ...@@ -12,5 +14,5 @@ export default function useClickOutside(elementRef: Ref<HTMLElement | null>) {
onUnmounted(() => { onUnmounted(() => {
document.removeEventListener('click', handler) document.removeEventListener('click', handler)
}) })
return { isClickOutSide } return isClickOutSide
} }
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import MyComponent from '@/components/MyComponent' import MyComponent from '@/components/MyComponent'
import { Progress, Select } from 'ant-design-vue' import { Progress, Select, Input } from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css' import 'ant-design-vue/dist/antd.css'
import './assets/style/reset.styl' import './assets/style/reset.styl'
createApp(App).use(MyComponent).use(Progress).use(Select).mount('#app') createApp(App)
.use(MyComponent)
.use(Progress)
.use(Select)
.use(Input)
.mount('#app')
<template>
<div class="map-btns" :class="{ full: fullScreen }">
<img
v-for="btn in btns"
:key="btn.key"
:src="btn.icon"
draggable="false"
@click="handleClick(btn.key)"
/>
</div>
<m-modal v-model="searchModal" title="搜索">
<div id="modal-search-bar">
<span class="edge left-top" />
<span class="edge right-top" />
<span class="edge left-bottom" />
<span class="edge right-bottom" />
<a-input-group compact>
<a-select v-model:value="searchType">
<a-select-option value="case">案件</a-select-option>
<a-select-option value="population">人口</a-select-option>
</a-select>
<a-input v-model:value="searchKey" placeholder="请输入搜索关键词" />
</a-input-group>
<div class="search-btn">搜索</div>
</div>
<div class="modal-case-content">
<div
v-for="(item, i) in caseList"
:key="i"
:class="{ done: item.status === 1 }"
>
<div>
<p>
<span>{{ item.type }}</span>
{{ item.address }}
</p>
<p>{{ item.date }}</p>
</div>
<div>{{ item.content }}</div>
<div v-if="item.status === 1" class="flag">已结案</div>
<div v-else class="flag">处置中</div>
</div>
</div>
</m-modal>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import btn1 from '@/assets/images/map-btn1.png'
import btn2 from '@/assets/images/map-btn2.png'
import btn3 from '@/assets/images/map-btn3.png'
import btn4 from '@/assets/images/map-btn4.png'
import btn5 from '@/assets/images/map-btn5.png'
import btn6 from '@/assets/images/map-btn6.png'
export default defineComponent({
name: 'MapBtns',
emits: ['full'],
setup(props, ctx) {
const btns = ref([
{ key: 'search', icon: btn1 },
{ key: 'full', icon: btn2 },
{ key: '', icon: btn3 },
{ key: '', icon: btn4 },
{ key: '', icon: btn5 },
{ key: '', icon: btn6 },
])
const fullScreen = ref(false)
const searchModal = ref(false)
const handleClick = (key: string) => {
switch (key) {
case 'full':
fullScreen.value = !fullScreen.value
ctx.emit('full', fullScreen.value)
break
case 'search':
searchModal.value = true
break
default:
break
}
}
const searchType = ref('case')
const searchKey = ref('')
const caseList = ref([
{
address: 'XX区XX路XX弄XX号',
date: '2021-01-23 ~ 2021-01-24',
type: '案件分类',
status: 1,
content:
'案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述',
},
{
address: 'XX区XX路XX弄XX号',
date: '2021-01-23 ~ 2021-01-24',
type: '案件分类',
status: 0,
content:
'案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述',
},
{
address: 'XX区XX路XX弄XX号',
date: '2021-01-23 ~ 2021-01-24',
type: '案件分类',
status: 0,
content:
'案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述案件内容及描述',
},
])
return {
btns,
fullScreen,
searchModal,
handleClick,
searchType,
searchKey,
caseList,
}
},
})
</script>
<style lang="stylus">
@import '../../components/MyComponent/main.styl'
$border = .01rem solid rgba(91,213,255,.3)
$bg = rgba(6,34,67,.4)
#modal-search-bar
width 100%
position relative
margin-bottom .1rem
.edge
display block
position absolute
width .06rem
height @width
border .01rem solid $secondary-color
z-index 1
&.left-top
top 0
left 0
border-right none
border-bottom none
&.right-top
top 0
right 0
border-left none
border-bottom none
&.left-bottom
bottom 0
left 0
border-right none
border-top none
&.right-bottom
bottom 0
right 0
border-left none
border-top none
.ant-select
border-radius 0
color $secondary-color
background $bg
width .7rem
height .25rem
line-height @height
font-size .12rem
.ant-select-selector
background inherit
border-radius inherit
border $border
height inherit
line-height inherit
font-size inherit
.ant-select-selection-item
line-height inherit
.ant-select-arrow
color $secondary-color
font-size .1rem
.ant-input
width calc(100% - 0.7rem)
border $border
background $bg
color #fff
height .25rem
line-height @height
font-size .1rem
padding-right .4rem
.search-btn
height 100%
color $secondary-color
line-height .25rem
position absolute
top 0
right .1rem
cursor pointer
z-index 99999
font-size .12rem
&:hover
font-weight bold
text-decoration underline
.modal-case-content
>div
position relative
padding .1rem
border $border
border-left .02rem solid $secondary-color
margin-bottom .1rem
overflow hidden
&.done
border-left-color #27C5A2
.flag
background #27C5A2
>div
&:nth-of-type(1)
border-bottom $border
padding-bottom .1rem
margin-bottom .1rem
p
span
display inline-block
color orange
border .01rem solid orange
border-radius .02rem
margin-right .1rem
padding 0 .03rem
font-size .08rem
&:last-child
color #aaa
font-size .08rem
margin-top .05rem
.flag
background $secondary-color
position absolute
top -0.08rem
right -0.28rem
transform rotate(45deg)
height .4rem
width .8rem
display flex
align-items flex-end
justify-content center
font-weight bold
padding-bottom .02rem
</style>
<style lang="stylus" scoped>
.map-btns
position fixed
bottom .05rem
left calc(16vw + .1rem)
transition left .3s ease
&.full
left .05rem
>img
display block
width .2rem
height @width
margin-top .05rem
cursor pointer
</style>
...@@ -7,10 +7,13 @@ ...@@ -7,10 +7,13 @@
> >
<m-title area="title">南东城运</m-title> <m-title area="title">南东城运</m-title>
<m-animate enter="fadeInLeft" leave="fadeOutLeft"> <m-animate enter="fadeInLeft" leave="fadeOutLeft">
<Command v-show="'street' === curViewType" area="left" /> <Command v-show="'street' === curViewType && !fullScreen" area="left" />
</m-animate> </m-animate>
<m-animate enter="fadeInLeft" leave="fadeOutLeft"> <m-animate enter="fadeInLeft" leave="fadeOutLeft">
<ManageBasic v-show="'street' !== curViewType" area="left" /> <ManageBasic
v-show="'street' !== curViewType && !fullScreen"
area="left"
/>
</m-animate> </m-animate>
<m-animate <m-animate
...@@ -21,19 +24,26 @@ ...@@ -21,19 +24,26 @@
> >
<component <component
:is="part.component" :is="part.component"
v-show="'street' === curViewType && curTheme === part.name" v-show="
'street' === curViewType && curTheme === part.name && !fullScreen
"
area="right" area="right"
/> />
</m-animate> </m-animate>
<m-animate enter="fadeInRight" leave="fadeOutRight"> <m-animate enter="fadeInRight" leave="fadeOutRight">
<PublicWork v-show="'street' !== curViewType" area="right" /> <PublicWork
v-show="'street' !== curViewType && !fullScreen"
area="right"
/>
</m-animate> </m-animate>
<ViewSelector /> <ViewSelector />
<MapBtns @full="fullScreen = $event" />
<m-drawer v-model="showDrawer"> test </m-drawer>
</m-grid> </m-grid>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, defineComponent, ref } from 'vue'
import ManageBasic from './left/manage-basic.vue' import ManageBasic from './left/manage-basic.vue'
import Command from './left/command.vue' import Command from './left/command.vue'
import PublicWork from './right/public-work.vue' import PublicWork from './right/public-work.vue'
...@@ -41,6 +51,7 @@ import PublicManage from './right/public-manage.vue' ...@@ -41,6 +51,7 @@ import PublicManage from './right/public-manage.vue'
import PublicService from './right/public-service.vue' import PublicService from './right/public-service.vue'
import PublicSafety from './right/public-safety.vue' import PublicSafety from './right/public-safety.vue'
import ViewSelector from './components/view-selector.vue' import ViewSelector from './components/view-selector.vue'
import MapBtns from './components/map-btns.vue'
import store from '@/store' import store from '@/store'
export default defineComponent({ export default defineComponent({
...@@ -53,6 +64,7 @@ export default defineComponent({ ...@@ -53,6 +64,7 @@ export default defineComponent({
PublicService, PublicService,
PublicSafety, PublicSafety,
ViewSelector, ViewSelector,
MapBtns,
}, },
setup() { setup() {
const curViewType = computed(() => store.state.curView.type) const curViewType = computed(() => store.state.curView.type)
...@@ -71,10 +83,14 @@ export default defineComponent({ ...@@ -71,10 +83,14 @@ export default defineComponent({
component: PublicSafety, component: PublicSafety,
}, },
]) ])
const fullScreen = ref(false)
const showDrawer = ref(false)
return { return {
curViewType, curViewType,
curTheme, curTheme,
streetComponentList, streetComponentList,
fullScreen,
showDrawer,
} }
}, },
}) })
......
...@@ -96,6 +96,10 @@ module.exports = { ...@@ -96,6 +96,10 @@ module.exports = {
name: 'm-sub', name: 'm-sub',
path: './src/components/MyComponent/MySub/my-sub.vue', path: './src/components/MyComponent/MySub/my-sub.vue',
}, },
{
name: 'm-drawer',
path: './src/components/MyComponent/MyDrawer/my-drawer.vue',
},
], ],
}, },
], ],
......
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