Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
6b45ed7e
authored
Mar 17, 2024
by
芋道源码
Committed by
Gitee
Mar 17, 2024
Browse files
Options
Browse Files
Download
Plain Diff
!406 适配顶部导航
Merge pull request !406 from 疯狂的世界/dev
parents
1a0f0a11
aa57d89b
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
260 additions
and
75 deletions
+260
-75
src/assets/imgs/diy/app-nav-bar-mp.png
+0
-0
src/components/DiyEditor/components/mobile/NavigationBar/components/CellProperty.vue
+90
-0
src/components/DiyEditor/components/mobile/NavigationBar/config.ts
+64
-20
src/components/DiyEditor/components/mobile/NavigationBar/index.vue
+53
-25
src/components/DiyEditor/components/mobile/NavigationBar/property.vue
+52
-29
src/components/MagicCubeEditor/index.vue
+1
-1
No files found.
src/assets/imgs/diy/app-nav-bar-mp.png
0 → 100644
View file @
6b45ed7e
3.51 KB
src/components/DiyEditor/components/mobile/NavigationBar/components/CellProperty.vue
0 → 100644
View file @
6b45ed7e
<
template
>
<div
class=
"h-40px flex items-center justify-center"
>
<MagicCubeEditor
v-model=
"cellList"
class=
"m-b-16px"
:rows=
"1"
:cols=
"cellCount"
:cube-size=
"38"
@
hot-area-selected=
"handleHotAreaSelected"
/>
<img
src=
"@/assets/imgs/diy/app-nav-bar-mp.png"
alt=
""
class=
"h-30px w-76px"
v-if=
"isMp"
/>
</div>
<template
v-for=
"(cell, cellIndex) in cellList"
:key=
"cellIndex"
>
<template
v-if=
"selectedHotAreaIndex === cellIndex"
>
<el-form-item
label=
"类型"
:prop=
"`cell[$
{cellIndex}].type`">
<el-radio-group
v-model=
"cell.type"
>
<el-radio
label=
"text"
>
文字
</el-radio>
<el-radio
label=
"image"
>
图片
</el-radio>
<el-radio
label=
"search"
>
搜索框
</el-radio>
</el-radio-group>
</el-form-item>
<!-- 1. 文字 -->
<template
v-if=
"cell.type === 'text'"
>
<el-form-item
label=
"内容"
:prop=
"`cell[$
{cellIndex}].text`">
<el-input
v-model=
"cell!.text"
maxlength=
"10"
show-word-limit
/>
</el-form-item>
<el-form-item
label=
"颜色"
:prop=
"`cell[$
{cellIndex}].text`">
<ColorInput
v-model=
"cell!.textColor"
/>
</el-form-item>
</
template
>
<!-- 2. 图片 -->
<
template
v-else-if=
"cell.type === 'image'"
>
<el-form-item
label=
"图片"
:prop=
"`cell[$
{cellIndex}].imgUrl`">
<UploadImg
v-model=
"cell.imgUrl"
:limit=
"1"
height=
"56px"
width=
"56px"
>
<template
#
tip
>
建议尺寸 56*56
</
template
>
</UploadImg>
</el-form-item>
<el-form-item
label=
"链接"
:prop=
"`cell[${cellIndex}].url`"
>
<AppLinkInput
v-model=
"cell.url"
/>
</el-form-item>
</template>
<!-- 3. 搜索框 -->
<
template
v-else
>
<el-form-item
label=
"提示文字"
:prop=
"`cell[$
{cellIndex}].placeholder`">
<el-input
v-model=
"cell.placeholder"
maxlength=
"10"
show-word-limit
/>
</el-form-item>
<el-form-item
label=
"圆角"
:prop=
"`cell[$
{cellIndex}].borderRadius`">
<el-slider
v-model=
"cell.borderRadius"
:max=
"100"
:min=
"0"
show-input
input-size=
"small"
:show-input-controls=
"false"
/>
</el-form-item>
</
template
>
</template>
</template>
</template>
<
script
setup
lang=
"ts"
>
import
{
NavigationBarCellProperty
}
from
'../config'
import
{
usePropertyForm
}
from
'@/components/DiyEditor/util'
// 导航栏属性面板
defineOptions
({
name
:
'NavigationBarCellProperty'
})
const
props
=
defineProps
<
{
modelValue
:
NavigationBarCellProperty
[]
isMp
:
boolean
}
>
()
const
emit
=
defineEmits
([
'update:modelValue'
])
const
{
formData
:
cellList
}
=
usePropertyForm
(
props
.
modelValue
,
emit
)
if
(
!
cellList
.
value
)
cellList
.
value
=
[]
// 单元格数量:小程序6个(右侧胶囊按钮占了2个),其它平台8个
const
cellCount
=
computed
(()
=>
(
props
.
isMp
?
6
:
8
))
// 选中的热区
const
selectedHotAreaIndex
=
ref
(
0
)
const
handleHotAreaSelected
=
(
cellValue
:
NavigationBarCellProperty
,
index
:
number
)
=>
{
selectedHotAreaIndex
.
value
=
index
if
(
!
cellValue
.
type
)
{
cellValue
.
type
=
'text'
cellValue
.
textColor
=
'#111111'
}
}
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
src/components/DiyEditor/components/mobile/NavigationBar/config.ts
View file @
6b45ed7e
...
@@ -2,22 +2,53 @@ import { DiyComponent } from '@/components/DiyEditor/util'
...
@@ -2,22 +2,53 @@ import { DiyComponent } from '@/components/DiyEditor/util'
/** 顶部导航栏属性 */
/** 顶部导航栏属性 */
export
interface
NavigationBarProperty
{
export
interface
NavigationBarProperty
{
// 页面标题
// 背景类型
title
:
string
bgType
:
'color'
|
'img'
// 页面描述
// 背景颜色
description
:
string
bgColor
:
string
// 顶部导航高度
// 图片链接
navBarHeight
:
number
bgImg
:
string
// 页面背景颜色
backgroundColor
:
string
// 页面背景图片
backgroundImage
:
string
// 样式类型:默认 | 沉浸式
// 样式类型:默认 | 沉浸式
styleType
:
'
default'
|
'immersion
'
styleType
:
'
normal'
|
'inner
'
// 常驻显示
// 常驻显示
alwaysShow
:
boolean
alwaysShow
:
boolean
// 是否显示返回按钮
// 小程序单元格列表
showGoBack
:
boolean
mpCells
:
NavigationBarCellProperty
[]
// 其它平台单元格列表
otherCells
:
NavigationBarCellProperty
[]
// 本地变量
_local
:
{
// 预览顶部导航(小程序)
previewMp
:
boolean
// 预览顶部导航(非小程序)
previewOther
:
boolean
}
}
/** 顶部导航栏 - 单元格 属性 */
export
interface
NavigationBarCellProperty
{
// 类型:文字 | 图片 | 搜索框
type
:
'text'
|
'image'
|
'search'
// 宽度
width
:
number
// 高度
height
:
number
// 顶部位置
top
:
number
// 左侧位置
left
:
number
// 文字内容
text
:
string
// 文字颜色
textColor
:
string
// 图片地址
imgUrl
:
string
// 图片链接
url
:
string
// 搜索框:提示文字
placeholder
:
string
// 搜索框:边框圆角半径
borderRadius
:
number
}
}
// 定义组件
// 定义组件
...
@@ -26,13 +57,26 @@ export const component = {
...
@@ -26,13 +57,26 @@ export const component = {
name
:
'顶部导航栏'
,
name
:
'顶部导航栏'
,
icon
:
'tabler:layout-navbar'
,
icon
:
'tabler:layout-navbar'
,
property
:
{
property
:
{
title
:
'页面标题'
,
bgType
:
'color'
,
description
:
''
,
bgColor
:
'#fff'
,
navBarHeight
:
35
,
bgImg
:
''
,
backgroundColor
:
'#fff'
,
styleType
:
'normal'
,
backgroundImage
:
''
,
styleType
:
'default'
,
alwaysShow
:
true
,
alwaysShow
:
true
,
showGoBack
:
true
mpCells
:
[
{
type
:
'text'
,
textColor
:
'#111111'
}
],
otherCells
:
[
{
type
:
'text'
,
textColor
:
'#111111'
}
],
_local
:
{
previewMp
:
true
,
previewOther
:
false
}
}
}
}
as
DiyComponent
<
NavigationBarProperty
>
}
as
DiyComponent
<
NavigationBarProperty
>
src/components/DiyEditor/components/mobile/NavigationBar/index.vue
View file @
6b45ed7e
<
template
>
<
template
>
<div
<div
class=
"navigation-bar"
:style=
"bgStyle"
>
class=
"navigation-bar"
<div
class=
"h-full w-full flex items-center"
>
:style=
"
{
<div
v-for=
"(cell, cellIndex) in cellList"
:key=
"cellIndex"
:style=
"getCellStyle(cell)"
>
height: `${property.navBarHeight}px`,
<span
v-if=
"cell.type === 'text'"
>
{{
cell
.
text
}}
</span>
backgroundColor: property.backgroundColor,
<img
v-else-if=
"cell.type === 'image'"
:src=
"cell.imgUrl"
alt=
""
class=
"h-full w-full"
/>
backgroundImage: `url(${property.backgroundImage})`
<SearchBar
v-else
:property=
"getSearchProp"
/>
}"
>
<!-- 左侧 -->
<div
class=
"left"
>
<Icon
icon=
"ep:arrow-left"
v-show=
"property.showGoBack"
/>
</div>
</div>
<!-- 中间 -->
<div
class=
"center"
:style=
"
{
height: `${property.navBarHeight}px`,
lineHeight: `${property.navBarHeight}px`
}"
>
{{
property
.
title
}}
</div>
</div>
<!-- 右侧 -->
<img
<div
class=
"right"
></div>
v-if=
"property._local?.previewMp"
src=
"@/assets/imgs/diy/app-nav-bar-mp.png"
alt=
""
class=
"h-30px w-86px"
/>
</div>
</div>
</
template
>
</
template
>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
NavigationBarProperty
}
from
'./config'
import
{
NavigationBarCellProperty
,
NavigationBarProperty
}
from
'./config'
import
SearchBar
from
'@/components/DiyEditor/components/mobile/SearchBar/index.vue'
import
{
StyleValue
}
from
'vue'
import
{
SearchProperty
}
from
'@/components/DiyEditor/components/mobile/SearchBar/config'
/** 页面顶部导航栏 */
/** 页面顶部导航栏 */
defineOptions
({
name
:
'NavigationBar'
})
defineOptions
({
name
:
'NavigationBar'
})
defineProps
<
{
property
:
NavigationBarProperty
}
>
()
const
props
=
defineProps
<
{
property
:
NavigationBarProperty
}
>
()
// 背景
const
bgStyle
=
computed
(()
=>
{
const
background
=
props
.
property
.
bgType
===
'img'
&&
props
.
property
.
bgImg
?
`url(
${
props
.
property
.
bgImg
}
) no-repeat top center / 100% 100%`
:
props
.
property
.
bgColor
return
{
background
}
})
// 单元格列表
const
cellList
=
computed
(()
=>
props
.
property
.
_local
?.
previewMp
?
props
.
property
.
mpCells
:
props
.
property
.
otherCells
)
// 单元格宽度
const
cellWidth
=
computed
(()
=>
{
return
props
.
property
.
_local
?.
previewMp
?
(
375
-
80
-
86
)
/
6
:
(
375
-
90
)
/
8
})
// 获得单元格样式
const
getCellStyle
=
(
cell
:
NavigationBarCellProperty
)
=>
{
return
{
width
:
cell
.
width
*
cellWidth
.
value
+
(
cell
.
width
-
1
)
*
10
+
'px'
,
left
:
cell
.
left
*
cellWidth
.
value
+
(
cell
.
left
+
1
)
*
10
+
'px'
,
position
:
'absolute'
}
as
StyleValue
}
// 获得搜索框属性
const
getSearchProp
=
(
cell
:
NavigationBarCellProperty
)
=>
{
return
{
height
:
30
,
showScan
:
false
,
placeholder
:
cell
.
placeholder
,
borderRadius
:
cell
.
borderRadius
}
as
SearchProperty
}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.navigation-bar
{
.navigation-bar
{
display
:
flex
;
display
:
flex
;
height
:
35
px
;
height
:
50
px
;
background
:
#fff
;
background
:
#fff
;
justify-content
:
space-between
;
justify-content
:
space-between
;
align-items
:
center
;
align-items
:
center
;
padding
:
0
6px
;
/* 左边 */
/* 左边 */
.left
{
.left
{
...
...
src/components/DiyEditor/components/mobile/NavigationBar/property.vue
View file @
6b45ed7e
<
template
>
<
template
>
<el-form
label-width=
"80px"
:model=
"formData"
:rules=
"rules"
>
<el-form
label-width=
"80px"
:model=
"formData"
:rules=
"rules"
>
<el-form-item
label=
"页面标题"
prop=
"title"
>
<el-input
v-model=
"formData!.title"
placeholder=
"页面标题"
maxlength=
"25"
show-word-limit
/>
</el-form-item>
<el-form-item
label=
"页面描述"
prop=
"description"
>
<el-input
type=
"textarea"
v-model=
"formData!.description"
placeholder=
"用户通过微信分享给朋友时,会自动显示页面描述"
/>
</el-form-item>
<el-form-item
label=
"样式"
prop=
"styleType"
>
<el-form-item
label=
"样式"
prop=
"styleType"
>
<el-radio-group
v-model=
"formData!.styleType"
>
<el-radio-group
v-model=
"formData!.styleType"
>
<el-radio
label=
"default"
>
默认
</el-radio>
<el-radio
label=
"normal"
>
标准
</el-radio>
<el-radio
label=
"immersion"
>
沉浸式
</el-radio>
<el-tooltip
content=
"沉侵式头部仅支持微信小程序、APP,建议页面第一个组件为图片展示类组件"
placement=
"top"
>
<el-radio
label=
"inner"
>
沉浸式
</el-radio>
</el-tooltip>
</el-radio-group>
</el-radio-group>
</el-form-item>
</el-form-item>
<el-form-item
label=
"常驻显示"
prop=
"alwaysShow"
v-if=
"formData.styleType === 'i
mmersion
'"
>
<el-form-item
label=
"常驻显示"
prop=
"alwaysShow"
v-if=
"formData.styleType === 'i
nner
'"
>
<el-radio-group
v-model=
"formData!.alwaysShow"
>
<el-radio-group
v-model=
"formData!.alwaysShow"
>
<el-radio
:label=
"false"
>
关闭
</el-radio>
<el-radio
:label=
"false"
>
关闭
</el-radio>
<el-tooltip
content=
"常驻显示关闭后,头部小组件将在页面滑动时淡入"
placement=
"top"
>
<el-radio
:label=
"true"
>
开启
</el-radio>
<el-radio
:label=
"true"
>
开启
</el-radio>
</el-tooltip>
</el-radio-group>
</el-radio-group>
</el-form-item>
</el-form-item>
<el-form-item
label=
"高度"
prop=
"navBarHeight"
>
<el-form-item
label=
"背景类型"
prop=
"bgType"
>
<el-slider
<el-radio-group
v-model=
"formData.bgType"
>
v-model=
"formData!.navBarHeight"
<el-radio
label=
"color"
>
纯色
</el-radio>
:max=
"100"
<el-radio
label=
"img"
>
图片
</el-radio>
:min=
"35"
</el-radio-group>
show-input
input-size=
"small"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"
返回按钮"
prop=
"showGoBack
"
>
<el-form-item
label=
"
背景颜色"
prop=
"bgColor"
v-if=
"formData.bgType === 'color'
"
>
<
el-switch
v-model=
"formData!.showGoBack
"
/>
<
ColorInput
v-model=
"formData.bgColor
"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"背景
颜色"
prop=
"backgroundColor"
>
<el-form-item
label=
"背景
图片"
prop=
"bgImg"
v-else
>
<
ColorInput
v-model=
"formData!.backgroundColor
"
/>
<
UploadImg
v-model=
"formData.bgImg"
:limit=
"1"
width=
"56px"
height=
"56px
"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"背景图片"
prop=
"backgroundImage"
>
<el-card
class=
"property-group"
shadow=
"never"
>
<UploadImg
v-model=
"formData!.backgroundImage"
:limit=
"1"
>
<template
#
header
>
<template
#
tip
>
建议宽度 750px
</
template
>
<div
class=
"flex items-center justify-between"
>
</UploadImg>
<span>
内容(小程序)
</span>
<el-form-item
prop=
"_local.previewMp"
class=
"m-b-0!"
>
<el-checkbox
v-model=
"formData._local.previewMp"
@
change=
"formData._local.previewOther = !formData._local.previewMp"
>
预览
</el-checkbox
>
</el-form-item>
</el-form-item>
</div>
</
template
>
<NavigationBarCellProperty
v-model=
"formData.mpCells"
is-mp
/>
</el-card>
<el-card
class=
"property-group"
shadow=
"never"
>
<
template
#
header
>
<div
class=
"flex items-center justify-between"
>
<span>
内容(非小程序)
</span>
<el-form-item
prop=
"_local.previewOther"
class=
"m-b-0!"
>
<el-checkbox
v-model=
"formData._local.previewOther"
@
change=
"formData._local.previewMp = !formData._local.previewOther"
>
预览
</el-checkbox
>
</el-form-item>
</div>
</
template
>
<NavigationBarCellProperty
v-model=
"formData.otherCells"
:is-mp=
"false"
/>
</el-card>
</el-form>
</el-form>
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
NavigationBarProperty
}
from
'./config'
import
{
NavigationBarProperty
}
from
'./config'
import
{
usePropertyForm
}
from
'@/components/DiyEditor/util'
import
{
usePropertyForm
}
from
'@/components/DiyEditor/util'
import
NavigationBarCellProperty
from
'@/components/DiyEditor/components/mobile/NavigationBar/components/CellProperty.vue'
// 导航栏属性面板
// 导航栏属性面板
defineOptions
({
name
:
'NavigationBarProperty'
})
defineOptions
({
name
:
'NavigationBarProperty'
})
// 表单校验
// 表单校验
...
@@ -58,6 +78,9 @@ const rules = {
...
@@ -58,6 +78,9 @@ const rules = {
const
props
=
defineProps
<
{
modelValue
:
NavigationBarProperty
}
>
()
const
props
=
defineProps
<
{
modelValue
:
NavigationBarProperty
}
>
()
const
emit
=
defineEmits
([
'update:modelValue'
])
const
emit
=
defineEmits
([
'update:modelValue'
])
const
{
formData
}
=
usePropertyForm
(
props
.
modelValue
,
emit
)
const
{
formData
}
=
usePropertyForm
(
props
.
modelValue
,
emit
)
if
(
!
formData
.
value
.
_local
)
{
formData
.
value
.
_local
=
{
previewMp
:
true
,
previewOther
:
false
}
}
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
<
style
scoped
lang=
"scss"
></
style
>
src/components/MagicCubeEditor/index.vue
View file @
6b45ed7e
...
@@ -189,7 +189,7 @@ const emit = defineEmits(['update:modelValue', 'hotAreaSelected'])
...
@@ -189,7 +189,7 @@ const emit = defineEmits(['update:modelValue', 'hotAreaSelected'])
const
emitUpdateModelValue
=
()
=>
emit
(
'update:modelValue'
,
hotAreas
)
const
emitUpdateModelValue
=
()
=>
emit
(
'update:modelValue'
,
hotAreas
)
// 热区选中
// 热区选中
const
selectedHotAreaIndex
=
ref
(
-
1
)
const
selectedHotAreaIndex
=
ref
(
0
)
const
handleHotAreaSelected
=
(
hotArea
:
Rect
,
index
:
number
)
=>
{
const
handleHotAreaSelected
=
(
hotArea
:
Rect
,
index
:
number
)
=>
{
selectedHotAreaIndex
.
value
=
index
selectedHotAreaIndex
.
value
=
index
emit
(
'hotAreaSelected'
,
hotArea
,
index
)
emit
(
'hotAreaSelected'
,
hotArea
,
index
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment