Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
H
hls-easy-ui
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
easyUI
hls-easy-ui
Commits
565b1d5f
Commit
565b1d5f
authored
Aug 16, 2024
by
王纵
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
将布局组件都归入动态组件中
parent
4c697b4b
Changes
19
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
2201 additions
and
11 deletions
+2201
-11
README.md
src/Dynamic/LayoutComponents/DContent/README.md
+11
-0
index.vue
src/Dynamic/LayoutComponents/DContent/index.vue
+144
-0
README.md
src/Dynamic/LayoutComponents/DHeader/README.md
+14
-0
index.vue
src/Dynamic/LayoutComponents/DHeader/index.vue
+180
-0
index.vue
src/Dynamic/LayoutComponents/DScroll/Bubble/index.vue
+139
-0
index.vue
src/Dynamic/LayoutComponents/DScroll/Loading/index.vue
+20
-0
loading.gif
src/Dynamic/LayoutComponents/DScroll/Loading/loading.gif
+0
-0
README.md
src/Dynamic/LayoutComponents/DScroll/README.md
+16
-0
index.js
src/Dynamic/LayoutComponents/DScroll/index.js
+16
-0
index.vue
src/Dynamic/LayoutComponents/DScroll/index.vue
+591
-0
index.vue.bak
src/Dynamic/LayoutComponents/DScroll/index.vue.bak
+578
-0
index.js
src/Dynamic/LayoutComponents/DScroll/mixins/index.js
+10
-0
scroll.bak
src/Dynamic/LayoutComponents/DScroll/scroll.bak
+306
-0
index.js
src/Dynamic/LayoutComponents/DScroll/utils/index.js
+14
-0
README.md
src/Dynamic/LayoutComponents/DView/README.md
+12
-0
index.vue
src/Dynamic/LayoutComponents/DView/index.vue
+95
-0
index.js
src/Dynamic/LayoutComponents/index.js
+20
-0
index.vue
src/Dynamic/index.vue
+15
-10
utils.js
src/Dynamic/utils/utils.js
+20
-1
No files found.
src/Dynamic/LayoutComponents/DContent/README.md
0 → 100755
View file @
565b1d5f
HContent 内容区域
```
html
<h-view>
<h-content>
<div>
内容
</div>
</h-content>
<h-view>
```
src/Dynamic/LayoutComponents/DContent/index.vue
0 → 100755
View file @
565b1d5f
/**
* @Author Think
* @Date 2018/11/24
*/
<
template
>
<div
class=
"content"
>
<slot/>
</div>
</
template
>
<
script
>
export
default
{
name
:
'DContent'
,
props
:
{
calContent
:
{
type
:
Boolean
,
default
:
true
,
},
},
data
()
{
return
{
orientation
:
'portrait'
,
}
},
mounted
()
{
if
(
this
.
calContent
)
{
this
.
resizeHeight
()
}
},
update
()
{
// if (this.calContent) {
// this.resizeHeight()
// }
},
methods
:
{
getHeaderHeight
()
{
let
vm
=
this
let
$el
=
vm
.
$el
.
previousElementSibling
let
headerHeight
=
0
do
{
if
(
$el
)
{
// let elHeight = window.getComputedStyle($el).offsetHeight
headerHeight
+=
$el
.
offsetHeight
/* let part = /^\d+(\.\d+)?px$/
if (elHeight && part.test(elHeight)) {
headerHeight += Number(elHeight.replace('px', ''))
} else {
headerHeight = elHeight
} */
/* let paddingTopHeight = window.getComputedStyle($el).paddingTop
let paddingBottomHeight = window.getComputedStyle($el).paddingBottom
if (paddingTopHeight && part.test(paddingTopHeight)) {
headerHeight += Number(paddingTopHeight.replace('px', ''))
}
if (paddingBottomHeight && part.test(paddingBottomHeight)) {
headerHeight += Number(paddingBottomHeight.replace('px', ''))
} */
$el
=
$el
.
previousElementSibling
}
}
while
(
$el
)
return
headerHeight
},
getNextElementHeight
()
{
let
vm
=
this
let
nextElement
=
vm
.
$el
.
nextElementSibling
let
nextHeight
=
0
do
{
if
(
nextElement
)
{
let
position
=
window
.
getComputedStyle
(
nextElement
).
position
if
(
position
!==
'fixed'
)
{
// let elHeight = window.getComputedStyle(nextElement).offsetHeight
nextHeight
+=
nextElement
.
offsetHeight
/* let part = /^\d+(\.\d+)?px$/
if (elHeight && part.test(elHeight)) {
nextHeight += Number(elHeight.replace('px', ''))
} else {
nextHeight = elHeight
} */
// let paddingTopHeight = window.getComputedStyle(nextElement).paddingTop
// let paddingBottomHeight = window.getComputedStyle(nextElement).paddingBottom
// if (paddingTopHeight && part.test(paddingTopHeight)) {
// nextHeight += Number(paddingTopHeight.replace('px', ''))
// }
// if (paddingBottomHeight && part.test(paddingBottomHeight)) {
// nextHeight += Number(paddingBottomHeight.replace('px', ''))
// }
}
nextElement
=
nextElement
.
nextElementSibling
}
}
while
(
nextElement
)
return
nextHeight
},
async
resizeHeight
()
{
let
vm
=
this
await
this
.
$nextTick
()
const
headerHeight
=
vm
.
getHeaderHeight
()
const
nextHeight
=
vm
.
getNextElementHeight
()
let
windowHeight
=
window
.
innerHeight
||
document
.
documentElement
.
clientHeight
||
document
.
body
.
clientHeight
let
windowWidth
=
window
.
innerWidth
||
document
.
documentElement
.
clientWidth
||
document
.
body
.
clientWidth
if
(
windowWidth
>
windowHeight
)
{
this
.
orientation
=
'landscape'
}
else
{
this
.
orientation
=
'portrait'
}
let
content
=
vm
.
$el
content
.
style
.
height
=
windowHeight
-
headerHeight
-
nextHeight
+
'px'
},
},
}
</
script
>
<
style
lang=
"less"
>
.content {
flex: 1;
overflow: hidden;
background-color: #fafafa;
position: relative;
overflow-y: scroll;
height: 100%;
-webkit-overflow-scrolling: touch;
overflow-scrolling: touch;
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios {
.has-header {
top: 84px;
}
}
}
// iPhoneX Max适配
@media (device-width: 414px) and (device-height: 896px) {
.platform-ios {
.has-header {
top: 84px;
}
}
}
</
style
>
src/Dynamic/LayoutComponents/DHeader/README.md
0 → 100755
View file @
565b1d5f
HHeader 头部导航
```
html
<h-header
class=
"bar-custom"
>
<div
slot=
"left"
class=
"h-header-btn"
@
click=
"$routeGo()"
>
<i
class=
"ion-ios-arrow-back"
/>
</div>
<div
slot=
"center"
>
意见反馈
</div>
<div
slot=
"right"
class=
"h-header-btn"
>
测试
</div>
</h-header>
```
src/Dynamic/LayoutComponents/DHeader/index.vue
0 → 100755
View file @
565b1d5f
/**
* @Author Think
* @Date 2018/11/24
*/
<
template
>
<header
:class=
"[borderCss,cusClass]"
class=
"h-header"
>
<!--左侧按钮-->
<section
:style=
"
{'flex':proportion[0] }" class="h-header-left">
<div
class=
"h-header-btn"
>
<slot
name=
"left"
/>
</div>
</section>
<!--中间Title-->
<h1
:style=
"
{'flex':proportion[1] }" class="h-header-center">
<slot
name=
"center"
/>
</h1>
<!--右侧区域-->
<section
:style=
"
{'flex':proportion[2] }" class="h-header-right">
<slot
name=
"right"
/>
</section>
</header>
</
template
>
<
script
>
export
default
{
name
:
'DHeader'
,
props
:
{
proportion
:
{
// slot left/center/right 横向面积比例
type
:
Array
,
default
:
()
=>
[
1
,
2
,
1
],
},
hasBorder
:
{
type
:
Boolean
,
default
:
true
,
},
cusClass
:
{
type
:
String
,
default
:
''
,
},
},
computed
:
{
borderCss
()
{
return
this
.
hasBorder
===
true
?
'vue-1px-b'
:
''
},
},
}
</
script
>
<
style
lang=
"less"
>
.h-header {
flex-shrink: 0;
height: 44px;
background: #fff;
display: flex;
align-items: center;
color: #4A4A4A;
box-sizing: content-box;
overflow: hidden;
position: relative;
z-index: 5;
width: 100%;
.h-header-center {
flex: 1;
font-size: 17px;
font-weight: 500;
line-height: 44px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
padding: 0;
margin: 0;
> * {
overflow: hidden;
text-overflow: ellipsis;
}
}
.h-header-left, .h-header-right {
flex: 0.5;
height: 100%;
white-space: nowrap;
overflow: hidden;
}
.h-header-left {
text-align: left;
.h-header-btn {
&:first-of-type {
padding-left: 15px;
}
}
}
.h-header-right {
text-align: right;
.h-header-btn {
justify-content: flex-end;
&:last-of-type {
padding-right: 15px;
}
}
}
// 头部按钮的推荐样式
.h-header-btn {
display: inline-flex;
align-items: center;
font-size: 16px;
min-width: 60px;
height: 100%;
overflow: hidden;
vertical-align: middle;
box-sizing: border-box;
width: 80%;
color:@headerColor;
}
.ion-ios-arrow-back {
font-size: 32px;
//color: @headerColor;
}
}
.h-header-border {
border-bottom: 1px solid rgba(0, 0, 0, .1); /*no*/
}
.bar-custom {
background-color: @headerColor;
border-bottom: none;
.buttons {
.button {
color: #fff;
}
}
.title {
color: #fff;
}
.h-header-left, .h-header-right{
.h-header-btn{
color: #fff;
}
}
.h-header-center{
color: #fff;
}
}
// ios平台
.platform-ios .h-header {
padding-top: 20px;
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios {
.h-header {
padding-top: 40px;
}
}
}
// iPhoneX Max适配
@media (device-width: 414px) and (device-height: 896px) {
.platform-ios {
.h-header {
padding-top: 40px;
}
}
}
</
style
>
src/Dynamic/LayoutComponents/DScroll/Bubble/index.vue
0 → 100755
View file @
565b1d5f
<
template
>
<canvas
ref=
"bubble"
:width=
"width"
:height=
"height"
:style=
"style"
/>
</
template
>
<
script
>
export
default
{
props
:
{
y
:
{
type
:
Number
,
default
:
0
,
},
},
data
()
{
return
{
width
:
40
,
height
:
60
,
}
},
computed
:
{
distance
()
{
return
Math
.
max
(
0
,
Math
.
min
(
this
.
y
*
this
.
ratio
,
this
.
maxDistance
))
},
style
()
{
return
`width:
${
this
.
width
/
this
.
ratio
}
px;height:
${
this
.
height
/
this
.
ratio
}
px`
},
},
watch
:
{
y
()
{
this
.
_draw
()
},
},
created
()
{
this
.
ratio
=
1
this
.
width
*=
this
.
ratio
this
.
height
*=
this
.
ratio
this
.
initRadius
=
10
*
this
.
ratio
// 外面阴影
this
.
minHeadRadius
=
10
*
this
.
ratio
this
.
minTailRadius
=
4
*
this
.
ratio
this
.
initArrowRadius
=
6
*
this
.
ratio
// 里面的刷新
this
.
minArrowRadius
=
6
*
this
.
ratio
this
.
arrowWidth
=
3
*
this
.
ratio
this
.
maxDistance
=
30
*
this
.
ratio
this
.
initCenterX
=
20
*
this
.
ratio
this
.
initCenterY
=
20
*
this
.
ratio
this
.
headCenter
=
{
x
:
this
.
initCenterX
,
y
:
this
.
initCenterY
,
}
},
mounted
()
{
this
.
_draw
()
},
methods
:
{
_draw
()
{
const
bubble
=
this
.
$refs
.
bubble
let
ctx
=
bubble
.
getContext
(
'2d'
)
ctx
.
clearRect
(
0
,
0
,
bubble
.
width
,
bubble
.
height
)
this
.
_drawBubble
(
ctx
)
this
.
_drawArrow
(
ctx
)
},
_drawBubble
(
ctx
)
{
ctx
.
save
()
ctx
.
beginPath
()
const
rate
=
this
.
distance
/
this
.
maxDistance
const
headRadius
=
this
.
initRadius
-
(
this
.
initRadius
-
this
.
minHeadRadius
)
*
rate
this
.
headCenter
.
y
=
this
.
initCenterY
-
(
this
.
initRadius
-
this
.
minHeadRadius
)
*
rate
// 画上半弧线
ctx
.
arc
(
this
.
headCenter
.
x
,
this
.
headCenter
.
y
,
headRadius
,
0
,
Math
.
PI
,
true
)
// 画左侧贝塞尔
const
tailRadius
=
this
.
initRadius
-
(
this
.
initRadius
-
this
.
minTailRadius
)
*
rate
const
tailCenter
=
{
x
:
this
.
headCenter
.
x
,
y
:
this
.
headCenter
.
y
+
this
.
distance
,
}
const
tailPointL
=
{
x
:
tailCenter
.
x
-
tailRadius
,
y
:
tailCenter
.
y
,
}
const
controlPointL
=
{
x
:
tailPointL
.
x
,
y
:
tailPointL
.
y
-
this
.
distance
/
2
,
}
ctx
.
quadraticCurveTo
(
controlPointL
.
x
,
controlPointL
.
y
,
tailPointL
.
x
,
tailPointL
.
y
)
// 画下半弧线
ctx
.
arc
(
tailCenter
.
x
,
tailCenter
.
y
,
tailRadius
,
Math
.
PI
,
0
,
true
)
// 画右侧贝塞尔
const
headPointR
=
{
x
:
this
.
headCenter
.
x
+
headRadius
,
y
:
this
.
headCenter
.
y
,
}
const
controlPointR
=
{
x
:
tailCenter
.
x
+
tailRadius
,
y
:
headPointR
.
y
+
this
.
distance
/
2
,
}
ctx
.
quadraticCurveTo
(
controlPointR
.
x
,
controlPointR
.
y
,
headPointR
.
x
,
headPointR
.
y
)
ctx
.
fillStyle
=
'rgb(170,170,170)'
ctx
.
fill
()
ctx
.
strokeStyle
=
'rgb(153,153,153)'
ctx
.
stroke
()
ctx
.
restore
()
},
_drawArrow
(
ctx
)
{
ctx
.
save
()
ctx
.
beginPath
()
const
rate
=
this
.
distance
/
this
.
maxDistance
const
arrowRadius
=
this
.
initArrowRadius
-
(
this
.
initArrowRadius
-
this
.
minArrowRadius
)
*
rate
// 画内圆
ctx
.
arc
(
this
.
headCenter
.
x
,
this
.
headCenter
.
y
,
arrowRadius
-
(
this
.
arrowWidth
-
rate
),
-
Math
.
PI
/
2
,
0
,
true
)
// 画外圆
ctx
.
arc
(
this
.
headCenter
.
x
,
this
.
headCenter
.
y
,
arrowRadius
,
0
,
Math
.
PI
*
3
/
2
,
false
)
ctx
.
lineTo
(
this
.
headCenter
.
x
,
this
.
headCenter
.
y
-
arrowRadius
-
this
.
arrowWidth
/
2
+
rate
)
ctx
.
lineTo
(
this
.
headCenter
.
x
+
this
.
arrowWidth
*
2
-
rate
*
2
,
this
.
headCenter
.
y
-
arrowRadius
+
this
.
arrowWidth
/
2
)
ctx
.
lineTo
(
this
.
headCenter
.
x
,
this
.
headCenter
.
y
-
arrowRadius
+
this
.
arrowWidth
*
3
/
2
-
rate
)
ctx
.
fillStyle
=
'rgb(255,255,255)'
ctx
.
fill
()
ctx
.
strokeStyle
=
'rgb(170,170,170)'
ctx
.
stroke
()
ctx
.
restore
()
},
},
}
</
script
>
src/Dynamic/LayoutComponents/DScroll/Loading/index.vue
0 → 100755
View file @
565b1d5f
<
template
>
<div
:class=
"c('-loading-container')"
>
<img
src=
"./loading.gif"
>
</div>
</
template
>
<
script
type=
"text/ecmascript-6"
>
import
mixin
from
'../mixins'
export
default
{
name
:
'Loading'
,
mixins
:
[
mixin
],
}
</
script
>
<
style
lang=
"stylus"
>
.vue-better-scroll-loading-container
> img
width 25px
height 25px
display block
</
style
>
src/Dynamic/LayoutComponents/DScroll/Loading/loading.gif
0 → 100755
View file @
565b1d5f
3.91 KB
src/Dynamic/LayoutComponents/DScroll/README.md
0 → 100755
View file @
565b1d5f
滚动组件
```
html
基于better-scroll
<scroll
ref=
"scroll"
:autoUpdate=
"true"
:pullUp=
"true"
class=
"has-header"
@
pullingUp=
"loadMore"
>
滚动内容
</scroll>
```
src/Dynamic/LayoutComponents/DScroll/index.js
0 → 100755
View file @
565b1d5f
/*
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-16 11:26:14
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-16 11:30:55
* @Version: 1.0.0
* @Description: 滚动
* @Copyright: Copyright (c) 2021, Hand-RongJing
*/
import
DScroll
from
'./index.vue'
DScroll
.
install
=
function
(
Vue
)
{
Vue
.
component
(
DScroll
.
name
,
DScroll
)
}
export
default
DScroll
src/Dynamic/LayoutComponents/DScroll/index.vue
0 → 100755
View file @
565b1d5f
This diff is collapsed.
Click to expand it.
src/Dynamic/LayoutComponents/DScroll/index.vue.bak
0 → 100755
View file @
565b1d5f
This diff is collapsed.
Click to expand it.
src/Dynamic/LayoutComponents/DScroll/mixins/index.js
0 → 100755
View file @
565b1d5f
const
pre
=
'vue-better-scroll'
export
default
{
methods
:
{
// 生成 css class
c
(
className
)
{
return
className
?
`
${
pre
}${
className
}
`
:
`
${
pre
}
`
},
},
}
src/Dynamic/LayoutComponents/DScroll/scroll.bak
0 → 100755
View file @
565b1d5f
<template>
<div class="scroll"
:class="{
'pull-down': (state === 0),
'pull-up': (state === 1),
refreshing: (state === 2),
touching: touching
}"
@touchstart="onRefresh ? touchStart($event) : undefined"
@touchmove="onRefresh ? touchMove($event) : undefined"
@touchend="onRefresh ? touchEnd($event) : undefined"
@mousedown="onRefresh ? mouseDown($event) : undefined"
@mousemove="onRefresh ? mouseMove($event) : undefined"
@mouseup="onRefresh ? mouseUp($event) : undefined"
@scroll="(onInfinite || infiniteLoading) ? onScroll($event) : undefined"
>
<div class="scroll-inner"
:style="{
transform: 'translate3d(0, ' + top + 'px, 0)',
webkitTransform: 'translate3d(0, ' + top + 'px, 0)'
}"
>
<div class="pull-to-refresh-layer" v-if="!!onRefresh">
<slot name="refresh">
<div class="preloader"></div>
<div class="pull-to-refresh-arrow"></div>
<span class="label-down">下拉刷新</span>
<span class="label-up">释放刷新</span>
<span class="label-refresh">正在刷新..</span>
</slot>
</div>
<slot></slot>
<div class="infinite-layer" v-if="onInfinite">
<slot name="infinite">
<div class="infinite-preloader"></div>
<span class="label-loading">正在加载..</span>
</slot>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
@layer-height: 80px;
@color-text-gray: #aaa;
@keyframes preloader-spin {
100% {
transform: rotate(360deg);
}
}
.pull-to-refresh-layer {
position: relative;
left: 0;
top: 0;
width: 100%;
height: @layer-height;
color: @color-text-gray;
.preloader {
visibility: hidden;
width: 40px;
height: 40px;
animation: preloader-spin 1s steps(12, end) infinite;
&:after {
display: block;
width: 100%;
height: 100%;
content: "";
background-image: url("data:image/svg+xml;charset=utf-8,<svg viewBox='0 0 120 120' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><defs><line id='l' x1='60' x2='60' y1='7' y2='27' stroke='#6c6c6c' stroke-width='11' stroke-linecap='round'/></defs><g><use xlink:href='#l' opacity='.27'/><use xlink:href='#l' opacity='.27' transform='rotate(30 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(60 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(90 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(120 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(150 60,60)'/><use xlink:href='#l' opacity='.37' transform='rotate(180 60,60)'/><use xlink:href='#l' opacity='.46' transform='rotate(210 60,60)'/><use xlink:href='#l' opacity='.56' transform='rotate(240 60,60)'/><use xlink:href='#l' opacity='.66' transform='rotate(270 60,60)'/><use xlink:href='#l' opacity='.75' transform='rotate(300 60,60)'/><use xlink:href='#l' opacity='.85' transform='rotate(330 60,60)'/></g></svg>");
background-repeat: no-repeat;
background-position: center;
background-size: 100%;
}
}
.pull-to-refresh-arrow {
width: 40px;
height: 40px;
background: no-repeat center;
background-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 40'><polygon points='9,22 9,0 17,0 17,22 26,22 13.5,40 0,22' fill='#8c8c8c'/></svg>");
background-size: 20.8px 32px;
z-index: 10;
transform: rotate(0deg) translate3d(0, 0, 0);
transition-duration: 300ms;
margin-left: -40px;
}
}
.scroll {
position: absolute;
top: -@layer-height;
right: 0;
bottom: 0;
left: 0;
overflow-x: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
&.touching .scroll-inner {
transition-duration: 0ms;
}
&:not(.refreshing) {
.pull-to-refresh-layer .preloader {
animation: none;
}
}
&.refreshing {
.pull-to-refresh-arrow {
visibility: hidden;
transition-duration: 0ms;
}
.preloader {
visibility: visible;
}
}
&.pull-up {
.pull-to-refresh-arrow {
transform: rotate(180deg) translate3d(0, 0, 0);
}
}
}
.scroll-inner {
position: absolute;
/* top: -@layer-height; */
top: 0;
width: 100%;
transition-duration: 300ms;
}
.label-down, .label-up, .label-refresh {
display: none;
text-align: center;
}
.pull-down .label-down,
.pull-up .label-up,
.refreshing .label-refresh {
display: block;
width: 5.5em;
}
.pull-to-refresh-layer {
display: flex;
align-items: center;
justify-content: center;
}
.infinite-layer {
height: @layer-height;
display: flex;
align-items: center;
justify-content: center;
color: @color-text-gray;
}
.infinite-preloader {
width: 40px;
height: 40px;
animation: preloader-spin 1s steps(12, end) infinite;
&:after {
display: block;
width: 100%;
height: 100%;
content: "";
background-image: url("data:image/svg+xml;charset=utf-8,<svg viewBox='0 0 120 120' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><defs><line id='l' x1='60' x2='60' y1='7' y2='27' stroke='#6c6c6c' stroke-width='11' stroke-linecap='round'/></defs><g><use xlink:href='#l' opacity='.27'/><use xlink:href='#l' opacity='.27' transform='rotate(30 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(60 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(90 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(120 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(150 60,60)'/><use xlink:href='#l' opacity='.37' transform='rotate(180 60,60)'/><use xlink:href='#l' opacity='.46' transform='rotate(210 60,60)'/><use xlink:href='#l' opacity='.56' transform='rotate(240 60,60)'/><use xlink:href='#l' opacity='.66' transform='rotate(270 60,60)'/><use xlink:href='#l' opacity='.75' transform='rotate(300 60,60)'/><use xlink:href='#l' opacity='.85' transform='rotate(330 60,60)'/></g></svg>");
background-repeat: no-repeat;
background-position: center;
background-size: 100%;
}
}
.label-loading {
display: block;
width: 5.5em;
text-align: center;
}
</style>
<script>
export default {
props: {
offset: {
type: Number,
default: 88
},
onRefresh: {
type: Function,
default: undefined,
required: false
},
onInfinite: {
type: Function,
default: undefined,
require: false
}
},
data() {
return {
top: 0,
state: 0, // 0:down, 1: up, 2: refreshing
startY: 0,
touching: false,
infiniteLoading: false
}
},
methods: {
touchStart(e) {
this.startY = e.targetTouches[0].pageY
this.touching = true
},
mouseDown(e) {
this.startY = e.pageY
this.touching = true
},
touchMove(e) {
if (this.$el.scrollTop > 0 || !this.touching) {
return
}
let diff = e.targetTouches[0].pageY - this.startY
if (diff > 0) e.preventDefault()
this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0)
if (this.state === 2) { // in refreshing
return
}
if (this.top >= this.offset) {
this.state = 1
} else {
this.state = 0
}
},
mouseMove(e) {
if (this.$el.scrollTop > 0 || !this.touching) {
return
}
let diff = e.pageY - this.startY
if (diff > 0) e.preventDefault()
this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0)
if (this.state === 2) { // in refreshing
return
}
if (this.top >= this.offset) {
this.state = 1
} else {
this.state = 0
}
},
touchEnd(e) {
this.touching = false
if (this.state === 2) { // in refreshing
this.state = 2
this.top = this.offset
return
}
if (this.top >= this.offset) { // do refresh
this.refresh()
} else { // cancel refresh
this.state = 0
this.top = 0
}
},
mouseUp(e) {
this.touching = false
if (this.state === 2) { // in refreshing
this.state = 2
this.top = this.offset
return
}
if (this.top >= this.offset) { // do refresh
this.refresh()
} else { // cancel refresh
this.state = 0
this.top = 0
}
},
refresh() {
this.state = 2
this.top = this.offset
this.onRefresh(this.refreshDone)
},
refreshDone() {
this.state = 0
this.top = 0
},
infinite() {
this.infiniteLoading = true
this.onInfinite(this.infiniteDone)
},
infiniteDone() {
this.infiniteLoading = false
},
onScroll(e) {
if (this.infiniteLoading) {
return
}
let outerHeight = this.$el.clientHeight
let innerHeight = this.$el.querySelector('.scroll-inner').clientHeight
let scrollTop = this.$el.scrollTop
let ptrHeight = this.onRefresh ? this.$el.querySelector('.pull-to-refresh-layer').clientHeight : 0
let infiniteHeight = this.$el.querySelector('.infinite-layer').clientHeight
let bottom = innerHeight - outerHeight - scrollTop - ptrHeight
if (bottom < infiniteHeight) this.infinite()
}
}
}
</script>
src/Dynamic/LayoutComponents/DScroll/utils/index.js
0 → 100755
View file @
565b1d5f
/**
* 一些帮助函数
*/
/**
* setTimeout 的 promise 封装
* @param {Number} time
* @returns
*/
export
function
timeout
(
time
)
{
return
new
Promise
(
resolve
=>
{
setTimeout
(
resolve
,
time
)
})
}
src/Dynamic/LayoutComponents/DView/README.md
0 → 100755
View file @
565b1d5f
HView 页面部分
```
html
<h-view>
<h-header>
</h-header>
<h-content>
</h-content>
</h-view>
```
src/Dynamic/LayoutComponents/DView/index.vue
0 → 100755
View file @
565b1d5f
<!--
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-16 11:26:14
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-16 11:30:27
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
-->
<
template
>
<div
:class=
"
{'h-ios': isIos}" class="h-view">
<slot/>
</div>
</
template
>
<
script
>
import
{
detectOS
}
from
'../../utils/utils'
;
export
default
{
name
:
'DView'
,
props
:
{
fullScreen
:
{
// 是否为全屏应用,全屏子应用此项需设为true
type
:
Boolean
,
default
:
true
,
},
title
:
{
type
:
String
,
default
:
''
,
},
},
data
()
{
return
{
isIos
:
false
,
}
},
mounted
()
{
if
(
this
.
title
)
{
document
.
title
=
this
.
title
}
},
activated
()
{
if
(
this
.
title
)
{
document
.
title
=
this
.
title
}
},
created
()
{
this
.
fullScreen
&&
detectOS
()
===
'ios'
&&
(
this
.
isIos
=
true
)
document
.
body
.
classList
.
add
(
'platform-'
+
detectOS
())
},
}
</
script
>
<
style
lang=
"less"
>
::selection {
background: #3367d6;
color: #fff;
}
input:hover ,input:focus{
caret-color: #3367d6;
}
.h-view {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
overflow: hidden;
// padding-bottom: 44px;
// background-color: $bgColor;
}
.platform-ios {
.h-view {
// padding-bottom: 64px;
}
}
// iPhoneX适配
@media only screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) {
.platform-ios {
.h-view {
// padding-bottom: 120px;
}
}
}
// iPhoneX Max适配
@media only screen and (device-width: 414px) and (device-height: 896px) {
.platform-ios {
.h-view {
// padding-bottom: 120px;
}
}
}
</
style
>
src/Dynamic/LayoutComponents/index.js
0 → 100644
View file @
565b1d5f
/*
* @Author: zong.wang01@hand-china.com
* @Date: 2024-08-16 11:32:06
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-16 11:34:28
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
*/
import
DView
from
'./DView'
;
import
DHeader
from
'./DHeader'
;
import
DContent
from
'./DContent'
;
import
DScroll
from
'./DScroll/index.vue'
;
export
{
DView
,
DHeader
,
DContent
,
DScroll
}
\ No newline at end of file
src/Dynamic/index.vue
View file @
565b1d5f
...
...
@@ -2,19 +2,19 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-29 10:51:56
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-16
09:56:40
* @LastEditTime: 2024-08-16
11:39:59
* @Version: 1.0.0
* @Description:
* @Copyright: Copyright (c) 2021, Hand-RongJing
-->
<
template
>
<
h
-view>
<
h
-header>
<
h-return
v-if=
"needBack"
slot=
"left"
@
click
.
native=
"$routeGo()"
/>
<
d
-view>
<
d
-header>
<
i
class=
"ion-ios-arrow-back"
v-if=
"needBack"
slot=
"left"
@
click
.
native=
"$routeGo()"
/>
<div
slot=
"center"
>
{{
configDatas
.
description
}}
</div>
</
h
-header>
<
h
-content>
</
d
-header>
<
d
-content>
<van-loading
size=
"24px"
vertical
v-if=
"loading"
>
加载中...
</van-loading>
<config-render-component
v-if=
"configDatas.id && !loading"
...
...
@@ -22,17 +22,18 @@
:staticLayoutTabs=
"staticLayoutTabs"
:componentButtons=
"componentButtons"
/>
</
h
-content>
</
d
-content>
<layout-buttons
v-if=
"configDatas.id"
:layoutButtonsFun=
"layoutButtons"
:headerButtons=
"headerButtons"
/>
</
h
-view>
</
d
-view>
</
template
>
<
script
>
import
{
Loading
}
from
'vant'
;
import
{
DView
,
DHeader
,
DContent
,
DScroll
}
from
'./LayoutComponents'
;
import
LayoutButtons
from
'./LayoutButtons'
;
import
ConfigRenderComponent
from
'./ConfigRenderComponent/index.jsx'
;
import
{
query
,
queryRoute
}
from
'./service'
...
...
@@ -44,7 +45,11 @@ export default {
components
:
{
[
Loading
.
name
]:
Loading
,
LayoutButtons
,
ConfigRenderComponent
ConfigRenderComponent
,
DView
,
DHeader
,
DContent
,
DScroll
},
props
:
{
layoutCode
:
{
// 页面编码
...
...
@@ -104,7 +109,7 @@ export default {
};
},
created
()
{
window
.
localStorage
.
setItem
(
'access_token'
,
'
5383d2f6-a740-4c9c-a4eb-008568f8f99
1'
);
window
.
localStorage
.
setItem
(
'access_token'
,
'
4b20ae48-aeac-4811-be76-85fb07a346b
1'
);
this
.
params
=
{
...
this
.
$route
.
params
,
...
this
.
$route
.
query
...
...
src/Dynamic/utils/utils.js
View file @
565b1d5f
...
...
@@ -2,7 +2,7 @@
* @Author: zong.wang01@hand-china.com
* @Date: 2024-07-30 14:39:47
* @LastEditors: zong.wang01@hand-china.com
* @LastEditTime: 2024-08-1
5 17:02:23
* @LastEditTime: 2024-08-1
6 11:27:44
* @Version: 1.0.0
* @Description: 工具类
* @Copyright: Copyright (c) 2021, Hand-RongJing
...
...
@@ -76,6 +76,24 @@ const dateFormat = (type, time) => { // 时间格式化 2019-09-08
}
};
/**
* 判断平台
* @return {String} 平台
*/
const
detectOS
=
()
=>
{
const
ua
=
navigator
.
userAgent
.
toLowerCase
()
if
(
/MicroMessenger/i
.
test
(
ua
))
{
return
'weixin'
}
else
if
(
/iPhone|iPad|iPod|iOS/i
.
test
(
ua
))
{
return
'ios'
}
else
if
(
/Android/i
.
test
(
ua
))
{
return
'android'
}
else
{
return
'other'
}
};
const
getOrganizationId
=
()
=>
{
return
0
;
// const globalState = getDvaApp()._store.getState();
...
...
@@ -142,6 +160,7 @@ export {
getHeaderExtrasProp
,
getDataSetName
,
dateFormat
,
detectOS
,
getOrganizationId
,
getCurrentUser
};
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