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
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
/**
* better-scroll vue封装
* @Author momoko
* @Date 2018/05
*/
<
template
>
<div
ref=
"scroll"
:class=
"[c(),
{'h-ios': isIos}]">
<div
:class=
"c('__wrapper')"
>
<div
ref=
"scrollContent"
class=
"scrollContent"
>
<slot/>
</div>
<slot
:pullUp=
"pullUp"
:pullUpNow=
"pullUpNow"
name=
"pullup"
>
<div
v-if=
"pullUp"
:class=
"c('__pullup')"
>
<div
v-if=
"!pullUpNow"
>
<span>
{{
pullUpTxt
}}
</span>
</div>
<div
v-else
>
<Loading/>
</div>
</div>
</slot>
</div>
<slot
:pullDown=
"pullDown"
:pullDownStyle=
"pullDownStyle"
:pullDownBefore=
"pullDownBefore"
:pullDownNow=
"pullDownNow"
:bubbleY=
"bubbleY"
name=
"pulldown"
>
<div
v-if=
"pullDown"
ref=
"pulldown"
:style=
"pullDownStyle"
:class=
"c('__pulldown')"
>
<div
v-if=
"pullDownBefore"
:class=
"c('__pulldown__before')"
>
<Bubble
:y=
"bubbleY"
/>
</div>
<div
v-else
:class=
"c('__pulldown__after')"
>
<div
v-if=
"pullDownNow"
>
<Loading/>
</div>
<div
v-else
><span>
{{
pullDownTxt
}}
</span></div>
</div>
</div>
</slot>
</div>
</
template
>
<
script
type=
"text/ecmascript-6"
>
import
BScroll
from
'better-scroll'
import
Loading
from
'./Loading'
import
Bubble
from
'./Bubble'
import
mixin
from
'./mixins'
import
{
timeout
}
from
'./utils'
import
{
detectOS
}
from
'../../utils/utils'
;
export
default
{
name
:
'DScroll'
,
components
:
{
Loading
,
Bubble
,
},
mixins
:
[
mixin
],
props
:
{
probeType
:
{
// 滚动事件监听类型
type
:
Number
,
default
:
1
,
},
click
:
{
// 开启点击事件代理
type
:
Boolean
,
default
:
true
,
},
listenScroll
:
{
// 监听滚动
type
:
Boolean
,
default
:
false
,
},
listenBeforeScrollStart
:
{
// 监听滚动开始前
type
:
Boolean
,
default
:
false
,
},
scrollX
:
{
// 开启X轴滚动
type
:
Boolean
,
default
:
false
,
},
scrollY
:
{
// 开启Y轴滚动
type
:
Boolean
,
default
:
true
,
},
scrollbar
:
{
// 开启滚动条
type
:
null
,
default
:
false
,
},
pullDown
:
{
// 启用下拉刷新
type
:
Boolean
,
default
:
false
,
},
pullDownConfig
:
{
// 下拉刷新配置
type
:
Object
,
default
:
()
=>
({
threshold
:
45
,
// 触发 pullingDown 的距离
stop
:
30
,
// pullingDown 正在刷新 hold 时的距离
txt
:
'刷新成功'
,
}),
},
pullUp
:
{
// 启用上拉加载
type
:
Boolean
,
default
:
false
,
},
pullUpConfig
:
{
// 上拉加载配置
type
:
Object
,
default
:
()
=>
({
threshold
:
100
,
// 提前触发 pullingUp 的距离
txt
:
{
more
:
'上拉加载'
,
noMore
:
'— 我是有底线的 —'
},
}),
},
startY
:
{
// 起始Y位置
type
:
Number
,
default
:
0
,
},
bounce
:
{
// 回弹效果
type
:
Boolean
,
default
:
true
,
},
bounceTime
:
{
// 回弹时间
type
:
Number
,
default
:
500
,
},
preventDefaultException
:
{
// 不阻止默认行为
type
:
Object
,
default
:
()
=>
({
tagName
:
/^
(
INPUT|TEXTAREA|BUTTON|SELECT
)
$/
,
}),
},
autoUpdate
:
{
// 自动刷新高度:适用于简单场景,复杂场景请使用updateData/refreshData
type
:
Boolean
,
default
:
false
,
},
updateData
:
{
// 引起更新上拉/下拉加载状态的数据(下拉刷新/上拉加载相关的数据)
type
:
Array
,
default
:
null
,
},
refreshData
:
{
// 引起刷新高度的数据(不包含 updateData 内的数据)
type
:
Array
,
default
:
null
,
},
hasFoot
:
{
// 底部按钮的配置
type
:
Object
,
default
:
()
=>
({
footFlag
:
false
,
// 提前触发 pullingUp 的距离
height
:
44
,
}),
},
height
:
{
type
:
String
,
default
:
''
}
},
data
()
{
return
{
pullDownBefore
:
true
,
// 下拉之前
pullDownNow
:
false
,
// 正在下拉
pullDownStyle
:
''
,
// 下拉样式
pullUpNow
:
false
,
// 正在上拉
pullUpFinally
:
false
,
// true表示到了上拉加载到了最底部
isRebounding
:
false
,
// 正在回弹
bubbleY
:
0
,
// 气泡y坐标,
isIos
:
false
,
fullScreen
:
true
,
fontSize
:
Number
(
window
.
document
.
documentElement
.
style
.
fontSize
.
replace
(
'px'
,
''
)),
winHeight
:
window
.
innerHeight
,
winWidth
:
window
.
innerWidth
,
}
},
computed
:
{
// 下拉的文本
pullDownTxt
()
{
return
this
.
pullDownConfig
&&
this
.
pullDownConfig
.
txt
},
// 上拉的文本
pullUpTxt
()
{
const
moreTxt
=
this
.
pullUpConfig
&&
this
.
pullUpConfig
.
txt
&&
this
.
pullUpConfig
.
txt
.
more
const
noMoreTxt
=
this
.
pullUpConfig
&&
this
.
pullUpConfig
.
txt
&&
this
.
pullUpConfig
.
txt
.
noMore
return
this
.
pullUpFinally
?
noMoreTxt
:
moreTxt
},
},
watch
:
{
updateData
()
{
this
.
update
()
},
async
refreshData
()
{
if
(
this
.
updateState
)
return
await
this
.
$nextTick
()
this
.
refresh
()
},
},
created
()
{
this
.
fullScreen
&&
detectOS
()
===
'ios'
&&
(
this
.
isIos
=
true
)
},
async
mounted
()
{
this
.
pullDownInitTop
=
parseInt
(
this
.
$refs
.
pulldown
&&
getComputedStyle
(
this
.
$refs
.
pulldown
).
top
)
||
-
10
await
this
.
$nextTick
()
this
.
initScroll
()
// 自动刷新高度:深监视 $data,发生改变时更新高度
this
.
autoUpdate
&&
this
.
$parent
&&
this
.
$parent
.
$data
&&
this
.
$watch
(()
=>
this
.
$parent
.
$data
,
(
val
)
=>
{
this
.
update
()
},
{
deep
:
true
,
})
},
methods
:
{
getHeaderHeight
()
{
let
vm
=
this
let
$el
=
vm
.
$el
.
previousElementSibling
let
headerHeight
=
0
do
{
if
(
$el
)
{
headerHeight
+=
vm
.
$el
.
offsetHeight
/* let elHeight = window.getComputedStyle($el).height
let part = /^\d+(\.\d+)?px$/
if (elHeight && part.test(elHeight)) {
headerHeight += Number(elHeight.replace('px', ''))
}
let marginTopHeight = window.getComputedStyle($el).marginTop
let marginBottomHeight = window.getComputedStyle($el).marginBottom
if (marginTopHeight && part.test(marginTopHeight)) {
headerHeight += Number(marginTopHeight.replace('px', ''))
}
if (marginBottomHeight && part.test(marginBottomHeight)) {
headerHeight += Number(marginBottomHeight.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'
)
{
nextHeight
+=
vm
.
$el
.
offsetHeight
/* let elHeight = window.getComputedStyle(nextElement).height
let part = /^\d+(\.\d+)?px$/
if (elHeight && part.test(elHeight)) {
nextHeight += Number(elHeight.replace('px', ''))
}
let marginTopHeight = window.getComputedStyle(nextElement).marginTop
let marginBottomHeight = window.getComputedStyle(nextElement).marginBottom
if (marginTopHeight && part.test(marginTopHeight)) {
nextHeight += Number(marginTopHeight.replace('px', ''))
}
if (marginBottomHeight && part.test(marginBottomHeight)) {
nextHeight += Number(marginBottomHeight.replace('px', ''))
} */
}
nextElement
=
nextElement
.
nextElementSibling
}
}
while
(
nextElement
)
return
nextHeight
},
// 初始化scroll
initScroll
()
{
let
vm
=
this
if
(
!
this
.
$refs
.
scroll
)
return
// if (this.height) {
// this.$refs.scroll.style.height = this.height;
// } else {
// const headerHeight = vm.getHeaderHeight()
// const nextHeight = vm.getNextElementHeight()
// this.$refs.scroll.style.height = `${this.$refs.scroll.getBoundingClientRect().height - headerHeight - nextHeight}px`
// }
// // 设置scrollContent的最小高,实现高度不足时也有回弹效果
// if (this.$refs.scrollContent) {
// // const nextHeight = vm.getNextElementHeight()
// this.$refs.scrollContent.style.minHeight = window.getComputedStyle(this.$refs.scroll).height; // `${this.$refs.scroll.getBoundingClientRect().height}px`
// // this.$refs.scrollContent.style.paddingTop = `${headerHeight}px`
// if (vm.hasFoot.footFlag) {
// let height = vm.hasFoot.height || 88
// // this.$refs.scrollContent.style.minHeight = `${this.$refs.scroll.getBoundingClientRect().height - height}px`
// this.$refs.scrollContent.style.paddingBottom = height + 'px'
// }
// }
const
options
=
{
probeType
:
this
.
probeType
,
click
:
this
.
click
,
scrollX
:
this
.
scrollX
,
scrollY
:
this
.
scrollY
,
scrollbar
:
this
.
scrollbar
,
pullDownRefresh
:
this
.
pullDown
&&
this
.
pullDownConfig
,
pullUpLoad
:
this
.
pullUp
&&
this
.
pullUpConfig
,
startY
:
this
.
startY
,
bounce
:
this
.
bounce
,
bounceTime
:
this
.
bounceTime
,
preventDefaultException
:
this
.
preventDefaultException
,
}
this
.
scroll
=
new
BScroll
(
this
.
$refs
.
scroll
,
options
)
this
.
listenScroll
&&
this
.
scroll
.
on
(
'scroll'
,
pos
=>
{
this
.
$emit
(
'scroll'
,
pos
)
})
this
.
listenBeforeScroll
&&
this
.
scroll
.
on
(
'beforeScrollStart'
,
()
=>
{
this
.
$emit
(
'beforeScrollStart'
)
})
this
.
pullDown
&&
this
.
_initPullDown
()
this
.
pullUp
&&
this
.
_initPullUp
()
},
// 初始化下拉刷新
_initPullDown
()
{
let
vm
=
this
this
.
scroll
.
on
(
'pullingDown'
,
()
=>
{
// if (this.pullUpFinally) {
// this.pullDownBefore = false
// vm.scroll.closePullDown()
// this.pullDownNow = false
// } else {
this
.
pullDownBefore
=
false
this
.
pullDownNow
=
true
setTimeout
(
function
()
{
vm
.
$emit
(
'pullingDown'
)
vm
.
scroll
.
closePullDown
()
// 防止在 bounce 前二次触发
},
150
)
// }
})
this
.
scroll
.
on
(
'scroll'
,
pos
=>
{
if
(
!
this
.
pullDown
||
pos
.
y
<
0
)
return
const
posY
=
Math
.
floor
(
pos
.
y
)
// 滚动的y轴位置:Number
if
(
this
.
pullDownBefore
)
{
this
.
bubbleY
=
Math
.
max
(
0
,
posY
+
this
.
pullDownInitTop
)
this
.
pullDownStyle
=
`transform: translateY(
${
Math
.
min
(
posY
,
-
this
.
pullDownInitTop
)}
px)`
}
else
{
this
.
bubbleY
=
0
}
if
(
this
.
isRebounding
)
{
this
.
pullDownStyle
=
`transform: translateY(
${
Math
.
min
(
posY
,
this
.
pullDownConfig
.
stop
)}
px)`
}
})
},
// 初始化上拉加载
_initPullUp
()
{
this
.
scroll
.
on
(
'pullingUp'
,
()
=>
{
let
vm
=
this
if
(
this
.
pullUpFinally
)
{
this
.
scroll
.
finishPullUp
()
}
else
{
vm
.
pullUpNow
=
true
setTimeout
(
function
()
{
vm
.
$emit
(
'pullingUp'
)
},
100
)
}
})
},
// 关闭滚动
disable
()
{
this
.
scroll
&&
this
.
scroll
.
disable
()
},
// 开启滚动
enable
()
{
this
.
scroll
&&
this
.
scroll
.
enable
()
},
// 销毁滚动示例
destroy
()
{
this
.
scroll
&&
this
.
scroll
.
destroy
()
},
// 刷新滚动高度
refresh
()
{
this
.
scroll
&&
this
.
scroll
.
refresh
()
},
// 更新加载状态,下拉/下拉成功后使用
async
update
(
final
)
{
if
(
this
.
updateState
)
return
this
.
updateState
=
true
// 正在update状态
if
(
this
.
pullDown
&&
this
.
pullDownNow
)
{
// 下拉刷新触发成功后
this
.
pullDownNow
=
false
await
timeout
(
this
.
bounceTime
/
2
)
// 刷新成功hold
this
.
isRebounding
=
true
this
.
scroll
.
finishPullDown
()
// 开始回弹
await
timeout
(
this
.
bounceTime
)
this
.
pullDownBefore
=
true
this
.
isRebounding
=
false
this
.
scroll
.
openPullDown
(
this
.
pullDownConfig
)
this
.
pullUpFinally
=
false
}
else
if
(
this
.
pullUp
&&
this
.
pullUpNow
)
{
// 上拉加载触发成功后
this
.
pullUpNow
=
false
this
.
scroll
.
finishPullUp
()
}
typeof
final
!==
'undefined'
&&
(
this
.
pullUpFinally
=
!!
final
)
await
this
.
$nextTick
()
this
.
refresh
()
this
.
updateState
=
false
},
/**
* 每次滚动多少距离
* @param {Number} x x轴位置
* @param {Number} y y轴位置
* @param {Number} time 滚动时间
* @return {Void}
*/
scrollBy
(
x
=
0
,
y
=
0
,
time
=
this
.
bounceTime
)
{
this
.
scroll
&&
this
.
scroll
.
scrollTo
((
this
.
scroll
.
absStartX
-
x
),
(
this
.
scroll
.
absStartY
-
y
),
time
)
},
/**
* 滚动到指定位置
* @param {Number} x x轴位置
* @param {Number} y y轴位置
* @param {Number} time 滚动时间
* @return {Void}
*/
scrollTo
(
x
=
0
,
y
=
0
,
time
=
this
.
bounceTime
)
{
this
.
scroll
&&
this
.
scroll
.
scrollTo
(
x
,
y
,
time
)
},
// 滚动到元素
scrollToElement
()
{
this
.
scroll
&&
this
.
scroll
.
scrollToElement
.
apply
(
this
.
scroll
,
arguments
)
},
// 滚动到顶部
scrollToTop
()
{
this
.
scroll
&&
this
.
scrollTo
(
0
,
0
)
},
// 滚动到底部
scrollToBottom
()
{
this
.
scroll
&&
this
.
scrollTo
(
0
,
this
.
scroll
.
maxScrollY
)
},
},
}
</
script
>
<
style
lang=
"stylus"
>
//$ = vue-better-scroll
.vue-better-scroll {
width 100%
overflow auto
// overflow hidden !important
box-sizing border-box
position relative
//top 0
height 100%
&__wrapper {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-webkit-text-size-adjust: none;
-moz-text-size-adjust: none;
text-size-adjust: none;
-webkit-transform-origin: left top;
transform-origin: left top;
padding-bottom: 20px
}
&__pullup {
width 100%
height 25px
display flex
justify-content center
align-items center
font-size 14px
color rgb(153, 153, 153)
}
&__pulldown {
position absolute
left 0
top 0; /*no*/
z-index -5
width 100%
display flex
justify-content center
align-items center
transition all
font-size 14px
color rgb(153, 153, 153)
&__before {
display flex
}
&__after {
width 100%
height 40px; /*no*/
display flex
justify-content center
align-items center
color #666
}
}
}
.has-footer {
.vue-better-scroll__wrapper {
padding-bottom: 50px;
}
}
.platform-ios{
.vue-better-scroll{
&__pulldown {
//padding-top:4px
}
}
.has-footer {
.vue-better-scroll__wrapper {
padding-bottom: 50px;
}
}
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios {
.vue-better-scroll{
&__pulldown {
//padding-top:24px
}
}
.has-footer {
.vue-better-scroll__wrapper {
padding-bottom: 90px;
}
}
}
}
// iPhoneX Max适配
@media (device-width: 414px) and (device-height: 896px) {
.platform-ios {
.vue-better-scroll{
&__pulldown {
//padding-top:24px
}
}
.has-footer {
.vue-better-scroll__wrapper {
padding-bottom: 90px;
}
}
}
}
</
style
>
src/Dynamic/LayoutComponents/DScroll/index.vue.bak
0 → 100755
View file @
565b1d5f
/**
* better-scroll vue封装
* @Author momoko
* @Date 2018/05
*/
<template>
<div ref="scroll" :class="[c(),{'h-ios': isIos}]" class="content scroll-content">
<div :class="c('__wrapper')">
<div ref="scrollContent" class="scrollContent">
<slot/>
</div>
<slot
:pullUp="pullUp"
:pullUpNow="pullUpNow"
name="pullup"
>
<div v-if="pullUp" :class="c('__pullup')">
<div v-if="!pullUpNow">
<span>{{ pullUpTxt }}</span>
</div>
<div v-else>
<Loading/>
</div>
</div>
</slot>
</div>
<slot
:pullDown="pullDown"
:pullDownStyle="pullDownStyle"
:pullDownBefore="pullDownBefore"
:pullDownNow="pullDownNow"
:bubbleY="bubbleY"
name="pulldown"
>
<div
v-if="pullDown" ref="pulldown" :style="pullDownStyle" :class="c('__pulldown')">
<div v-if="pullDownBefore" :class="c('__pulldown__before')">
<Bubble :y="bubbleY"/>
</div>
<div v-else :class="c('__pulldown__after')">
<div v-if="pullDownNow">
<Loading/>
</div>
<div v-else><span>{{ pullDownTxt }}</span></div>
</div>
</div>
</slot>
</div>
</template>
<script type="text/ecmascript-6">
import BScroll from 'better-scroll'
import Loading from './Loading'
import Bubble from './Bubble'
import mixin from './mixins'
import {timeout} from './utils'
import { detectOS } from '../../common/utils/index'
export default {
name: 'Scroll',
components: {
Loading,
Bubble,
},
mixins: [mixin],
props: {
probeType: {
// 滚动事件监听类型
type: Number,
default: 1,
},
click: {
// 开启点击事件代理
type: Boolean,
default: true,
},
listenScroll: {
// 监听滚动
type: Boolean,
default: false,
},
listenBeforeScrollStart: {
// 监听滚动开始前
type: Boolean,
default: false,
},
scrollX: {
// 开启X轴滚动
type: Boolean,
default: false,
},
scrollY: {
// 开启Y轴滚动
type: Boolean,
default: true,
},
scrollbar: {
// 开启滚动条
type: null,
default: false,
},
pullDown: {
// 启用下拉刷新
type: Boolean,
default: false,
},
pullDownConfig: {
// 下拉刷新配置
type: Object,
default: () => ({
threshold: 45, // 触发 pullingDown 的距离
stop: 30, // pullingDown 正在刷新 hold 时的距离
txt: '刷新成功',
}),
},
pullUp: {
// 启用上拉加载
type: Boolean,
default: false,
},
pullUpConfig: {
// 上拉加载配置
type: Object,
default: () => ({
threshold: 100, // 提前触发 pullingUp 的距离
txt: {more: '上拉加载', noMore: '— 我是有底线的 —'},
}),
},
startY: {
// 起始Y位置
type: Number,
default: 0,
},
bounce: {
// 回弹效果
type: Boolean,
default: true,
},
bounceTime: {
// 回弹时间
type: Number,
default: 500,
},
preventDefaultException: {
// 不阻止默认行为
type: Object,
default: () => ({
tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/,
}),
},
autoUpdate: {
// 自动刷新高度:适用于简单场景,复杂场景请使用updateData/refreshData
type: Boolean,
default: false,
},
updateData: {
// 引起更新上拉/下拉加载状态的数据(下拉刷新/上拉加载相关的数据)
type: Array,
default: null,
},
refreshData: {
// 引起刷新高度的数据(不包含 updateData 内的数据)
type: Array,
default: null,
},
hasFoot: {
// 底部按钮的配置
type: Object,
default: () => ({
footFlag: false, // 提前触发 pullingUp 的距离
height: 44,
}),
},
},
data () {
return {
pullDownBefore: true, // 下拉之前
pullDownNow: false, // 正在下拉
pullDownStyle: '', // 下拉样式
pullUpNow: false, // 正在上拉
pullUpFinally: false, // true表示到了上拉加载到了最底部
isRebounding: false, // 正在回弹
bubbleY: 0, // 气泡y坐标,
isIos: false,
fullScreen: true,
fontSize: Number(window.document.documentElement.style.fontSize.replace('px', '')),
winHeight: window.innerHeight,
winWidth: window.innerWidth,
}
},
computed: {
// 下拉的文本
pullDownTxt () {
return this.pullDownConfig && this.pullDownConfig.txt
},
// 上拉的文本
pullUpTxt () {
const moreTxt = this.pullUpConfig && this.pullUpConfig.txt && this.pullUpConfig.txt.more
const noMoreTxt = this.pullUpConfig && this.pullUpConfig.txt && this.pullUpConfig.txt.noMore
return this.pullUpFinally ? noMoreTxt : moreTxt
},
},
watch: {
updateData () {
this.update()
},
async refreshData () {
if (this.updateState) return
await this.$nextTick()
this.refresh()
},
},
created () {
this.fullScreen && detectOS() === 'ios' && (this.isIos = true)
},
async mounted () {
this.pullDownInitTop = parseInt(this.$refs.pulldown && getComputedStyle(this.$refs.pulldown).top) || -60
await this.$nextTick()
this.initScroll()
// 自动刷新高度:深监视 $data,发生改变时更新高度
this.autoUpdate && this.$parent && this.$parent.$data && this.$watch(() => this.$parent.$data, (val) => {
this.update()
}, {
deep: true,
})
},
methods: {
getHeaderHeight () {
let vm = this
let $el = vm.$el.previousElementSibling
let headerHeight = 0
do {
if ($el) {
let elHeight = window.getComputedStyle($el).height
let part = /^\d+(\.\d+)?px$/
if (elHeight && part.test(elHeight)) {
headerHeight += Number(elHeight.replace('px', ''))
}
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).height
let part = /^\d+(\.\d+)?px$/
if (elHeight && part.test(elHeight)) {
nextHeight += Number(elHeight.replace('px', ''))
}
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
},
// 初始化scroll
initScroll () {
let vm = this
if (!this.$refs.scroll) return
// 设置scrollContent的最小高,实现高度不足时也有回弹效果
if (this.$refs.scrollContent) {
const headerHeight = vm.getHeaderHeight()
// const nextHeight = vm.getNextElementHeight()
this.$refs.scrollContent.style.minHeight = `${this.$refs.scroll.getBoundingClientRect().height + 1}px`
this.$refs.scrollContent.style.paddingTop = `${headerHeight}px`
if (vm.hasFoot.footFlag) {
let height = vm.hasFoot.height || 88
// this.$refs.scrollContent.style.minHeight = `${this.$refs.scroll.getBoundingClientRect().height - height}px`
this.$refs.scrollContent.style.paddingBottom = height + 'px'
}
}
const options = {
probeType: this.probeType,
click: this.click,
scrollX: this.scrollX,
scrollY: this.scrollY,
scrollbar: this.scrollbar,
pullDownRefresh: this.pullDown && this.pullDownConfig,
pullUpLoad: this.pullUp && this.pullUpConfig,
startY: this.startY,
bounce: this.bounce,
bounceTime: this.bounceTime,
preventDefaultException: this.preventDefaultException,
}
this.scroll = new BScroll(this.$refs.scroll, options)
this.listenScroll &&
this.scroll.on('scroll', pos => {
this.$emit('scroll', pos)
})
this.listenBeforeScroll &&
this.scroll.on('beforeScrollStart', () => {
this.$emit('beforeScrollStart')
})
this.pullDown && this._initPullDown()
this.pullUp && this._initPullUp()
},
// 初始化下拉刷新
_initPullDown () {
let vm = this
this.scroll.on('pullingDown', () => {
// if (this.pullUpFinally) {
// this.pullDownBefore = false
// vm.scroll.closePullDown()
// this.pullDownNow = false
// } else {
this.pullDownBefore = false
this.pullDownNow = true
setTimeout(function () {
vm.$emit('pullingDown')
vm.scroll.closePullDown() // 防止在 bounce 前二次触发
}, 150)
// }
})
this.scroll.on('scroll', pos => {
if (!this.pullDown || pos.y < 0) return
const posY = Math.floor(pos.y) // 滚动的y轴位置:Number
if (this.pullDownBefore) {
this.bubbleY = Math.max(0, posY + this.pullDownInitTop)
this.pullDownStyle = `transform: translateY(${Math.min(posY, -this.pullDownInitTop)}px)`
} else {
this.bubbleY = 0
}
if (this.isRebounding) {
this.pullDownStyle = `transform: translateY(${Math.min(posY, this.pullDownConfig.stop)}px)`
}
})
},
// 初始化上拉加载
_initPullUp () {
this.scroll.on('pullingUp', () => {
let vm = this
if (this.pullUpFinally) {
this.scroll.finishPullUp()
} else {
vm.pullUpNow = true
setTimeout(function () {
vm.$emit('pullingUp')
}, 100)
}
})
},
// 关闭滚动
disable () {
this.scroll && this.scroll.disable()
},
// 开启滚动
enable () {
this.scroll && this.scroll.enable()
},
// 销毁滚动示例
destroy () {
this.scroll && this.scroll.destroy()
},
// 刷新滚动高度
refresh () {
this.scroll && this.scroll.refresh()
},
// 更新加载状态,下拉/下拉成功后使用
async update (final) {
if (this.updateState) return
this.updateState = true // 正在update状态
if (this.pullDown && this.pullDownNow) {
// 下拉刷新触发成功后
this.pullDownNow = false
await timeout(this.bounceTime / 2) // 刷新成功hold
this.isRebounding = true
this.scroll.finishPullDown() // 开始回弹
await timeout(this.bounceTime)
this.pullDownBefore = true
this.isRebounding = false
this.scroll.openPullDown(this.pullDownConfig)
this.pullUpFinally = false
} else if (this.pullUp && this.pullUpNow) {
// 上拉加载触发成功后
this.pullUpNow = false
this.scroll.finishPullUp()
}
typeof final !== 'undefined' && (this.pullUpFinally = !!final)
await this.$nextTick()
this.refresh()
this.updateState = false
},
/**
* 每次滚动多少距离
* @param {Number} x x轴位置
* @param {Number} y y轴位置
* @param {Number} time 滚动时间
* @return {Void}
*/
scrollBy (x = 0, y = 0, time = this.bounceTime) {
this.scroll && this.scroll.scrollTo((this.scroll.absStartX - x), (this.scroll.absStartY - y), time)
},
/**
* 滚动到指定位置
* @param {Number} x x轴位置
* @param {Number} y y轴位置
* @param {Number} time 滚动时间
* @return {Void}
*/
scrollTo (x = 0, y = 0, time = this.bounceTime) {
this.scroll && this.scroll.scrollTo(x, y, time)
},
// 滚动到元素
scrollToElement () {
this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
},
// 滚动到顶部
scrollToTop () {
this.scroll && this.scrollTo(0, 0)
},
// 滚动到底部
scrollToBottom () {
this.scroll && this.scrollTo(0, this.scroll.maxScrollY)
},
},
}
</script>
<style lang="stylus">
//$ = vue-better-scroll
.vue-better-scroll {
width 100%
overflow hidden !important
box-sizing border-box
position absolute
top 0
height 100%
&__wrapper {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-webkit-text-size-adjust: none;
-moz-text-size-adjust: none;
text-size-adjust: none;
-webkit-transform-origin: left top;
transform-origin: left top;
padding-bottom: 20px
}
&__pullup {
width 100%
height 25px
display flex
justify-content center
align-items center
font-size 14px
color rgb(153, 153, 153)
}
&__pulldown {
position absolute
left 0
top 0; /*no*/
width 100%
display flex
justify-content center
align-items center
transition all
font-size 14px
color rgb(153, 153, 153)
&__before {
display flex
}
&__after {
width 100%
height 40px; /*no*/
display flex
justify-content center
align-items center
color #666
}
}
}
.has-footer {
.vue-better-scroll__wrapper {
padding-bottom: 50px;
}
}
.platform-ios{
.vue-better-scroll{
&__pulldown {
padding-top:4px
}
}
.has-footer {
.vue-better-scroll__wrapper {
padding-bottom: 50px;
}
}
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios {
.vue-better-scroll{
&__pulldown {
padding-top:24px
}
}
.has-footer {
.vue-better-scroll__wrapper {
padding-bottom: 90px;
}
}
}
}
// iPhoneX Max适配
@media (device-width: 414px) and (device-height: 896px) {
.platform-ios {
.vue-better-scroll{
&__pulldown {
padding-top:24px
}
}
.has-footer {
.vue-better-scroll__wrapper {
padding-bottom: 90px;
}
}
}
}
</style>
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