Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
uni-app
提交
2534a279
U
uni-app
项目概览
DCloud
/
uni-app
2 个月 前同步成功
通知
717
Star
38705
Fork
3642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
7
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
7
Issue
7
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2534a279
编写于
4月 09, 2020
作者:
fxy060608
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor(v3): diff
上级
d1349bb0
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
165 addition
and
184 deletion
+165
-184
packages/uni-app-plus/dist/index.v3.js
packages/uni-app-plus/dist/index.v3.js
+123
-121
src/platforms/app-plus/service/framework/plugins/diff.js
src/platforms/app-plus/service/framework/plugins/diff.js
+3
-63
src/shared/util.js
src/shared/util.js
+39
-0
未找到文件。
packages/uni-app-plus/dist/index.v3.js
浏览文件 @
2534a279
...
...
@@ -308,6 +308,45 @@ var serviceContext = (function () {
const
timerFn
=
()
=>
fn
.
apply
(
this
,
arguments
);
timeout
=
setTimeout
(
timerFn
,
delay
);
}
}
/**
* Check if two values are loosely equal - that is,
* if they are plain objects, do they have the same shape?
*/
function
looseEqual
(
a
,
b
)
{
if
(
a
===
b
)
return
true
const
isObjectA
=
isObject
(
a
);
const
isObjectB
=
isObject
(
b
);
if
(
isObjectA
&&
isObjectB
)
{
try
{
const
isArrayA
=
Array
.
isArray
(
a
);
const
isArrayB
=
Array
.
isArray
(
b
);
if
(
isArrayA
&&
isArrayB
)
{
return
a
.
length
===
b
.
length
&&
a
.
every
((
e
,
i
)
=>
{
return
looseEqual
(
e
,
b
[
i
])
})
}
else
if
(
a
instanceof
Date
&&
b
instanceof
Date
)
{
return
a
.
getTime
()
===
b
.
getTime
()
}
else
if
(
!
isArrayA
&&
!
isArrayB
)
{
const
keysA
=
Object
.
keys
(
a
);
const
keysB
=
Object
.
keys
(
b
);
return
keysA
.
length
===
keysB
.
length
&&
keysA
.
every
(
key
=>
{
return
looseEqual
(
a
[
key
],
b
[
key
])
})
}
else
{
/* istanbul ignore next */
return
false
}
}
catch
(
e
)
{
/* istanbul ignore next */
return
false
}
}
else
if
(
!
isObjectA
&&
!
isObjectB
)
{
return
String
(
a
)
===
String
(
b
)
}
else
{
return
false
}
}
const
encodeReserveRE
=
/
[
!'()*
]
/g
;
...
...
@@ -649,7 +688,7 @@ var serviceContext = (function () {
const
ASYNC_API
=
[
'
createBLEConnection
'
];
const
CALLBACK_API_RE
=
/^on/
;
const
CALLBACK_API_RE
=
/^on
|^off
/
;
function
isContextApi
(
name
)
{
return
CONTEXT_API_RE
.
test
(
name
)
...
...
@@ -1373,7 +1412,7 @@ var serviceContext = (function () {
}
},
data
:
{
type
:
[
Object
,
String
,
ArrayBuffer
],
type
:
[
Object
,
String
,
Array
,
Array
Buffer
],
validator
(
value
,
params
)
{
params
.
data
=
value
||
''
;
}
...
...
@@ -1414,6 +1453,9 @@ var serviceContext = (function () {
value
=
(
value
||
''
).
toLowerCase
();
params
.
responseType
=
Object
.
values
(
responseType
).
indexOf
(
value
)
<
0
?
responseType
.
TEXT
:
value
;
}
},
withCredentials
:
{
type
:
Boolean
}
};
...
...
@@ -2175,7 +2217,9 @@ var serviceContext = (function () {
valid
=
t
===
expectedType
.
toLowerCase
();
if
(
!
valid
&&
t
===
'
object
'
)
{
valid
=
value
instanceof
type
;
}
}
}
else
if
(
value
.
byteLength
>=
0
)
{
valid
=
true
;
}
else
if
(
expectedType
===
'
Object
'
)
{
valid
=
isPlainObject
(
value
);
}
else
if
(
expectedType
===
'
Array
'
)
{
...
...
@@ -2970,7 +3014,7 @@ var serviceContext = (function () {
}
function
getScreenInfo
()
{
const
{
resolutionWidth
,
resolutionHeight
}
=
plus
.
screen
.
getCur
e
entSize
();
const
{
resolutionWidth
,
resolutionHeight
}
=
plus
.
screen
.
getCur
r
entSize
();
return
{
screenWidth
:
Math
.
round
(
resolutionWidth
),
screenHeight
:
Math
.
round
(
resolutionHeight
)
...
...
@@ -3019,7 +3063,7 @@ var serviceContext = (function () {
function
createAudioInstance
()
{
const
audioId
=
`
${
Date
.
now
()}${
Math
.
random
()}
`
;
const
audio
=
audios
[
audioId
]
=
plus
.
audio
.
createPlayer
(
''
);
const
audio
=
audios
[
audioId
]
=
plus
.
audio
.
createPlayer
(
''
);
audio
.
src
=
''
;
audio
.
volume
=
1
;
audio
.
startTime
=
0
;
...
...
@@ -3093,7 +3137,7 @@ var serviceContext = (function () {
errMsg
:
'
getAudioState:ok
'
,
duration
:
1
e3
*
(
audio
.
getDuration
()
||
0
),
currentTime
:
audio
.
isStopped
?
0
:
1
e3
*
audio
.
getPosition
(),
paused
:
audio
.
isPaused
,
paused
:
audio
.
isPaused
()
,
src
,
volume
,
startTime
:
1
e3
*
startTime
,
...
...
@@ -3109,7 +3153,7 @@ var serviceContext = (function () {
const
audio
=
audios
[
audioId
];
const
operationTypes
=
[
'
play
'
,
'
pause
'
,
'
stop
'
];
if
(
operationTypes
.
indexOf
(
operationType
)
>=
0
)
{
audio
[
operationType
===
operationTypes
[
0
]
&&
audio
.
isPaused
?
'
resume
'
:
operationType
]();
audio
[
operationType
===
operationTypes
[
0
]
&&
audio
.
isPaused
()
?
'
resume
'
:
operationType
]();
}
else
if
(
operationType
===
'
seek
'
)
{
audio
.
seekTo
(
currentTime
/
1
e3
);
}
...
...
@@ -3118,9 +3162,9 @@ var serviceContext = (function () {
}
}
let
audio
;
let
timeUpdateTimer
=
null
;
let
audio
;
let
timeUpdateTimer
=
null
;
const
TIME_UPDATE
=
250
;
const
publishBackgroundAudioStateChange
=
(
state
,
res
=
{})
=>
publish
(
'
onBackgroundAudioStateChange
'
,
Object
.
assign
({
...
...
@@ -3143,15 +3187,15 @@ var serviceContext = (function () {
audio
.
addEventListener
(
event
,
()
=>
{
// 添加 isStopped 属性是为了解决 安卓设备停止播放后获取播放进度不正确的问题
if
(
event
===
'
play
'
)
{
audio
.
isStopped
=
false
;
audio
.
isStopped
=
false
;
startTimeUpdateTimer
();
}
else
if
(
event
===
'
stop
'
)
{
audio
.
isStopped
=
true
;
}
if
(
event
===
'
pause
'
||
event
===
'
ended
'
||
event
===
'
stop
'
)
{
stopTimeUpdateTimer
();
}
}
if
(
event
===
'
pause
'
||
event
===
'
ended
'
||
event
===
'
stop
'
)
{
stopTimeUpdateTimer
();
}
const
eventName
=
`onMusic
${
event
[
0
].
toUpperCase
()
+
event
.
substr
(
1
)}
`
;
publish
(
eventName
,
{
...
...
@@ -3163,13 +3207,13 @@ var serviceContext = (function () {
});
});
});
audio
.
addEventListener
(
'
waiting
'
,
()
=>
{
audio
.
addEventListener
(
'
waiting
'
,
()
=>
{
stopTimeUpdateTimer
();
publishBackgroundAudioStateChange
(
'
waiting
'
,
{
dataUrl
:
audio
.
src
});
});
audio
.
addEventListener
(
'
error
'
,
err
=>
{
audio
.
addEventListener
(
'
error
'
,
err
=>
{
stopTimeUpdateTimer
();
publish
(
'
onMusicError
'
,
{
dataUrl
:
audio
.
src
,
...
...
@@ -3183,20 +3227,20 @@ var serviceContext = (function () {
});
audio
.
addEventListener
(
'
prev
'
,
()
=>
publish
(
'
onBackgroundAudioPrev
'
));
audio
.
addEventListener
(
'
next
'
,
()
=>
publish
(
'
onBackgroundAudioNext
'
));
}
function
startTimeUpdateTimer
()
{
stopTimeUpdateTimer
();
timeUpdateTimer
=
setInterval
(()
=>
{
publishBackgroundAudioStateChange
(
'
timeUpdate
'
,
{});
},
TIME_UPDATE
);
}
}
function
stopTimeUpdateTimer
()
{
if
(
timeUpdateTimer
!==
null
)
{
clearInterval
(
timeUpdateTimer
);
}
}
function
startTimeUpdateTimer
()
{
stopTimeUpdateTimer
();
timeUpdateTimer
=
setInterval
(()
=>
{
publishBackgroundAudioStateChange
(
'
timeUpdate
'
,
{});
},
TIME_UPDATE
);
}
function
stopTimeUpdateTimer
()
{
if
(
timeUpdateTimer
!==
null
)
{
clearInterval
(
timeUpdateTimer
);
}
}
function
setMusicState
(
args
)
{
initMusic
();
...
...
@@ -3225,7 +3269,7 @@ var serviceContext = (function () {
dataUrl
:
audio
.
src
,
duration
:
audio
.
getDuration
()
||
0
,
currentPosition
:
audio
.
getPosition
(),
status
:
audio
.
isPaused
?
0
:
1
,
status
:
audio
.
isPaused
()
?
0
:
1
,
downloadPercent
:
Math
.
round
(
100
*
audio
.
getBuffered
()
/
audio
.
getDuration
()),
errMsg
:
`getMusicPlayerState:ok`
}
...
...
@@ -3301,7 +3345,7 @@ var serviceContext = (function () {
let
newData
=
{
duration
:
audio
.
getDuration
()
||
0
,
currentTime
:
audio
.
isStopped
?
0
:
audio
.
getPosition
(),
paused
:
audio
.
isPaused
,
paused
:
audio
.
isPaused
()
,
src
:
audio
.
src
,
buffered
:
audio
.
getBuffered
(),
title
:
audio
.
title
,
...
...
@@ -5651,14 +5695,21 @@ var serviceContext = (function () {
openLocation
:
openLocation$1
});
function
openLocation$2
(
data
)
{
function
openLocation$2
(
data
,
callbackId
)
{
showPage
({
url
:
'
__uniappopenlocation
'
,
data
,
style
:
{
titleNView
:
{
type
:
'
transparent
'
}
},
popGesture
:
'
close
'
,
backButtonAutoControl
:
'
close
'
},
onClose
()
{
invoke$1
(
callbackId
,
{
errMsg
:
'
openLocation:fail cancel
'
});
}
});
return
{
...
...
@@ -9253,17 +9304,14 @@ var serviceContext = (function () {
const
eventNames
=
[
'
load
'
,
'
close
'
,
'
verify
'
,
'
error
'
];
const
ERROR_CODE_LIST
=
[
-
5001
,
-
5002
,
-
5003
,
-
5004
,
-
5005
,
-
5006
];
class
RewardedVideoAd
{
constructor
(
adpid
)
{
this
.
_options
=
{
adpid
:
adpid
};
constructor
(
options
=
{})
{
const
_callbacks
=
this
.
_callbacks
=
{};
eventNames
.
forEach
(
item
=>
{
_callbacks
[
item
]
=
[];
...
...
@@ -9277,7 +9325,7 @@ var serviceContext = (function () {
this
.
_adError
=
''
;
this
.
_loadPromiseResolve
=
null
;
this
.
_loadPromiseReject
=
null
;
const
rewardAd
=
this
.
_rewardAd
=
plus
.
ad
.
createRewardedVideoAd
(
this
.
_
options
);
const
rewardAd
=
this
.
_rewardAd
=
plus
.
ad
.
createRewardedVideoAd
(
options
);
rewardAd
.
onLoad
((
e
)
=>
{
this
.
_isLoad
=
true
;
this
.
_dispatchEvent
(
'
load
'
,
{});
...
...
@@ -9290,6 +9338,9 @@ var serviceContext = (function () {
this
.
_loadAd
();
this
.
_dispatchEvent
(
'
close
'
,
{
isEnded
:
e
.
isEnded
});
});
rewardAd
.
onVerify
&&
rewardAd
.
onVerify
((
e
)
=>
{
this
.
_dispatchEvent
(
'
verify
'
,
{
isValid
:
e
.
isValid
});
});
rewardAd
.
onError
((
e
)
=>
{
const
{
code
,
message
}
=
e
;
const
data
=
{
code
:
code
,
errMsg
:
message
};
...
...
@@ -9323,6 +9374,12 @@ var serviceContext = (function () {
}
})
}
getProvider
()
{
return
this
.
_rewardAd
.
getProvider
()
}
destroy
()
{
this
.
_rewardAd
.
destroy
();
}
_loadAd
()
{
this
.
_isLoad
=
false
;
this
.
_rewardAd
.
load
();
...
...
@@ -9336,10 +9393,8 @@ var serviceContext = (function () {
}
}
function
createRewardedVideoAd
({
adpid
=
''
}
=
{})
{
return
new
RewardedVideoAd
(
adpid
)
function
createRewardedVideoAd
(
options
)
{
return
new
RewardedVideoAd
(
options
)
}
...
...
@@ -10646,8 +10701,9 @@ var serviceContext = (function () {
var
cId
=
canvasEventCallbacks
.
push
(
function
(
data
)
{
invoke$1
(
callbackId
,
data
);
});
// fix ...
operateCanvas
(
canvasId
,
pageId
,
'
putImageData
'
,
{
data
:
[...
data
]
,
data
:
Array
.
prototype
.
slice
.
call
(
data
)
,
x
,
y
,
width
,
...
...
@@ -10729,17 +10785,13 @@ var serviceContext = (function () {
callback
.
invoke
(
callbackId
,
data
);
});
const
methods
=
[
'
getCenterLocation
'
,
'
getScale
'
,
'
getRegion
'
,
'
includePoints
'
,
'
translateMarker
'
];
const
methods
=
[
'
getCenterLocation
'
,
'
moveToLocation
'
,
'
getScale
'
,
'
getRegion
'
,
'
includePoints
'
,
'
translateMarker
'
];
class
MapContext
{
constructor
(
id
,
pageVm
)
{
this
.
id
=
id
;
this
.
pageVm
=
pageVm
;
}
moveToLocation
()
{
operateMapPlayer$3
(
this
.
id
,
this
.
pageVm
,
'
moveToLocation
'
);
}
}
MapContext
.
prototype
.
$getAppMap
=
function
()
{
...
...
@@ -11058,11 +11110,11 @@ var serviceContext = (function () {
});
const
callbacks$a
=
{
pause
:
[]
,
resume
:
[]
,
start
:
[]
,
stop
:
[]
,
error
:
[]
pause
:
null
,
resume
:
null
,
start
:
null
,
stop
:
null
,
error
:
null
};
class
RecorderManager
{
...
...
@@ -11071,15 +11123,13 @@ var serviceContext = (function () {
const
state
=
res
.
state
;
delete
res
.
state
;
delete
res
.
errMsg
;
callbacks$a
[
state
].
forEach
(
callback
=>
{
if
(
typeof
callback
===
'
function
'
)
{
callback
(
res
);
}
});
if
(
typeof
callbacks$a
[
state
]
===
'
function
'
)
{
callbacks$a
[
state
](
res
);
}
});
}
onError
(
callback
)
{
callbacks$a
.
error
.
push
(
callback
)
;
callbacks$a
.
error
=
callback
;
}
onFrameRecorded
(
callback
)
{
...
...
@@ -11091,16 +11141,16 @@ var serviceContext = (function () {
}
onPause
(
callback
)
{
callbacks$a
.
pause
.
push
(
callback
)
;
callbacks$a
.
pause
=
callback
;
}
onResume
(
callback
)
{
callbacks$a
.
resume
.
push
(
callback
)
;
callbacks$a
.
resume
=
callback
;
}
onStart
(
callback
)
{
callbacks$a
.
start
.
push
(
callback
)
;
callbacks$a
.
start
=
callback
;
}
onStop
(
callback
)
{
callbacks$a
.
stop
.
push
(
callback
)
;
callbacks$a
.
stop
=
callback
;
}
pause
()
{
invokeMethod
(
'
operateRecorder
'
,
{
...
...
@@ -11393,7 +11443,7 @@ var serviceContext = (function () {
success
,
fail
,
complete
},
errMsg
)
{
}
=
{}
,
errMsg
)
{
var
data
=
{
errMsg
};
...
...
@@ -12146,7 +12196,7 @@ var serviceContext = (function () {
return
}
if
(
!
page
.
$page
.
meta
.
isNVue
)
{
const
target
=
page
.
$vm
.
_$vd
.
elements
.
find
(
target
=>
target
.
t
agNam
e
===
'
web-view
'
&&
target
.
events
[
'
message
'
]);
const
target
=
page
.
$vm
.
_$vd
.
elements
.
find
(
target
=>
target
.
t
yp
e
===
'
web-view
'
&&
target
.
events
[
'
message
'
]);
if
(
!
target
)
{
return
}
...
...
@@ -12265,13 +12315,13 @@ var serviceContext = (function () {
getCurrentPages
})
{
function
createPageEvent
(
eventType
)
{
return
function
(
args
,
pageId
)
{
return
function
(
args
,
pageId
)
{
pageId
=
parseInt
(
pageId
);
const
pages
=
getCurrentPages
();
const
page
=
pages
.
find
(
page
=>
page
.
$page
.
id
===
pageId
);
if
(
page
)
{
callPageHook
(
page
,
eventType
,
args
);
}
else
{
}
else
if
(
process
.
env
.
NODE_ENV
!==
'
production
'
)
{
console
.
error
(
`Not Found:Page[
${
pageId
}
]`
);
}
}
...
...
@@ -12304,7 +12354,7 @@ var serviceContext = (function () {
}
callback
(
res
);
}
}
}
subscribe
(
'
onPageScroll
'
,
createPageEvent
(
'
onPageScroll
'
));
subscribe
(
'
onReachBottom
'
,
createPageEvent
(
'
onReachBottom
'
));
...
...
@@ -13150,61 +13200,13 @@ var serviceContext = (function () {
data
[
k
]
=
v
;
}
function
diffObject
(
newObj
,
oldObj
,
every
=
true
)
{
let
result
,
key
,
cur
,
old
;
for
(
key
in
newObj
)
{
cur
=
newObj
[
key
];
old
=
oldObj
[
key
];
if
(
old
!==
cur
)
{
if
(
!
every
)
{
return
newObj
}
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
key
,
cur
);
}
}
return
result
}
function
diffArray
(
newArr
,
oldArr
)
{
const
newLen
=
newArr
.
length
;
if
(
newLen
!==
oldArr
.
length
)
{
return
newArr
}
if
(
isPlainObject
(
newArr
[
0
]))
{
for
(
let
i
=
0
;
i
<
newLen
;
i
++
)
{
if
(
diffObject
(
newArr
[
i
],
oldArr
[
i
],
false
))
{
return
newArr
}
}
}
else
{
for
(
let
i
=
0
;
i
<
newLen
;
i
++
)
{
if
(
newArr
[
i
]
!==
oldArr
[
i
])
{
return
newArr
}
}
}
}
function
diffElmData
(
newObj
,
oldObj
)
{
let
result
,
key
,
cur
,
old
;
for
(
key
in
newObj
)
{
cur
=
newObj
[
key
];
old
=
oldObj
[
key
];
if
(
old
!==
cur
)
{
// 全量同步 style (因为 style 可能会动态删除部分样式)
if
(
key
===
B_STYLE
&&
isPlainObject
(
cur
)
&&
isPlainObject
(
old
))
{
if
(
Object
.
keys
(
cur
).
length
!==
Object
.
keys
(
old
).
length
)
{
// 长度不等
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
B_STYLE
,
cur
);
}
else
{
const
style
=
diffObject
(
cur
,
old
,
false
);
style
&&
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
B_STYLE
,
style
);
}
}
else
if
(
key
===
V_FOR
&&
Array
.
isArray
(
cur
)
&&
Array
.
isArray
(
old
))
{
const
vFor
=
diffArray
(
cur
,
old
);
vFor
&&
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
V_FOR
,
vFor
);
}
else
{
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
key
,
cur
);
}
if
(
!
looseEqual
(
old
,
cur
))
{
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
key
,
cur
);
}
}
return
result
...
...
src/platforms/app-plus/service/framework/plugins/diff.js
浏览文件 @
2534a279
import
{
isPlainObject
looseEqual
}
from
'
uni-shared
'
import
{
V_FOR
,
B_STYLE
}
from
'
../../constants
'
function
setResult
(
data
,
k
,
v
)
{
data
[
k
]
=
v
}
function
diffObject
(
newObj
,
oldObj
,
every
=
true
)
{
let
result
,
key
,
cur
,
old
for
(
key
in
newObj
)
{
cur
=
newObj
[
key
]
old
=
oldObj
[
key
]
if
(
old
!==
cur
)
{
if
(
!
every
)
{
return
newObj
}
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
key
,
cur
)
}
}
return
result
}
function
diffArray
(
newArr
,
oldArr
)
{
const
newLen
=
newArr
.
length
if
(
newLen
!==
oldArr
.
length
)
{
return
newArr
}
if
(
isPlainObject
(
newArr
[
0
]))
{
for
(
let
i
=
0
;
i
<
newLen
;
i
++
)
{
if
(
diffObject
(
newArr
[
i
],
oldArr
[
i
],
false
))
{
return
newArr
}
}
}
else
{
for
(
let
i
=
0
;
i
<
newLen
;
i
++
)
{
if
(
newArr
[
i
]
!==
oldArr
[
i
])
{
return
newArr
}
}
}
}
function
diffElmData
(
newObj
,
oldObj
)
{
let
result
,
key
,
cur
,
old
for
(
key
in
newObj
)
{
cur
=
newObj
[
key
]
old
=
oldObj
[
key
]
if
(
old
!==
cur
)
{
if
(
key
===
B_STYLE
&&
isPlainObject
(
cur
)
&&
isPlainObject
(
old
))
{
// 全量同步 style (因为 style 可能会动态删除部分样式)
if
(
Object
.
keys
(
cur
).
length
!==
Object
.
keys
(
old
).
length
)
{
// 长度不等
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
B_STYLE
,
cur
)
}
else
{
const
style
=
diffObject
(
cur
,
old
,
false
)
style
&&
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
B_STYLE
,
style
)
}
}
else
if
(
key
===
V_FOR
&&
Array
.
isArray
(
cur
)
&&
Array
.
isArray
(
old
))
{
const
vFor
=
diffArray
(
cur
,
old
)
vFor
&&
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
V_FOR
,
vFor
)
}
else
{
if
(
key
.
indexOf
(
'
change:
'
)
===
0
)
{
// wxs change:prop
try
{
// 先简单的用 stringify 判断
if
(
JSON
.
stringify
(
cur
)
===
JSON
.
stringify
(
old
))
{
continue
}
}
catch
(
e
)
{}
}
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
key
,
cur
)
}
if
(
!
looseEqual
(
old
,
cur
))
{
setResult
(
result
||
(
result
=
Object
.
create
(
null
)),
key
,
cur
)
}
}
return
result
...
...
src/shared/util.js
浏览文件 @
2534a279
...
...
@@ -96,3 +96,42 @@ export function debounce (fn, delay) {
export
function
kebabCase
(
string
)
{
return
string
.
replace
(
/
[
A-Z
]
/g
,
str
=>
'
-
'
+
str
.
toLowerCase
())
}
/**
* Check if two values are loosely equal - that is,
* if they are plain objects, do they have the same shape?
*/
export
function
looseEqual
(
a
,
b
)
{
if
(
a
===
b
)
return
true
const
isObjectA
=
isObject
(
a
)
const
isObjectB
=
isObject
(
b
)
if
(
isObjectA
&&
isObjectB
)
{
try
{
const
isArrayA
=
Array
.
isArray
(
a
)
const
isArrayB
=
Array
.
isArray
(
b
)
if
(
isArrayA
&&
isArrayB
)
{
return
a
.
length
===
b
.
length
&&
a
.
every
((
e
,
i
)
=>
{
return
looseEqual
(
e
,
b
[
i
])
})
}
else
if
(
a
instanceof
Date
&&
b
instanceof
Date
)
{
return
a
.
getTime
()
===
b
.
getTime
()
}
else
if
(
!
isArrayA
&&
!
isArrayB
)
{
const
keysA
=
Object
.
keys
(
a
)
const
keysB
=
Object
.
keys
(
b
)
return
keysA
.
length
===
keysB
.
length
&&
keysA
.
every
(
key
=>
{
return
looseEqual
(
a
[
key
],
b
[
key
])
})
}
else
{
/* istanbul ignore next */
return
false
}
}
catch
(
e
)
{
/* istanbul ignore next */
return
false
}
}
else
if
(
!
isObjectA
&&
!
isObjectB
)
{
return
String
(
a
)
===
String
(
b
)
}
else
{
return
false
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录