Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
yangkaifeng
uni-app
提交
d8e7df02
U
uni-app
项目概览
yangkaifeng
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
3
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d8e7df02
编写于
7月 06, 2021
作者:
Q
qiang
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev' into alpha
# Conflicts: # packages/uni-mp-weixin/dist/index.js
上级
5ab4b880
57ed3bf5
变更
28
隐藏空白更改
内联
并排
Showing
28 changed file
with
447 addition
and
282 deletion
+447
-282
docs/component/input.md
docs/component/input.md
+2
-6
packages/uni-cli-shared/lib/preprocess.js
packages/uni-cli-shared/lib/preprocess.js
+4
-0
packages/uni-mp-weixin/dist/index.js
packages/uni-mp-weixin/dist/index.js
+111
-107
packages/uni-template-compiler/__tests__/compiler-extra.spec.js
...es/uni-template-compiler/__tests__/compiler-extra.spec.js
+10
-0
packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js
...ni-template-compiler/__tests__/compiler-mp-alipay.spec.js
+2
-2
packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
...uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
+2
-2
packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js
...ni-template-compiler/__tests__/compiler-mp-weixin.spec.js
+46
-6
packages/uni-template-compiler/lib/script/traverse/data/event.js
...s/uni-template-compiler/lib/script/traverse/data/event.js
+1
-2
packages/uni-template-compiler/lib/script/traverse/index.js
packages/uni-template-compiler/lib/script/traverse/index.js
+3
-17
packages/uni-template-compiler/lib/script/traverse/render-list.js
.../uni-template-compiler/lib/script/traverse/render-list.js
+8
-4
packages/uni-template-compiler/lib/script/traverse/render-slot.js
.../uni-template-compiler/lib/script/traverse/render-slot.js
+5
-2
packages/uni-template-compiler/lib/script/traverse/statements.js
...s/uni-template-compiler/lib/script/traverse/statements.js
+71
-15
packages/vue-cli-plugin-uni/lib/configure-webpack.js
packages/vue-cli-plugin-uni/lib/configure-webpack.js
+15
-2
packages/vue-cli-plugin-uni/packages/mp-vue/dist/mp.runtime.esm.js
...vue-cli-plugin-uni/packages/mp-vue/dist/mp.runtime.esm.js
+2
-1
packages/webpack-uni-mp-loader/lib/plugin/generate-json.js
packages/webpack-uni-mp-loader/lib/plugin/generate-json.js
+1
-1
packages/webpack-uni-pages-loader/lib/platforms/mp-toutiao/project.config.json
...pages-loader/lib/platforms/mp-toutiao/project.config.json
+1
-1
src/core/runtime/wrapper/create-subpackage-app.js
src/core/runtime/wrapper/create-subpackage-app.js
+8
-7
src/core/view/components/image/index.vue
src/core/view/components/image/index.vue
+2
-3
src/core/view/components/input/index.vue
src/core/view/components/input/index.vue
+22
-32
src/core/view/components/scroll-view/index.vue
src/core/view/components/scroll-view/index.vue
+67
-41
src/core/view/mixins/field.js
src/core/view/mixins/field.js
+3
-1
src/core/view/mixins/keyboard.js
src/core/view/mixins/keyboard.js
+31
-22
src/core/view/plugins/index.js
src/core/view/plugins/index.js
+1
-1
src/platforms/app-plus/service/framework/config.js
src/platforms/app-plus/service/framework/config.js
+1
-0
src/platforms/app-plus/view/framework/plugins/gesture.js
src/platforms/app-plus/view/framework/plugins/gesture.js
+17
-0
src/platforms/app-plus/view/framework/plugins/index.js
src/platforms/app-plus/view/framework/plugins/index.js
+3
-1
src/platforms/h5/components/page/pageHead.vue
src/platforms/h5/components/page/pageHead.vue
+0
-1
src/platforms/mp-weixin/runtime/wrapper/app-base-parser.js
src/platforms/mp-weixin/runtime/wrapper/app-base-parser.js
+8
-5
未找到文件。
docs/component/input.md
浏览文件 @
d8e7df02
...
...
@@ -24,7 +24,6 @@
|adjust-position|Boolean|true|键盘弹起时,是否自动上推页面|App-Android(vue 页面 softinputMode 为 adjustResize 时无效)、微信小程序、百度小程序、QQ小程序|
|hold-keyboard|boolean|false|focus时,点击页面的时候不收起键盘|微信小程序2.8.2|
|auto-blur|boolean|false|键盘收起时,是否自动失去焦点|App 3.0.0+|
|verifyNumber|boolean|false|当设置
`type="number"`
时,是否对输入的字符执行
`当前输入是否有效`
判断|HBuilder 3.1.19+|
|@input|EventHandle||当键盘输入时,触发input事件,event.detail = {value}|差异见下方 Tips|
|@focus|EventHandle||输入框聚焦时触发,event.detail = { value, height },height 为键盘高度|仅微信小程序、App(2.2.3+) 、QQ小程序支持 height|
|@blur|EventHandle||输入框失去焦点时触发,event.detail = {value: value}||
...
...
@@ -37,9 +36,6 @@
-
如果遇到 value 属性设置不生效的问题参考:
[
组件属性设置不生效解决办法
](
/vue-api?id=_4-组件属性设置不生效解决办法
)
-
`input`
组件上有默认的
`min-height`
样式,如果
`min-height`
的值大于
`height`
的值那么
`height`
样式无效。
-
H5 暂未支持动态切换,请使用
`v-if`
进行整体切换。
-
`verifyNumber`
:是否对输入的字符执行输入是否有效判断判断
-
为
`false`
时:不执行输入是否有效判断,输入时会响应
`input`
事件,此时
`event.detail = {value,valid}`
,属性
`valid`
用来表明当前输入是否有效。
-
为
`true`
时:执行输入是否有效判断, 输入非数字字符将不会被赋值,也不会响应
`input`
事件。例如:
`-(负号)`
就是非数字字符。输入负数时,需要输入数字后再移动光标到数字最前面输入
`-(负号)`
。
```
html
<!-- 错误写法 -->
...
...
@@ -57,9 +53,9 @@
|值|说明|平台差异说明|
|:-|:-|:-|
|text|文本输入键盘||
|number|数字输入键盘|均支持,
app-vue下可以输入浮点数,app-nvue和小程序平台下只能输入整数。注意iOS上app-vue弹出的数字键盘并非9宫格方式
|
|number|数字输入键盘|均支持,
App平台、H5平台 3.1.22 以下版本 vue 页面在 iOS 平台显示的键盘包含负数和小数。
|
|idcard|身份证输入键盘|微信、支付宝、百度、QQ小程序|
|digit|带小数点的数字键盘|
App的nvue页面、微信、支付宝、百度、头条、QQ小程序
|
|digit|带小数点的数字键盘|
均支持,App平台、H5平台 vue 页面在 iOS 平台显示的键盘包含负数。
|
**注意事项**
...
...
packages/uni-cli-shared/lib/preprocess.js
浏览文件 @
d8e7df02
const
DEFAULT_KEYS
=
[
'
VUE2
'
,
'
VUE3
'
,
'
MP
'
,
'
APP
'
,
'
APP-PLUS-NVUE
'
,
...
...
@@ -25,6 +27,8 @@ module.exports = function initPreprocess (name, platforms, userDefines = {}) {
defaultContext
[
normalize
(
name
)]
=
false
})
defaultContext
.
VUE2
=
true
vueContext
[
normalize
(
name
)]
=
true
if
(
name
===
'
app-plus
'
)
{
...
...
packages/uni-mp-weixin/dist/index.js
浏览文件 @
d8e7df02
import
Vue
from
'
vue
'
;
function
b64DecodeUnicode
(
str
)
{
return
decodeURIComponent
(
atob
(
str
).
split
(
''
).
map
(
function
(
c
)
{
return
'
%
'
+
(
'
00
'
+
c
.
charCodeAt
(
0
).
toString
(
16
)).
slice
(
-
2
)
}).
join
(
''
))
}
function
getCurrentUserInfo
()
{
const
token
=
(
wx
).
getStorageSync
(
'
uni_id_token
'
)
||
''
;
const
tokenArr
=
token
.
split
(
'
.
'
);
if
(
!
token
||
tokenArr
.
length
!==
3
)
{
return
{
uid
:
null
,
role
:
[],
permission
:
[],
tokenExpired
:
0
}
}
let
userInfo
;
try
{
userInfo
=
JSON
.
parse
(
b64DecodeUnicode
(
tokenArr
[
1
]));
}
catch
(
error
)
{
throw
new
Error
(
'
获取当前用户信息出错,详细错误信息为:
'
+
error
.
message
)
}
userInfo
.
tokenExpired
=
userInfo
.
exp
*
1000
;
delete
userInfo
.
exp
;
delete
userInfo
.
iat
;
return
userInfo
}
function
uniIdMixin
(
Vue
)
{
Vue
.
prototype
.
uniIDHasRole
=
function
(
roleId
)
{
const
{
role
}
=
getCurrentUserInfo
();
return
role
.
indexOf
(
roleId
)
>
-
1
};
Vue
.
prototype
.
uniIDHasPermission
=
function
(
permissionId
)
{
const
{
permission
}
=
getCurrentUserInfo
();
return
this
.
uniIDHasRole
(
'
admin
'
)
||
permission
.
indexOf
(
permissionId
)
>
-
1
};
Vue
.
prototype
.
uniIDTokenValid
=
function
()
{
const
{
tokenExpired
}
=
getCurrentUserInfo
();
return
tokenExpired
>
Date
.
now
()
};
function
b64DecodeUnicode
(
str
)
{
return
decodeURIComponent
(
atob
(
str
).
split
(
''
).
map
(
function
(
c
)
{
return
'
%
'
+
(
'
00
'
+
c
.
charCodeAt
(
0
).
toString
(
16
)).
slice
(
-
2
)
}).
join
(
''
))
}
function
getCurrentUserInfo
()
{
const
token
=
(
wx
).
getStorageSync
(
'
uni_id_token
'
)
||
''
;
const
tokenArr
=
token
.
split
(
'
.
'
);
if
(
!
token
||
tokenArr
.
length
!==
3
)
{
return
{
uid
:
null
,
role
:
[],
permission
:
[],
tokenExpired
:
0
}
}
let
userInfo
;
try
{
userInfo
=
JSON
.
parse
(
b64DecodeUnicode
(
tokenArr
[
1
]));
}
catch
(
error
)
{
throw
new
Error
(
'
获取当前用户信息出错,详细错误信息为:
'
+
error
.
message
)
}
userInfo
.
tokenExpired
=
userInfo
.
exp
*
1000
;
delete
userInfo
.
exp
;
delete
userInfo
.
iat
;
return
userInfo
}
function
uniIdMixin
(
Vue
)
{
Vue
.
prototype
.
uniIDHasRole
=
function
(
roleId
)
{
const
{
role
}
=
getCurrentUserInfo
();
return
role
.
indexOf
(
roleId
)
>
-
1
};
Vue
.
prototype
.
uniIDHasPermission
=
function
(
permissionId
)
{
const
{
permission
}
=
getCurrentUserInfo
();
return
this
.
uniIDHasRole
(
'
admin
'
)
||
permission
.
indexOf
(
permissionId
)
>
-
1
};
Vue
.
prototype
.
uniIDTokenValid
=
function
()
{
const
{
tokenExpired
}
=
getCurrentUserInfo
();
return
tokenExpired
>
Date
.
now
()
};
}
const
_toString
=
Object
.
prototype
.
toString
;
...
...
@@ -472,37 +472,37 @@ var previewImage = {
}
};
const
UUID_KEY
=
'
__DC_STAT_UUID
'
;
let
deviceId
;
function
addUuid
(
result
)
{
deviceId
=
deviceId
||
wx
.
getStorageSync
(
UUID_KEY
);
if
(
!
deviceId
)
{
deviceId
=
Date
.
now
()
+
''
+
Math
.
floor
(
Math
.
random
()
*
1
e7
);
wx
.
setStorage
({
key
:
UUID_KEY
,
data
:
deviceId
});
}
result
.
deviceId
=
deviceId
;
}
function
addSafeAreaInsets
(
result
)
{
if
(
result
.
safeArea
)
{
const
safeArea
=
result
.
safeArea
;
result
.
safeAreaInsets
=
{
top
:
safeArea
.
top
,
left
:
safeArea
.
left
,
right
:
result
.
windowWidth
-
safeArea
.
right
,
bottom
:
result
.
windowHeight
-
safeArea
.
bottom
};
}
}
var
getSystemInfo
=
{
returnValue
:
function
(
result
)
{
addUuid
(
result
);
addSafeAreaInsets
(
result
);
}
const
UUID_KEY
=
'
__DC_STAT_UUID
'
;
let
deviceId
;
function
addUuid
(
result
)
{
deviceId
=
deviceId
||
wx
.
getStorageSync
(
UUID_KEY
);
if
(
!
deviceId
)
{
deviceId
=
Date
.
now
()
+
''
+
Math
.
floor
(
Math
.
random
()
*
1
e7
);
wx
.
setStorage
({
key
:
UUID_KEY
,
data
:
deviceId
});
}
result
.
deviceId
=
deviceId
;
}
function
addSafeAreaInsets
(
result
)
{
if
(
result
.
safeArea
)
{
const
safeArea
=
result
.
safeArea
;
result
.
safeAreaInsets
=
{
top
:
safeArea
.
top
,
left
:
safeArea
.
left
,
right
:
result
.
windowWidth
-
safeArea
.
right
,
bottom
:
result
.
windowHeight
-
safeArea
.
bottom
};
}
}
var
getSystemInfo
=
{
returnValue
:
function
(
result
)
{
addUuid
(
result
);
addSafeAreaInsets
(
result
);
}
};
// import navigateTo from 'uni-helpers/navigate-to'
...
...
@@ -1369,11 +1369,14 @@ function initScopedSlotsParams () {
};
Vue
.
prototype
.
$setScopedSlotsParams
=
function
(
name
,
value
)
{
const
vueId
=
this
.
$options
.
propsData
.
vueId
;
const
object
=
center
[
vueId
]
=
center
[
vueId
]
||
{};
object
[
name
]
=
value
;
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
();
const
vueIds
=
this
.
$options
.
propsData
.
vueId
;
if
(
vueIds
)
{
const
vueId
=
vueIds
.
split
(
'
,
'
)[
0
];
const
object
=
center
[
vueId
]
=
center
[
vueId
]
||
{};
object
[
name
]
=
value
;
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
();
}
}
};
...
...
@@ -1774,11 +1777,12 @@ function createComponent (vueOptions) {
}
}
function
createSubpackageApp
(
vm
)
{
function
createSubpackageApp
(
vm
)
{
const
appOptions
=
parseApp
(
vm
);
const
app
=
getApp
({
allowDefault
:
true
});
vm
.
$scope
=
app
;
const
globalData
=
app
.
globalData
;
if
(
globalData
)
{
Object
.
keys
(
appOptions
.
globalData
).
forEach
(
name
=>
{
...
...
@@ -1793,39 +1797,39 @@ function createSubpackageApp (vm) {
}
});
if
(
isFn
(
appOptions
.
onShow
)
&&
wx
.
onAppShow
)
{
wx
.
onAppShow
((...
args
)
=>
{
appOptions
.
onShow
.
apply
(
app
,
args
);
wx
.
onAppShow
((...
args
)
=>
{
vm
.
__call_hook
(
'
onShow
'
,
args
);
});
}
if
(
isFn
(
appOptions
.
onHide
)
&&
wx
.
onAppHide
)
{
wx
.
onAppHide
((...
args
)
=>
{
appOptions
.
onHide
.
apply
(
app
,
args
);
wx
.
onAppHide
((...
args
)
=>
{
vm
.
__call_hook
(
'
onHide
'
,
args
);
});
}
if
(
isFn
(
appOptions
.
onLaunch
))
{
const
args
=
wx
.
getLaunchOptionsSync
&&
wx
.
getLaunchOptionsSync
();
appOptions
.
onLaunch
.
call
(
app
,
args
);
vm
.
__call_hook
(
'
onLaunch
'
,
args
);
}
return
vm
}
function
createPlugin
(
vm
)
{
const
appOptions
=
parseApp
(
vm
);
if
(
isFn
(
appOptions
.
onShow
)
&&
wx
.
onAppShow
)
{
wx
.
onAppShow
((...
args
)
=>
{
appOptions
.
onShow
.
apply
(
vm
,
args
);
});
}
if
(
isFn
(
appOptions
.
onHide
)
&&
wx
.
onAppHide
)
{
wx
.
onAppHide
((...
args
)
=>
{
appOptions
.
onHide
.
apply
(
vm
,
args
);
});
}
if
(
isFn
(
appOptions
.
onLaunch
))
{
const
args
=
wx
.
getLaunchOptionsSync
&&
wx
.
getLaunchOptionsSync
();
appOptions
.
onLaunch
.
call
(
vm
,
args
);
}
return
vm
function
createPlugin
(
vm
)
{
const
appOptions
=
parseApp
(
vm
);
if
(
isFn
(
appOptions
.
onShow
)
&&
wx
.
onAppShow
)
{
wx
.
onAppShow
((...
args
)
=>
{
appOptions
.
onShow
.
apply
(
vm
,
args
);
});
}
if
(
isFn
(
appOptions
.
onHide
)
&&
wx
.
onAppHide
)
{
wx
.
onAppHide
((...
args
)
=>
{
appOptions
.
onHide
.
apply
(
vm
,
args
);
});
}
if
(
isFn
(
appOptions
.
onLaunch
))
{
const
args
=
wx
.
getLaunchOptionsSync
&&
wx
.
getLaunchOptionsSync
();
appOptions
.
onLaunch
.
call
(
vm
,
args
);
}
return
vm
}
todos
.
forEach
(
todoApi
=>
{
...
...
packages/uni-template-compiler/__tests__/compiler-extra.spec.js
浏览文件 @
d8e7df02
...
...
@@ -737,6 +737,16 @@ describe('mp:compiler-extra', () => {
'
<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index"><view><view data-event-opts="{{[[
\'
tap
\'
,[[
\'
e0
\'
,[
\'
$event
\'
]]]]]}}" data-event-params="{{({item})}}" bindtap="__e"></view></view></block>
'
,
'
with(this){var l0=array();if(!_isMounted){e0=function($event,item){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item=_temp2.item;var _temp,_temp2;return test(item)}}$mp.data=Object.assign({},{$root:{l0:l0}})}
'
)
assertCodegen
(
'
<view v-for="(item, index) in array()"><view @click="test(item)">{{item}}</view></view>
'
,
'
<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index"><view><view data-event-opts="{{[[
\'
tap
\'
,[[
\'
e0
\'
,[
\'
$event
\'
]]]]]}}" data-event-params="{{({item})}}" bindtap="__e">{{item}}</view></view></block>
'
,
'
with(this){var l0=array();if(!_isMounted){e0=function($event,item){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item=_temp2.item;var _temp,_temp2;return test(item)}}$mp.data=Object.assign({},{$root:{l0:l0}})}
'
)
assertCodegen
(
'
<view v-for="(item, index) in array()"><view @click="test(item)">{{get(item)}}</view></view>
'
,
'
<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index"><view><view data-event-opts="{{[[
\'
tap
\'
,[[
\'
e0
\'
,[
\'
$event
\'
]]]]]}}" data-event-params="{{({item:item.$orig})}}" bindtap="__e">{{item.m0}}</view></view></block>
'
,
'
with(this){var l0=__map(array(),function(item,index){var $orig=__get_orig(item);var m0=get(item);return{$orig:$orig,m0:m0}});if(!_isMounted){e0=function($event,item){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item=_temp2.item;var _temp,_temp2;return test(item)}}$mp.data=Object.assign({},{$root:{l0:l0}})}
'
)
})
it
(
'
generate bool attr
'
,
()
=>
{
assertCodegen
(
...
...
packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js
浏览文件 @
d8e7df02
...
...
@@ -115,7 +115,7 @@ describe('mp:compiler-mp-alipay', () => {
assertCodegen
(
'
<view><slot :item="item"><slot></view>
'
,
'
<view><block a:if="{{$slots.$default}}"><slot item="{{item}}"></slot></block><block a:else><slot></slot></block></view>
'
,
'
with(this){if($scope.props.scopedSlotsCompiler==="augmented"){
const $root=$mp.data.$root;
$setScopedSlotsParams("default",{"item":item})}}
'
,
'
with(this){if($scope.props.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":item})}}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
...
...
@@ -123,7 +123,7 @@ describe('mp:compiler-mp-alipay', () => {
assertCodegen
(
'
<view><slot v-bind="object"><slot></view>
'
,
'
<view><block a:if="{{$slots.$default}}"><slot></slot></block><block a:else><slot></slot></block></view>
'
,
'
with(this){if($scope.props.scopedSlotsCompiler==="augmented"){
const $root=$mp.data.$root;
$setScopedSlotsParams("default",object)}}
'
,
'
with(this){if($scope.props.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",object)}}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
...
...
packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js
浏览文件 @
d8e7df02
...
...
@@ -99,7 +99,7 @@ describe('mp:compiler-mp-baidu', () => {
assertCodegen
(
'
<view><slot :item="item"><slot></view>
'
,
'
<view><block s-if="{{$slots.default}}"><slot var-item="item"></slot></block><block s-else><slot></slot></block></view>
'
,
'
with(this){if($scope.data.scopedSlotsCompiler==="augmented"){
const $root=$mp.data.$root;
$setScopedSlotsParams("default",{"item":item})}}
'
,
'
with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":item})}}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
...
...
@@ -107,7 +107,7 @@ describe('mp:compiler-mp-baidu', () => {
assertCodegen
(
'
<view><slot v-bind="object"><slot></view>
'
,
'
<view><block s-if="{{$slots.default}}"><slot></slot></block><block s-else><slot></slot></block></view>
'
,
'
with(this){if($scope.data.scopedSlotsCompiler==="augmented"){
const $root=$mp.data.$root;
$setScopedSlotsParams("default",object)}}
'
,
'
with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",object)}}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
...
...
packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js
浏览文件 @
d8e7df02
...
...
@@ -116,7 +116,39 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen
(
'
<view><slot :item="item"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view>
'
,
'
with(this){if($scope.data.scopedSlotsCompiler==="augmented"){const $root=$mp.data.$root;$setScopedSlotsParams("default",{"item":item})}}
'
,
'
with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":item})}}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
)
assertCodegen
(
'
<view><view v-for="(item,index) in list" :key="index"><slot :item="item"><slot></view></view>
'
,
'
<view><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item.$orig}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view></block></view>
'
,
'
with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":$orig})}return{$orig:$orig}});$mp.data=Object.assign({},{$root:{l0:l0}})}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
)
assertCodegen
(
'
<view><view v-for="(item,index) in list" :key="index"><slot :item="item" :test="test"><slot></view></view>
'
,
'
<view><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item.$orig}}" test="{{test}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view></block></view>
'
,
'
with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":$orig,"test":test})}return{$orig:$orig}});$mp.data=Object.assign({},{$root:{l0:l0}})}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
)
assertCodegen
(
'
<view><view v-for="(item,index) in list" :key="index"><slot :item="item" :test="test()"><slot></view></view>
'
,
'
<view><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item.$orig}}" test="{{$root.m0}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view></block></view>
'
,
'
with(this){var m0=test();var l0=__map(list,function(item,index){var $orig=__get_orig(item);if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":$orig,"test":m0})}return{$orig:$orig}});$mp.data=Object.assign({},{$root:{m0:m0,l0:l0}})}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
)
assertCodegen
(
'
<view><view v-for="(item,index) in list" :key="index"><slot :item="item" :test="test()+item"><slot></view></view>
'
,
'
<view><block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{item.$orig}}" test="{{$root.m0+item.$orig}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view></block></view>
'
,
'
with(this){var m0=test();var l0=__map(list,function(item,index){var $orig=__get_orig(item);if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",{"item":$orig,"test":m0+$orig})}return{$orig:$orig}});$mp.data=Object.assign({},{$root:{m0:m0,l0:l0}})}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
...
...
@@ -124,7 +156,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen
(
'
<view><slot :item="getValue(item)"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot><scoped-slots-default item="{{$root.m0}}" class="scoped-ref" bind:__l="__l"></scoped-slots-default></block><block wx:else><slot></slot></block></view>
'
,
'
with(this){var m0=getValue(item);$mp.data=Object.assign({},{$root:{m0:m0}});if($scope.data.scopedSlotsCompiler==="augmented"){
const $root=$mp.data.$root;$setScopedSlotsParams("default",{"item":$root.
m0})}}
'
,
'
with(this){var m0=getValue(item);$mp.data=Object.assign({},{$root:{m0:m0}});if($scope.data.scopedSlotsCompiler==="augmented"){
$setScopedSlotsParams("default",{"item":
m0})}}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
...
...
@@ -132,7 +164,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen
(
'
<view><slot v-bind="object"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot></block><block wx:else><slot></slot></block></view>
'
,
'
with(this){if($scope.data.scopedSlotsCompiler==="augmented"){
const $root=$mp.data.$root;
$setScopedSlotsParams("default",object)}}
'
,
'
with(this){if($scope.data.scopedSlotsCompiler==="augmented"){$setScopedSlotsParams("default",object)}}
'
,
{
scopedSlotsCompiler
:
'
auto
'
}
...
...
@@ -164,10 +196,18 @@ describe('mp:compiler-mp-weixin', () => {
scopedSlotsCompiler
:
'
augmented
'
}
)
assertCodegen
(
'
<my-component1><my-component2><template v-slot="{item}">{{getValue(item)}}<template></my-component2></my-component1>
'
,
'
<my-component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[
\'
default
\'
]}}"><my-component2 vue-id="{{(
\'
551070e6-2
\'
)+
\'
,
\'
+(
\'
551070e6-1
\'
)}}" bind:__l="__l" vue-slots="{{[
\'
default
\'
]}}"><block><block wx:if="{{$root.m0}}">{{$root.m1}}</block></block></my-component2></my-component1>
'
,
'
with(this){var m0=$hasScopedSlotsParams("551070e6-2");var m1=m0?getValue($getScopedSlotsParams("551070e6-2","default","item")):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1}})}
'
,
{
scopedSlotsCompiler
:
'
augmented
'
}
)
assertCodegen
(
'
<view><slot :item="item"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot></block><block wx:else><slot></slot></block></view>
'
,
'
with(this){
$setScopedSlotsParams("default",{"item":item})
}
'
,
'
with(this){
{$setScopedSlotsParams("default",{"item":item})}
}
'
,
{
scopedSlotsCompiler
:
'
augmented
'
}
...
...
@@ -175,7 +215,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen
(
'
<view><slot :item="getValue(item)"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot></block><block wx:else><slot></slot></block></view>
'
,
'
with(this){
$setScopedSlotsParams("default",{"item":getValue(item)})
}
'
,
'
with(this){
{$setScopedSlotsParams("default",{"item":getValue(item)})}
}
'
,
{
scopedSlotsCompiler
:
'
augmented
'
}
...
...
@@ -183,7 +223,7 @@ describe('mp:compiler-mp-weixin', () => {
assertCodegen
(
'
<view><slot v-bind="object"><slot></view>
'
,
'
<view><block wx:if="{{$slots.default}}"><slot></slot></block><block wx:else><slot></slot></block></view>
'
,
'
with(this){
$setScopedSlotsParams("default",object)
}
'
,
'
with(this){
{$setScopedSlotsParams("default",object)}
}
'
,
{
scopedSlotsCompiler
:
'
augmented
'
}
...
...
packages/uni-template-compiler/lib/script/traverse/data/event.js
浏览文件 @
d8e7df02
...
...
@@ -520,8 +520,7 @@ module.exports = function processEvent (paths, path, state, isComponent, tagName
ret
.
push
(
t
.
objectProperty
(
t
.
stringLiteral
(
ATTR_DATA_EVENT_PARAMS
),
// 直接使用对象格式微信小程序编译会报错
t
.
stringLiteral
(
`{{({
${
params
.
join
(
'
,
'
)}
})}}`
)
t
.
objectExpression
(
params
.
map
(
param
=>
t
.
objectProperty
(
t
.
identifier
(
param
),
t
.
identifier
(
param
),
false
,
true
)))
)
)
}
...
...
packages/uni-template-compiler/lib/script/traverse/index.js
浏览文件 @
d8e7df02
...
...
@@ -24,7 +24,8 @@ const {
const
{
getInItIfStatement
,
getDataExpressionStatement
getDataExpressionStatement
,
getRenderSlotStatement
}
=
require
(
'
./statements
'
)
const
visitor
=
require
(
'
./visitor
'
)
...
...
@@ -114,22 +115,7 @@ module.exports = function traverse (ast, state) {
}
if
(
renderSlotStatementArray
.
length
)
{
if
(
state
.
options
.
scopedSlotsCompiler
===
'
auto
'
)
{
const
node
=
t
.
ifStatement
(
t
.
binaryExpression
(
'
===
'
,
t
.
memberExpression
(
t
.
memberExpression
(
t
.
identifier
(
'
$scope
'
),
t
.
identifier
(
state
.
options
.
platform
.
name
===
'
mp-alipay
'
?
'
props
'
:
'
data
'
)),
t
.
identifier
(
'
scopedSlotsCompiler
'
)),
t
.
stringLiteral
(
'
augmented
'
)
),
t
.
blockStatement
([
t
.
variableDeclaration
(
'
const
'
,
[
t
.
variableDeclarator
(
t
.
identifier
(
'
$root
'
),
t
.
memberExpression
(
t
.
memberExpression
(
t
.
identifier
(
'
$mp
'
),
t
.
identifier
(
'
data
'
)),
t
.
identifier
(
'
$root
'
))
)]),
...
renderSlotStatementArray
])
)
blockStatementBody
.
push
(
node
)
}
else
{
blockStatementBody
.
push
(...
renderSlotStatementArray
)
}
blockStatementBody
.
push
(
getRenderSlotStatement
(
state
,
renderSlotStatementArray
))
}
reIdentifier
(
identifierArray
)
...
...
packages/uni-template-compiler/lib/script/traverse/render-list.js
浏览文件 @
d8e7df02
...
...
@@ -135,7 +135,8 @@ module.exports = function traverseRenderList (path, state) {
forIndex
,
forExtra
:
getForExtra
(
forItem
,
forIndex
,
path
,
state
),
propertyArray
:
[],
declarationArray
:
[]
declarationArray
:
[],
renderSlotStatementArray
:
[]
}
const
forState
=
{
...
...
@@ -149,13 +150,14 @@ module.exports = function traverseRenderList (path, state) {
propertyArray
:
[],
declarationArray
:
[],
computedProperty
:
{},
initExpressionStatementArray
:
state
.
initExpressionStatementArray
initExpressionStatementArray
:
state
.
initExpressionStatementArray
,
renderSlotStatementArray
:
state
.
renderSlotStatementArray
}
functionExpression
.
traverse
(
require
(
'
./visitor
'
),
forState
)
const
forPath
=
path
.
get
(
'
arguments.0
'
)
if
(
forStateScoped
.
propertyArray
.
length
)
{
if
(
forStateScoped
.
propertyArray
.
length
||
forStateScoped
.
renderSlotStatementArray
.
length
)
{
// for => map
forPath
.
replaceWith
(
getMemberExpr
(
...
...
@@ -165,9 +167,11 @@ module.exports = function traverseRenderList (path, state) {
forPath
.
node
,
forStateScoped
.
propertyArray
,
forStateScoped
.
declarationArray
,
forStateScoped
.
renderSlotStatementArray
,
[],
// eventPropertyArray
forItem
,
forIndex
forIndex
,
state
),
forState
)
...
...
packages/uni-template-compiler/lib/script/traverse/render-slot.js
浏览文件 @
d8e7df02
...
...
@@ -15,7 +15,7 @@ module.exports = function getRenderSlot (path, state) {
const
newProperties
=
[]
propertiesPath
.
forEach
(
path
=>
{
const
properties
=
path
.
get
(
'
key
'
).
isStringLiteral
({
value
:
'
SLOT_DEFAULT
'
})
?
oldProperties
:
newProperties
properties
.
push
(
state
.
options
.
scopedSlotsCompiler
===
'
auto
'
?
path
.
node
:
t
.
clone
Deep
(
path
.
nod
e
))
properties
.
push
(
state
.
options
.
scopedSlotsCompiler
===
'
auto
'
?
path
.
node
:
t
.
clone
Node
(
path
.
node
,
tru
e
))
})
if
(
!
newProperties
.
length
)
{
return
...
...
@@ -29,7 +29,10 @@ module.exports = function getRenderSlot (path, state) {
}
}
if
(
valueNode
)
{
state
.
renderSlotStatementArray
.
push
(
t
.
expressionStatement
(
t
.
callExpression
(
t
.
identifier
(
'
$setScopedSlotsParams
'
),
[
t
.
stringLiteral
(
name
.
node
.
value
),
valueNode
])))
const
scoped
=
state
.
scoped
// TODO 判断是否包含作用域内变量
const
renderSlotStatementArray
=
scoped
&&
scoped
.
length
?
scoped
[
scoped
.
length
-
1
].
renderSlotStatementArray
:
state
.
renderSlotStatementArray
renderSlotStatementArray
.
push
(
t
.
expressionStatement
(
t
.
callExpression
(
t
.
identifier
(
'
$setScopedSlotsParams
'
),
[
t
.
stringLiteral
(
name
.
node
.
value
),
valueNode
])))
}
// TODO 组件嵌套
}
packages/uni-template-compiler/lib/script/traverse/statements.js
浏览文件 @
d8e7df02
...
...
@@ -4,7 +4,9 @@ const {
VAR_MP
,
VAR_ROOT
,
VAR_ORIGINAL
,
INTERNAL_GET_ORIG
INTERNAL_GET_ORIG
,
IDENTIFIER_METHOD
,
IDENTIFIER_FILTER
}
=
require
(
'
../../constants
'
)
/**
* e0=e=>count++
...
...
@@ -31,6 +33,53 @@ function getInItIfStatement (expressionStatementArray) {
)
}
function
getRenderSlotStatement
(
state
,
renderSlotStatementArray
,
forItem
)
{
function
cloneNode
(
node
)
{
if
(
Array
.
isArray
(
node
))
{
return
node
.
map
(
function
(
item
)
{
return
cloneNode
(
item
)
})
}
else
if
(
typeof
node
===
'
object
'
)
{
if
(
!
node
)
{
return
node
}
if
(
t
.
isMemberExpression
(
node
))
{
// 纠正被处理过的对象
const
name
=
node
.
object
.
name
// identifier 使用原值以被后续修改
if
((
name
===
VAR_ROOT
||
name
===
forItem
)
&&
t
.
isIdentifier
(
node
.
property
)
&&
[
IDENTIFIER_METHOD
,
IDENTIFIER_FILTER
].
includes
(
node
.
property
.
name
))
{
return
node
.
property
}
}
else
if
(
t
.
isIdentifier
(
node
,
{
name
:
forItem
}))
{
// 预处理 forItem
return
t
.
identifier
(
VAR_ORIGINAL
)
}
const
target
=
Object
.
create
(
node
)
Object
.
keys
(
node
).
forEach
(
function
(
key
)
{
target
[
key
]
=
cloneNode
(
node
[
key
])
})
return
target
}
else
{
return
node
}
}
renderSlotStatementArray
.
forEach
(
renderSlotStatement
=>
{
const
argument
=
renderSlotStatement
.
expression
.
arguments
[
1
]
if
(
t
.
isObjectExpression
(
argument
))
{
// 克隆以避免影响模板
argument
.
properties
=
cloneNode
(
argument
.
properties
)
}
})
const
blockStatement
=
t
.
blockStatement
(
renderSlotStatementArray
)
if
(
state
.
options
.
scopedSlotsCompiler
===
'
auto
'
)
{
return
t
.
ifStatement
(
t
.
binaryExpression
(
'
===
'
,
t
.
memberExpression
(
t
.
memberExpression
(
t
.
identifier
(
'
$scope
'
),
t
.
identifier
(
state
.
options
.
platform
.
name
===
'
mp-alipay
'
?
'
props
'
:
'
data
'
)),
t
.
identifier
(
'
scopedSlotsCompiler
'
)),
t
.
stringLiteral
(
'
augmented
'
)
),
blockStatement
)
}
return
blockStatement
}
/**
* items.map(function(item,index){return {}})
*/
...
...
@@ -38,9 +87,11 @@ function getMapCallExpression (
object
,
objectPropertyArray
,
declarationArray
,
renderSlotStatementArray
,
eventPropertyArray
,
forItem
,
forIndex
forIndex
,
state
)
{
const
blockStatement
=
[]
// var $orgi = __get_orig(forItem)
...
...
@@ -49,24 +100,28 @@ function getMapCallExpression (
t
.
identifier
(
forItem
)
]))
]))
if
(
declarationArray
.
length
)
{
declarationArray
.
forEach
(
declaration
=>
{
blockStatement
.
push
(
declaration
)
})
blockStatement
.
push
(
t
.
returnStatement
(
// return {$orgi:$orgi}
t
.
objectExpression
(
[
t
.
objectProperty
(
t
.
identifier
(
VAR_ORIGINAL
),
t
.
identifier
(
VAR_ORIGINAL
)
)
].
concat
(
objectPropertyArray
)
)
))
}
if
(
renderSlotStatementArray
.
length
)
{
blockStatement
.
push
(
getRenderSlotStatement
(
state
,
renderSlotStatementArray
,
forItem
))
}
blockStatement
.
push
(
t
.
returnStatement
(
// return {$orgi:$orgi}
t
.
objectExpression
(
[
t
.
objectProperty
(
t
.
identifier
(
VAR_ORIGINAL
),
t
.
identifier
(
VAR_ORIGINAL
)
)
].
concat
(
objectPropertyArray
)
)
))
const
params
=
[
t
.
identifier
(
forItem
)]
if
(
forIndex
)
{
params
.
push
(
t
.
identifier
(
forIndex
))
...
...
@@ -119,5 +174,6 @@ module.exports = {
getInItIfStatement
,
getMapCallExpression
,
getDataExpressionStatement
,
getEventExpressionStatement
getEventExpressionStatement
,
getRenderSlotStatement
}
packages/vue-cli-plugin-uni/lib/configure-webpack.js
浏览文件 @
d8e7df02
...
...
@@ -286,12 +286,25 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
}
}
try
{
if
(
process
.
env
.
UNI_HBUILDERX_PLUGINS
)
{
require
(
path
.
resolve
(
process
.
env
.
UNI_HBUILDERX_PLUGINS
,
'
uni_helpers/lib/bytenode
'
))
const
{
W
}
=
require
(
path
.
resolve
(
process
.
env
.
UNI_HBUILDERX_PLUGINS
,
'
uni_helpers
'
))
plugins
.
push
(
new
W
({
dir
:
process
.
env
.
UNI_INPUT_DIR
}))
}
}
catch
(
e
)
{}
return
merge
({
devtool
:
false
,
resolve
:
{
alias
:
{
'
@
'
:
path
.
resolve
(
process
.
env
.
UNI_INPUT_DIR
),
'
./@
'
:
path
.
resolve
(
process
.
env
.
UNI_INPUT_DIR
),
// css中的'@/static/logo.png'会被转换成'./@/static/logo.png'加载
'
./@
'
:
path
.
resolve
(
process
.
env
.
UNI_INPUT_DIR
),
// css中的'@/static/logo.png'会被转换成'./@/static/logo.png'加载
vue
$
:
getPlatformVue
(
vueOptions
),
'
uni-pages
'
:
path
.
resolve
(
process
.
env
.
UNI_INPUT_DIR
,
'
pages.json
'
),
'
@dcloudio/uni-stat
'
:
require
.
resolve
(
'
@dcloudio/uni-stat
'
),
...
...
@@ -319,4 +332,4 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
watchOptions
:
require
(
'
./util
'
).
getWatchOptions
()
},
platformWebpackConfig
)
}
}
}
packages/vue-cli-plugin-uni/packages/mp-vue/dist/mp.runtime.esm.js
浏览文件 @
d8e7df02
...
...
@@ -5467,7 +5467,8 @@ function _diff(current, pre, path, result) {
var
currentType
=
type
(
currentValue
);
var
preType
=
type
(
preValue
);
if
(
currentType
!=
ARRAYTYPE
&&
currentType
!=
OBJECTTYPE
)
{
if
(
currentValue
!=
pre
[
key
])
{
// NOTE 此处将 != 修改为 !==。涉及地方太多恐怕测试不到,如果出现数据对比问题,将其修改回来。
if
(
currentValue
!==
pre
[
key
])
{
setResult
(
result
,
(
path
==
''
?
''
:
path
+
"
.
"
)
+
key
,
currentValue
);
}
}
else
if
(
currentType
==
ARRAYTYPE
)
{
...
...
packages/webpack-uni-mp-loader/lib/plugin/generate-json.js
浏览文件 @
d8e7df02
...
...
@@ -102,7 +102,7 @@ function normalizeUsingComponents (file, usingComponents) {
}
file
=
path
.
dirname
(
'
/
'
+
file
)
names
.
forEach
(
name
=>
{
usingComponents
[
name
]
=
path
.
relative
(
file
,
usingComponents
[
name
]
)
usingComponents
[
name
]
=
normalizePath
(
path
.
relative
(
file
,
usingComponents
[
name
])
)
})
return
usingComponents
}
...
...
packages/webpack-uni-pages-loader/lib/platforms/mp-toutiao/project.config.json
浏览文件 @
d8e7df02
...
...
@@ -6,6 +6,6 @@
"minified"
:
false
,
"newFeature"
:
true
},
"appid"
:
"
体验a
ppId"
,
"appid"
:
"
testA
ppId"
,
"projectname"
:
""
}
src/core/runtime/wrapper/create-subpackage-app.js
浏览文件 @
d8e7df02
...
...
@@ -7,11 +7,12 @@ import {
import
parseApp
from
'
uni-platform/runtime/wrapper/app-parser
'
export
default
function
createSubpackageApp
(
vm
)
{
export
default
function
createSubpackageApp
(
vm
)
{
const
appOptions
=
parseApp
(
vm
)
const
app
=
getApp
({
allowDefault
:
true
})
vm
.
$scope
=
app
const
globalData
=
app
.
globalData
if
(
globalData
)
{
Object
.
keys
(
appOptions
.
globalData
).
forEach
(
name
=>
{
...
...
@@ -26,18 +27,18 @@ export default function createSubpackageApp (vm) {
}
})
if
(
isFn
(
appOptions
.
onShow
)
&&
__GLOBAL__
.
onAppShow
)
{
__GLOBAL__
.
onAppShow
((...
args
)
=>
{
appOptions
.
onShow
.
apply
(
app
,
args
)
__GLOBAL__
.
onAppShow
((...
args
)
=>
{
vm
.
__call_hook
(
'
onShow
'
,
args
)
})
}
if
(
isFn
(
appOptions
.
onHide
)
&&
__GLOBAL__
.
onAppHide
)
{
__GLOBAL__
.
onAppHide
((...
args
)
=>
{
appOptions
.
onHide
.
apply
(
app
,
args
)
__GLOBAL__
.
onAppHide
((...
args
)
=>
{
vm
.
__call_hook
(
'
onHide
'
,
args
)
})
}
if
(
isFn
(
appOptions
.
onLaunch
))
{
const
args
=
__GLOBAL__
.
getLaunchOptionsSync
&&
__GLOBAL__
.
getLaunchOptionsSync
()
appOptions
.
onLaunch
.
call
(
app
,
args
)
vm
.
__call_hook
(
'
onLaunch
'
,
args
)
}
return
vm
}
}
src/core/view/components/image/index.vue
浏览文件 @
d8e7df02
...
...
@@ -142,14 +142,13 @@ export default {
_fixSize
()
{
if
(
this
.
ratio
)
{
const
$el
=
this
.
$el
const
rect
=
$el
.
getBoundingClientRect
()
if
(
this
.
mode
===
'
widthFix
'
)
{
const
width
=
rect
.
w
idth
const
width
=
$el
.
offsetW
idth
if
(
width
)
{
$el
.
style
.
height
=
fixNumber
(
width
/
this
.
ratio
)
+
'
px
'
}
}
else
if
(
this
.
mode
===
'
heightFix
'
)
{
const
height
=
rect
.
h
eight
const
height
=
$el
.
offsetH
eight
if
(
height
)
{
$el
.
style
.
width
=
fixNumber
(
height
*
this
.
ratio
)
+
'
px
'
}
...
...
src/core/view/components/input/index.vue
浏览文件 @
d8e7df02
<
template
>
<uni-input
v-on=
"$listeners"
>
<div
ref=
"wrapper"
class=
"uni-input-wrapper"
<div
ref=
"wrapper"
class=
"uni-input-wrapper"
>
<div
v-show=
"!(composing || valueSync.length ||
!valid
)"
v-show=
"!(composing || valueSync.length ||
cachedValue === '-'
)"
ref=
"placeholder"
:style=
"placeholderStyle"
:class=
"placeholderClass"
...
...
@@ -23,6 +23,7 @@
:maxlength=
"maxlength"
:step=
"step"
:enterkeyhint=
"confirmType"
:pattern=
"type === 'number' ? '[0-9]*' : null"
class=
"uni-input-input"
autocomplete=
"off"
@
change.stop
...
...
@@ -94,15 +95,10 @@ export default {
confirmType
:
{
type
:
String
,
default
:
'
done
'
},
verifyNumber
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
return
{
valid
:
true
,
wrapperHeight
:
0
,
cachedValue
:
''
}
...
...
@@ -184,8 +180,8 @@ export default {
return
}
// type="number" 不支持 maxlength 属性,因此需要主动限制长度。
if
(
this
.
inputType
===
'
number
'
)
{
// type="number" 不支持 maxlength 属性,因此需要主动限制长度。
const
maxlength
=
parseInt
(
this
.
maxlength
,
10
)
if
(
maxlength
>
0
&&
$event
.
target
.
value
.
length
>
maxlength
)
{
// 输入前字符长度超出范围,则不触发input,且将值还原
...
...
@@ -198,37 +194,31 @@ export default {
this
.
valueSync
=
$event
.
target
.
value
}
}
}
if
(
~
NUMBER_TYPES
.
indexOf
(
this
.
type
))
{
// 在输入 - 负号 的情况下,event.target.value没有值,但是会触发校验 false
this
.
valid
=
this
.
$refs
.
input
.
validity
&&
this
.
$refs
.
input
.
validity
.
valid
if
(
!
this
.
verifyNumber
)
{
this
.
cachedValue
=
this
.
valueSync
}
else
{
// 处理部分输入法可以输入其它字符的情况,此处理无法先输入 -(负号),只能输入数字再移动光标输入负号
if
(
this
.
$refs
.
input
.
validity
&&
!
this
.
valid
)
{
$event
.
target
.
value
=
this
.
cachedValue
this
.
valueSync
=
$event
.
target
.
value
// 输入非法字符不触发 input 事件
// 数字类型输入错误时无法获取具体的值,自定义校验和纠正。
this
.
__clearCachedValue
&&
$event
.
target
.
removeEventListener
(
'
blur
'
,
this
.
__clearCachedValue
)
if
(
$event
.
target
.
validity
&&
!
$event
.
target
.
validity
.
valid
)
{
if
((
!
this
.
cachedValue
&&
$event
.
data
===
'
-
'
)
||
(
this
.
cachedValue
[
0
]
===
'
-
'
&&
$event
.
inputType
===
'
deleteContentBackward
'
))
{
this
.
cachedValue
=
'
-
'
const
clearCachedValue
=
this
.
__clearCachedValue
=
()
=>
{
this
.
cachedValue
=
''
}
$event
.
target
.
addEventListener
(
'
blur
'
,
clearCachedValue
)
return
}
else
{
this
.
cachedValue
=
this
.
valueSync
}
this
.
cachedValue
=
this
.
valueSync
=
$event
.
target
.
value
=
this
.
cachedValue
===
'
-
'
?
''
:
this
.
cachedValue
// 输入非法字符不触发 input 事件
return
}
else
{
this
.
cachedValue
=
this
.
valueSync
}
}
if
(
outOfMaxlength
)
return
this
.
$triggerInput
(
$event
,
Object
.
assign
(
{
this
.
$triggerInput
(
$event
,
{
value
:
this
.
valueSync
},
(()
=>
{
if
(
!
this
.
verifyNumber
)
{
return
{
valid
:
this
.
valid
}
}
})()),
force
)
},
force
)
},
_onComposition
(
$event
)
{
if
(
$event
.
type
===
'
compositionstart
'
)
{
...
...
src/core/view/components/scroll-view/index.vue
浏览文件 @
d8e7df02
...
...
@@ -26,6 +26,7 @@
<div
class=
"uni-scroll-view-refresh-inner"
>
<svg
v-if=
"refreshState=='pulling'"
key=
"refresh__icon"
:style=
"
{'transform': 'rotate('+ refreshRotate +'deg)'}"
fill="#2BD009"
class="uni-scroll-view-refresh__icon"
...
...
@@ -41,6 +42,7 @@
</svg>
<svg
v-if=
"refreshState=='refreshing'"
key=
"refresh__spinner"
class=
"uni-scroll-view-refresh__spinner"
width=
"24"
height=
"24"
...
...
@@ -205,60 +207,77 @@ export default {
}
var
touchStart
=
null
var
needStop
=
null
let
toUpperNumber
=
0
// 容器触顶时,此时鼠标Y轴位置
let
triggerAbort
=
false
let
beforeRefreshing
=
false
this
.
__handleTouchMove
=
function
(
event
)
{
var
x
=
event
.
touches
[
0
].
pageX
var
y
=
event
.
touches
[
0
].
pageY
var
main
=
self
.
$refs
.
main
if
(
needStop
===
null
)
{
if
(
Math
.
abs
(
x
-
touchStart
.
x
)
>
Math
.
abs
(
y
-
touchStart
.
y
))
{
// 横向滑动
if
(
self
.
scrollX
)
{
if
(
main
.
scrollLeft
===
0
&&
x
>
touchStart
.
x
)
{
needStop
=
false
return
}
else
if
(
main
.
scrollWidth
===
main
.
offsetWidth
+
main
.
scrollLeft
&&
x
<
touchStart
.
x
)
{
needStop
=
false
return
}
needStop
=
true
}
else
{
if
(
Math
.
abs
(
x
-
touchStart
.
x
)
>
Math
.
abs
(
y
-
touchStart
.
y
))
{
// 横向滑动
if
(
self
.
scrollX
)
{
if
(
main
.
scrollLeft
===
0
&&
x
>
touchStart
.
x
)
{
needStop
=
false
return
}
else
if
(
main
.
scrollWidth
===
main
.
offsetWidth
+
main
.
scrollLeft
&&
x
<
touchStart
.
x
)
{
needStop
=
false
return
}
needStop
=
true
}
else
{
// 纵向滑动
if
(
self
.
scrollY
)
{
if
(
main
.
scrollTop
===
0
&&
y
>
touchStart
.
y
)
{
needStop
=
false
return
}
else
if
(
main
.
scrollHeight
===
main
.
offsetHeight
+
main
.
scrollTop
&&
y
<
touchStart
.
y
)
{
needStop
=
false
return
}
needStop
=
false
}
}
else
{
// 纵向滑动
if
(
self
.
scrollY
)
{
if
(
self
.
refresherEnabled
&&
main
.
scrollTop
===
0
&&
y
>
touchStart
.
y
)
{
needStop
=
true
}
else
{
// 刷新时,阻止页面滚动
if
(
event
.
cancelable
!==
false
)
event
.
preventDefault
()
}
else
if
(
main
.
scrollHeight
===
main
.
offsetHeight
+
main
.
scrollTop
&&
y
<
touchStart
.
y
)
{
needStop
=
false
return
}
needStop
=
true
}
else
{
needStop
=
false
}
}
if
(
needStop
)
{
event
.
stopPropagation
()
}
if
(
main
.
scrollTop
===
0
&&
event
.
touches
.
length
===
1
)
{
// 如果容器滑动到达顶端,则进入下拉状态
self
.
refreshState
=
'
pulling
'
}
if
(
self
.
refresherEnabled
&&
self
.
refreshState
===
'
pulling
'
)
{
const
dy
=
y
-
touchStart
.
y
self
.
refresherHeight
=
dy
let
rotate
=
dy
/
self
.
refresherThreshold
if
(
rotate
>
1
)
{
rotate
=
1
if
(
toUpperNumber
===
0
)
{
toUpperNumber
=
y
}
if
(
!
beforeRefreshing
)
{
self
.
refresherHeight
=
y
-
toUpperNumber
// 之前为刷新状态则不再触发pulling
if
(
self
.
refresherHeight
>
0
)
{
triggerAbort
=
true
self
.
$trigger
(
'
refresherpulling
'
,
event
,
{
deltaY
:
dy
})
}
}
else
{
rotate
=
rotate
*
360
self
.
refresherHeight
=
dy
+
self
.
refresherThreshold
// 如果之前在刷新状态,则不触发刷新中断
triggerAbort
=
false
}
self
.
refreshRotate
=
rotate
self
.
$trigger
(
'
refresherpulling
'
,
event
,
{
deltaY
:
dy
})
const
route
=
self
.
refresherHeight
/
self
.
refresherThreshold
self
.
refreshRotate
=
(
route
>
1
?
1
:
route
)
*
360
}
}
...
...
@@ -267,14 +286,10 @@ export default {
disableScrollBounce
({
disable
:
true
})
needStop
=
null
touchStart
=
{
x
:
event
.
touches
[
0
].
pageX
,
y
:
event
.
touches
[
0
].
pageY
}
if
(
self
.
refresherEnabled
&&
self
.
refreshState
!==
'
refreshing
'
&&
self
.
$refs
.
main
.
scrollTop
===
0
)
{
self
.
refreshState
=
'
pulling
'
}
}
}
this
.
__handleTouchEnd
=
function
(
event
)
{
...
...
@@ -283,14 +298,24 @@ export default {
disable
:
false
})
if
(
self
.
refresherHeight
>=
self
.
refresherThreshold
)
{
self
.
refresherHeight
=
self
.
refresherThreshold
self
.
refreshState
=
'
refreshing
'
// 之前是刷新状态则不再触发刷新
if
(
beforeRefreshing
)
return
beforeRefreshing
=
true
self
.
_setRefreshState
(
'
refreshing
'
)
}
else
{
self
.
refresherHeight
=
0
self
.
$trigger
(
'
refresherabort
'
,
event
,
{})
beforeRefreshing
=
false
self
.
refreshState
=
'
refresherabort
'
self
.
refresherHeight
=
toUpperNumber
=
0
if
(
triggerAbort
)
{
triggerAbort
=
false
self
.
$trigger
(
'
refresherabort
'
,
event
,
{})
}
}
}
this
.
$refs
.
main
.
addEventListener
(
'
touchstart
'
,
this
.
__handleTouchStart
,
passiveOptions
)
this
.
$refs
.
main
.
addEventListener
(
'
touchmove
'
,
this
.
__handleTouchMove
,
passiveOptions
)
this
.
$refs
.
main
.
addEventListener
(
'
touchmove
'
,
this
.
__handleTouchMove
)
this
.
$refs
.
main
.
addEventListener
(
'
scroll
'
,
this
.
__handleScroll
,
supportsPassive
?
{
passive
:
false
}
:
false
)
...
...
@@ -567,7 +592,8 @@ uni-scroll-view[hidden] {
height
:
40px
;
border-radius
:
50%
;
background-color
:
#fff
;
box-shadow
:
0
1px
6px
rgba
(
0
,
0
,
0
,
.117647
),
0
1px
4px
rgba
(
0
,
0
,
0
,
.117647
);
box-shadow
:
0
1px
6px
rgba
(
0
,
0
,
0
,
0.117647
),
0
1px
4px
rgba
(
0
,
0
,
0
,
0.117647
);
}
.uni-scroll-view-refresh__spinner
{
...
...
src/core/view/mixins/field.js
浏览文件 @
d8e7df02
...
...
@@ -148,7 +148,9 @@ export default {
this
.
_field
=
el
startTime
=
startTime
||
Date
.
now
()
if
(
this
.
needFocus
)
{
this
.
_focus
()
setTimeout
(()
=>
{
this
.
_focus
()
})
}
},
_focus
()
{
...
...
src/core/view/mixins/keyboard.js
浏览文件 @
d8e7df02
...
...
@@ -3,6 +3,28 @@ import {
}
from
'
uni-shared
'
import
emitter
from
'
./emitter
'
let
resetTimer
let
isAndroid
let
osVersion
let
keyboardHeight
let
keyboardChangeCallback
let
webviewStyle
if
(
__PLATFORM__
===
'
app-plus
'
)
{
plusReady
(()
=>
{
isAndroid
=
plus
.
os
.
name
.
toLowerCase
()
===
'
android
'
osVersion
=
plus
.
os
.
version
// iOS 14.6 调用同步方法导致键盘弹卡顿
if
(
!
isAndroid
&&
parseFloat
(
osVersion
)
>=
14.6
)
{
const
currentWebview
=
plus
.
webview
.
currentWebview
()
webviewStyle
=
currentWebview
.
getStyle
()
||
{}
}
})
document
.
addEventListener
(
'
keyboardchange
'
,
function
(
event
)
{
keyboardHeight
=
event
.
height
keyboardChangeCallback
&&
keyboardChangeCallback
()
},
false
)
}
/**
* 保证iOS点击输入框外隐藏键盘
*/
...
...
@@ -14,7 +36,8 @@ function setSoftinputTemporary (vm, reset) {
const
MODE_ADJUSTPAN
=
'
adjustPan
'
const
MODE_NOTHING
=
'
nothing
'
const
currentWebview
=
plus
.
webview
.
currentWebview
()
const
style
=
currentWebview
.
getStyle
()
||
{}
// iOS 14.6 调用同步方法导致键盘弹卡顿
const
style
=
webviewStyle
||
currentWebview
.
getStyle
()
||
{}
const
options
=
{
mode
:
(
reset
||
style
.
softinputMode
===
MODE_ADJUSTRESIZE
)
?
MODE_ADJUSTRESIZE
:
(
vm
.
adjustPosition
?
MODE_ADJUSTPAN
:
MODE_NOTHING
),
position
:
{
...
...
@@ -63,22 +86,6 @@ function resetSoftinputNavBar (vm) {
}
}
let
resetTimer
let
isAndroid
let
osVersion
let
keyboardHeight
let
keyboardChangeCallback
if
(
__PLATFORM__
===
'
app-plus
'
)
{
plusReady
(()
=>
{
isAndroid
=
plus
.
os
.
name
.
toLowerCase
()
===
'
android
'
osVersion
=
plus
.
os
.
version
})
document
.
addEventListener
(
'
keyboardchange
'
,
function
(
event
)
{
keyboardHeight
=
event
.
height
keyboardChangeCallback
&&
keyboardChangeCallback
()
},
false
)
}
export
default
{
name
:
'
Keyboard
'
,
mixins
:
[
emitter
],
...
...
@@ -146,11 +153,13 @@ export default {
if
(
__PLATFORM__
===
'
app-plus
'
)
{
// 安卓单独隐藏键盘后点击输入框不会触发 focus 事件
el
.
addEventListener
(
'
click
'
,
()
=>
{
if
(
!
this
.
disabled
&&
focus
&&
keyboardHeight
===
0
)
{
setSoftinputTemporary
(
this
)
}
})
if
(
isAndroid
)
{
el
.
addEventListener
(
'
click
'
,
()
=>
{
if
(
!
this
.
disabled
&&
focus
&&
keyboardHeight
===
0
)
{
setSoftinputTemporary
(
this
)
}
})
}
if
(
!
isAndroid
&&
parseInt
(
osVersion
)
<
12
)
{
// iOS12 以下系统 focus 事件设置较迟,改在 touchstart 设置
el
.
addEventListener
(
'
touchstart
'
,
()
=>
{
...
...
src/core/view/plugins/index.js
浏览文件 @
d8e7df02
...
...
@@ -100,4 +100,4 @@ export default {
})
}
}
}
src/platforms/app-plus/service/framework/config.js
浏览文件 @
d8e7df02
...
...
@@ -76,6 +76,7 @@ export function initEntryPage () {
const
entryRoute
=
'
/
'
+
entryPagePath
const
routeOptions
=
__uniRoutes
.
find
(
route
=>
route
.
path
===
entryRoute
)
if
(
!
routeOptions
)
{
console
.
error
(
`[uni-app]
${
entryPagePath
}
not found...`
)
return
}
...
...
src/platforms/app-plus/view/framework/plugins/gesture.js
0 → 100644
浏览文件 @
d8e7df02
if
(
String
(
navigator
.
vendor
).
indexOf
(
'
Apple
'
)
===
0
)
{
let
firstEvent
let
timeout
// 用于全局禁用 iOS 双击包含手势
document
.
documentElement
.
addEventListener
(
'
click
'
,
event
=>
{
const
TIME_MAX
=
450
const
PAGE_MAX
=
44
clearTimeout
(
timeout
)
if
(
firstEvent
&&
Math
.
abs
(
event
.
pageX
-
firstEvent
.
pageX
)
<=
PAGE_MAX
&&
Math
.
abs
(
event
.
pageY
-
firstEvent
.
pageY
)
<=
PAGE_MAX
&&
event
.
timeStamp
-
firstEvent
.
timeStamp
<=
TIME_MAX
)
{
event
.
preventDefault
()
}
firstEvent
=
event
timeout
=
setTimeout
(()
=>
{
firstEvent
=
null
},
TIME_MAX
)
})
}
src/platforms/app-plus/view/framework/plugins/index.js
浏览文件 @
d8e7df02
...
...
@@ -12,6 +12,8 @@ import {
initEvent
}
from
'
./event
'
import
'
./gesture
'
export
default
{
install
(
Vue
,
options
)
{
if
(
process
.
env
.
NODE_ENV
!==
'
production
'
)
{
...
...
@@ -29,4 +31,4 @@ export default {
initEvent
(
Vue
)
}
}
}
src/platforms/h5/components/page/pageHead.vue
浏览文件 @
d8e7df02
...
...
@@ -174,7 +174,6 @@
left
:
70px
;
right
:
70px
;
min-width
:
0
;
user-select
:
auto
;
}
.uni-page-head-btn
{
...
...
src/platforms/mp-weixin/runtime/wrapper/app-base-parser.js
浏览文件 @
d8e7df02
...
...
@@ -74,11 +74,14 @@ function initScopedSlotsParams () {
}
Vue
.
prototype
.
$setScopedSlotsParams
=
function
(
name
,
value
)
{
const
vueId
=
this
.
$options
.
propsData
.
vueId
const
object
=
center
[
vueId
]
=
center
[
vueId
]
||
{}
object
[
name
]
=
value
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
()
const
vueIds
=
this
.
$options
.
propsData
.
vueId
if
(
vueIds
)
{
const
vueId
=
vueIds
.
split
(
'
,
'
)[
0
]
const
object
=
center
[
vueId
]
=
center
[
vueId
]
||
{}
object
[
name
]
=
value
if
(
parents
[
vueId
])
{
parents
[
vueId
].
$forceUpdate
()
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录