提交 08824db1 编写于 作者: Q qiang

Merge branch 'alpha'

# Conflicts:
#	docs/component/input.md
......@@ -25,7 +25,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+|
|verify-number|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}||
......@@ -38,9 +37,6 @@
- 如果遇到 value 属性设置不生效的问题参考:[组件属性设置不生效解决办法](/vue-api?id=_4-组件属性设置不生效解决办法)
- `input` 组件上有默认的 `min-height` 样式,如果 `min-height` 的值大于 `height` 的值那么 `height` 样式无效。
- H5 暂未支持动态切换,请使用 `v-if`进行整体切换。
- `verify-number`:是否对输入的字符执行输入是否有效判断判断
-`false`时:不执行输入是否有效判断,输入时会响应`input`事件,此时`event.detail = {value,valid}`,属性`valid`用来表明当前输入是否有效。
-`true`时:执行输入是否有效判断, 输入非数字字符将不会被赋值,也不会响应`input`事件。例如:`-(负号)`就是非数字字符。输入负数时,需要输入数字后再移动光标到数字最前面输入`-(负号)`
```html
<!-- 错误写法 -->
......@@ -58,9 +54,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 平台显示的键盘包含负数。|
|tel|电话输入键盘|仅App的nvue页面支持|
**注意事项**
......
......@@ -12,5 +12,5 @@
"message": "chore(release): publish %s"
}
},
"version": "2.0.0-alpha-31920210623001"
"version": "2.0.0-alpha-31920210707001"
}
{
"name": "@dcloudio/uni-app-plus-nvue",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app app-plus-nvue",
"main": "dist/index.js",
"repository": {
......
......@@ -1745,6 +1745,7 @@ function createSubpackageApp (vm) {
const app = getApp({
allowDefault: true
});
vm.$scope = app;
const globalData = app.globalData;
if (globalData) {
Object.keys(appOptions.globalData).forEach(name => {
......@@ -1759,18 +1760,18 @@ 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
}
......
......@@ -9350,6 +9350,7 @@ var serviceContext = (function () {
const entryRoute = '/' + entryPagePath;
const routeOptions = __uniRoutes.find(route => route.path === entryRoute);
if (!routeOptions) {
console.error(`[uni-app] ${entryPagePath} not found...`);
return
}
......
{
"name": "@dcloudio/uni-app-plus",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app app-plus",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-automator",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app automator",
"main": "dist/index.js",
"repository": {
......
......@@ -203,7 +203,7 @@ export default {
// #ifdef MP-TOUTIAO
let changeName
const events = this.$scope.dataset.eventOpts
const events = this.$scope.dataset.eventOpts || []
for (var i = 0; i < events.length; i++) {
const event = events[i]
if (event[0].includes('^load')) {
......@@ -410,63 +410,7 @@ export default {
complete && complete()
})
},
_execLoadData (callback, clear) {
if (this.loading) {
return
}
this.loading = true
this.errorMessage = ''
this._getExec().then((res) => {
this.loading = false
const {
data,
count
} = res.result
this._isEnded = data.length < this.pageSize
this.hasMore = !this._isEnded
const data2 = this.getone ? (data.length ? data[0] : undefined) : data
if (this.getcount) {
this.paginationInternal.count = count
}
callback && callback(data2, this._isEnded, this.paginationInternal)
this._dispatchEvent(events.load, data2)
if (this.getone || this.pageData === pageMode.replace) {
this.dataList = data2
} else {
if (clear) {
this.dataList = data2
} else {
this.dataList.push(...data2)
}
}
// #ifdef H5
if (process.env.NODE_ENV === 'development') {
this._debugDataList.length = 0
const formatData = JSON.parse(JSON.stringify(this.dataList))
if (Array.isArray(this.dataList)) {
this._debugDataList.push(...formatData)
} else {
this._debugDataList.push(formatData)
}
}
// #endif
}).catch((err) => {
this.loading = false
this.errorMessage = err
callback && callback()
this.$emit(events.error, err)
if (process.env.NODE_ENV === 'development') {
console.error(err)
}
})
},
_getExec () {
getTemp(isTemp = true) {
/* eslint-disable no-undef */
let db = uniCloud.database()
......@@ -516,10 +460,89 @@ export default {
if (this.gettreepath) {
getOptions.getTreePath = treeOptions
}
db = db.skip(size * (current - 1)).limit(size).get(getOptions)
db = db.skip(size * (current - 1)).limit(size)
if (isTemp) {
db = db.getTemp(getOptions)
db.udb = this
} else {
db = db.get(getOptions)
}
return db
},
setResult(result) {
if (result.code === 0) {
this._execLoadDataSuccess(result)
} else {
this._execLoadDataFail(new Error(result.message))
}
},
_execLoadData (callback, clear) {
if (this.loading) {
return
}
this.loading = true
this.errorMessage = ''
this._getExec().then((res) => {
this.loading = false
this._execLoadDataSuccess(res.result, callback, clear)
// #ifdef H5
if (process.env.NODE_ENV === 'development') {
this._debugDataList.length = 0
const formatData = JSON.parse(JSON.stringify(this.dataList))
if (Array.isArray(this.dataList)) {
this._debugDataList.push(...formatData)
} else {
this._debugDataList.push(formatData)
}
}
// #endif
}).catch((err) => {
this.loading = false
this._execLoadDataFail(err, callback)
})
},
_execLoadDataSuccess(result, callback, clear) {
const {
data,
count
} = result
this._isEnded = data.length < this.pageSize
this.hasMore = !this._isEnded
const data2 = this.getone ? (data.length ? data[0] : undefined) : data
if (this.getcount) {
this.paginationInternal.count = count
}
callback && callback(data2, this._isEnded, this.paginationInternal)
this._dispatchEvent(events.load, data2)
if (this.getone || this.pageData === pageMode.replace) {
this.dataList = data2
} else {
if (clear) {
this.dataList = data2
} else {
this.dataList.push(...data2)
}
}
},
_execLoadDataFail(err, callback) {
this.errorMessage = err
callback && callback()
this.$emit(events.error, err)
if (process.env.NODE_ENV === 'development') {
console.error(err)
}
},
_getExec () {
return this.getTemp(false)
},
_execRemove (id, action, success, fail, complete, needConfirm, needLoading, loadingTitle) {
if (!this.collection || !id) {
return
......
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') {
......
{
"name": "@dcloudio/uni-cli-shared",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-cli-shared",
"main": "lib/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-h5-ui",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app h5 ui",
"main": "dist/index.umd.min.js",
"repository": {
......
此差异已折叠。
{
"name": "@dcloudio/uni-h5",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app h5",
"main": "dist/index.umd.min.js",
"repository": {
......
{
"name": "@dcloudio/uni-i18n",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "@dcloudio/uni-i18n",
"main": "dist/uni-i18n.cjs.js",
"module": "dist/uni-i18n.esm.js",
......
{
"name": "@dcloudio/uni-migration",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app migration",
"main": "lib/index.js",
"repository": {
......
......@@ -2023,11 +2023,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();
}
}
};
......@@ -2723,6 +2726,7 @@ function createSubpackageApp (vm) {
const app = getApp({
allowDefault: true
});
vm.$scope = app;
const globalData = app.globalData;
if (globalData) {
Object.keys(appOptions.globalData).forEach(name => {
......@@ -2737,18 +2741,18 @@ function createSubpackageApp (vm) {
}
});
if (isFn(appOptions.onShow) && my.onAppShow) {
my.onAppShow((...args) => {
appOptions.onShow.apply(app, args);
my.onAppShow((...args) => {
vm.__call_hook('onShow', args);
});
}
if (isFn(appOptions.onHide) && my.onAppHide) {
my.onAppHide((...args) => {
appOptions.onHide.apply(app, args);
my.onAppHide((...args) => {
vm.__call_hook('onHide', args);
});
}
if (isFn(appOptions.onLaunch)) {
const args = my.getLaunchOptionsSync && my.getLaunchOptionsSync();
appOptions.onLaunch.call(app, args);
vm.__call_hook('onLaunch', args);
}
return vm
}
......
{
"name": "@dcloudio/uni-mp-alipay",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app mp-alipay",
"main": "dist/index.js",
"repository": {
......
......@@ -1710,11 +1710,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();
}
}
};
......@@ -2065,6 +2068,12 @@ function parseComponent (vueOptions) {
const oldAttached = componentOptions.lifetimes.attached;
// 百度小程序基础库 3.260 以上支持页面 onInit 生命周期,提前创建 vm 实例
componentOptions.lifetimes.onInit = function onInit (query) {
// 百度小程序后续可能移除 pageinstance 属性,为向后兼容进行补充
if (!this.pageinstance || !this.pageinstance.setData) {
const pages = getCurrentPages();
this.pageinstance = pages[pages.length - 1];
}
// 处理百度小程序 onInit 生命周期调用 setData 无效的问题
const setData = this.setData;
const setDataArgs = [];
......@@ -2228,6 +2237,7 @@ function createSubpackageApp (vm) {
const app = getApp({
allowDefault: true
});
vm.$scope = app;
const globalData = app.globalData;
if (globalData) {
Object.keys(appOptions.globalData).forEach(name => {
......@@ -2242,18 +2252,18 @@ function createSubpackageApp (vm) {
}
});
if (isFn(appOptions.onShow) && swan.onAppShow) {
swan.onAppShow((...args) => {
appOptions.onShow.apply(app, args);
swan.onAppShow((...args) => {
vm.__call_hook('onShow', args);
});
}
if (isFn(appOptions.onHide) && swan.onAppHide) {
swan.onAppHide((...args) => {
appOptions.onHide.apply(app, args);
swan.onAppHide((...args) => {
vm.__call_hook('onHide', args);
});
}
if (isFn(appOptions.onLaunch)) {
const args = swan.getLaunchOptionsSync && swan.getLaunchOptionsSync();
appOptions.onLaunch.call(app, args);
vm.__call_hook('onLaunch', args);
}
return vm
}
......
{
"name": "@dcloudio/uni-mp-baidu",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app mp-baidu",
"main": "dist/index.js",
"repository": {
......
......@@ -1459,11 +1459,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();
}
}
};
......@@ -1862,6 +1865,7 @@ function createSubpackageApp (vm) {
const app = getApp({
allowDefault: true
});
vm.$scope = app;
const globalData = app.globalData;
if (globalData) {
Object.keys(appOptions.globalData).forEach(name => {
......@@ -1876,18 +1880,18 @@ function createSubpackageApp (vm) {
}
});
if (isFn(appOptions.onShow) && ks.onAppShow) {
ks.onAppShow((...args) => {
appOptions.onShow.apply(app, args);
ks.onAppShow((...args) => {
vm.__call_hook('onShow', args);
});
}
if (isFn(appOptions.onHide) && ks.onAppHide) {
ks.onAppHide((...args) => {
appOptions.onHide.apply(app, args);
ks.onAppHide((...args) => {
vm.__call_hook('onHide', args);
});
}
if (isFn(appOptions.onLaunch)) {
const args = ks.getLaunchOptionsSync && ks.getLaunchOptionsSync();
appOptions.onLaunch.call(app, args);
vm.__call_hook('onLaunch', args);
}
return vm
}
......
{
"name": "@dcloudio/uni-mp-kuaishou",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app mp-kuaishou",
"main": "dist/index.js",
"repository": {
......
......@@ -1620,11 +1620,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();
}
}
};
......@@ -2035,6 +2038,7 @@ function createSubpackageApp (vm) {
const app = getApp({
allowDefault: true
});
vm.$scope = app;
const globalData = app.globalData;
if (globalData) {
Object.keys(appOptions.globalData).forEach(name => {
......@@ -2049,18 +2053,18 @@ 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
}
......
{
"name": "@dcloudio/uni-mp-qq",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app mp-qq",
"main": "dist/index.js",
"repository": {
......
......@@ -1712,11 +1712,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();
}
}
};
......@@ -2259,6 +2262,7 @@ function createSubpackageApp (vm) {
const app = getApp({
allowDefault: true
});
vm.$scope = app;
const globalData = app.globalData;
if (globalData) {
Object.keys(appOptions.globalData).forEach(name => {
......@@ -2273,18 +2277,18 @@ function createSubpackageApp (vm) {
}
});
if (isFn(appOptions.onShow) && tt.onAppShow) {
tt.onAppShow((...args) => {
appOptions.onShow.apply(app, args);
tt.onAppShow((...args) => {
vm.__call_hook('onShow', args);
});
}
if (isFn(appOptions.onHide) && tt.onAppHide) {
tt.onAppHide((...args) => {
appOptions.onHide.apply(app, args);
tt.onAppHide((...args) => {
vm.__call_hook('onHide', args);
});
}
if (isFn(appOptions.onLaunch)) {
const args = tt.getLaunchOptionsSync && tt.getLaunchOptionsSync();
appOptions.onLaunch.call(app, args);
vm.__call_hook('onLaunch', args);
}
return vm
}
......
{
"name": "@dcloudio/uni-mp-toutiao",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app mp-toutiao",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-mp-vue",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "@dcloudio/uni-mp-vue",
"main": "dist/vue.runtime.esm.js",
"module": "dist/vue.runtime.esm.js",
......
......@@ -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();
}
}
};
......@@ -1779,6 +1782,7 @@ function createSubpackageApp (vm) {
const app = getApp({
allowDefault: true
});
vm.$scope = app;
const globalData = app.globalData;
if (globalData) {
Object.keys(appOptions.globalData).forEach(name => {
......@@ -1793,18 +1797,18 @@ 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
}
......
{
"name": "@dcloudio/uni-mp-weixin",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app mp-weixin",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-quickapp-native",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app quickapp-native",
"main": "dist/vue.prod.js",
"repository": {
......
......@@ -1894,6 +1894,7 @@ function createSubpackageApp (vm) {
const app = getApp({
allowDefault: true
});
vm.$scope = app;
const globalData = app.globalData;
if (globalData) {
Object.keys(appOptions.globalData).forEach(name => {
......@@ -1908,18 +1909,18 @@ function createSubpackageApp (vm) {
}
});
if (isFn(appOptions.onShow) && qa.onAppShow) {
qa.onAppShow((...args) => {
appOptions.onShow.apply(app, args);
qa.onAppShow((...args) => {
vm.__call_hook('onShow', args);
});
}
if (isFn(appOptions.onHide) && qa.onAppHide) {
qa.onAppHide((...args) => {
appOptions.onHide.apply(app, args);
qa.onAppHide((...args) => {
vm.__call_hook('onHide', args);
});
}
if (isFn(appOptions.onLaunch)) {
const args = qa.getLaunchOptionsSync && qa.getLaunchOptionsSync();
appOptions.onLaunch.call(app, args);
vm.__call_hook('onLaunch', args);
}
return vm
}
......
{
"name": "@dcloudio/uni-quickapp-webview",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app quickapp-webview",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-stat",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "",
"main": "dist/index.js",
"repository": {
......
......@@ -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(
......
......@@ -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'
}
......
......@@ -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'
}
......
......@@ -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'
}
......
......@@ -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)))
)
)
}
......
......@@ -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)
......
......@@ -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
)
......
......@@ -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.cloneDeep(path.node))
properties.push(state.options.scopedSlotsCompiler === 'auto' ? path.node : t.cloneNode(path.node, true))
})
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 组件嵌套
}
......@@ -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
}
{
"name": "@dcloudio/uni-template-compiler",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-template-compiler",
"main": "lib/index.js",
"repository": {
......
{
"name": "@dcloudio/vue-cli-plugin-hbuilderx",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "HBuilderX plugin for vue-cli 3",
"main": "index.js",
"repository": {
......
{
"name": "@dcloudio/vue-cli-plugin-uni-optimize",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app optimize plugin for vue-cli 3",
"main": "index.js",
"repository": {
......
......@@ -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)
}
}
}
{
"name": "@dcloudio/vue-cli-plugin-uni",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app plugin for vue-cli 3",
"main": "index.js",
"repository": {
......@@ -17,7 +17,7 @@
"author": "fxy060608",
"license": "Apache-2.0",
"dependencies": {
"@dcloudio/uni-stat": "^2.0.0-alpha-31920210623001",
"@dcloudio/uni-stat": "^2.0.0-alpha-31920210707001",
"buffer-json": "^2.0.0",
"copy-webpack-plugin": "^5.1.1",
"cross-env": "^5.2.0",
......
......@@ -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) {
......
......@@ -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
}
......
{
"name": "@dcloudio/webpack-uni-mp-loader",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "webpack-uni-mp-loader",
"main": "index.js",
"repository": {
......
......@@ -6,6 +6,6 @@
"minified": false,
"newFeature": true
},
"appid": "体验appId",
"appid": "testAppId",
"projectname": ""
}
{
"name": "@dcloudio/webpack-uni-pages-loader",
"version": "2.0.0-alpha-31920210623001",
"version": "2.0.0-alpha-31920210707001",
"description": "uni-app pages.json loader",
"main": "lib/index.js",
"repository": {
......@@ -21,7 +21,7 @@
"strip-json-comments": "^2.0.1"
},
"uni-app": {
"compilerVersion": "3.1.19"
"compilerVersion": "3.1.22"
},
"gitHead": "2033cd540cff5d8469ff77e87779cd4daa5c9121"
}
......@@ -12,6 +12,7 @@ export default function createSubpackageApp (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
}
}
......@@ -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.width
const width = $el.offsetWidth
if (width) {
$el.style.height = fixNumber(width / this.ratio) + 'px'
}
} else if (this.mode === 'heightFix') {
const height = rect.height
const height = $el.offsetHeight
if (height) {
$el.style.width = fixNumber(height * this.ratio) + 'px'
}
......
<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') {
......
......@@ -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 {
......
......@@ -148,7 +148,9 @@ export default {
this._field = el
startTime = startTime || Date.now()
if (this.needFocus) {
this._focus()
setTimeout(() => {
this._focus()
})
}
},
_focus () {
......
......@@ -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', () => {
......
......@@ -100,4 +100,4 @@ export default {
})
}
}
}
......@@ -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
}
......
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)
})
}
......@@ -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)
}
}
}
......@@ -174,7 +174,6 @@
left: 70px;
right: 70px;
min-width: 0;
user-select: auto;
}
.uni-page-head-btn {
......
......@@ -32,6 +32,12 @@ export default function parseComponent (vueOptions) {
const oldAttached = componentOptions.lifetimes.attached
// 百度小程序基础库 3.260 以上支持页面 onInit 生命周期,提前创建 vm 实例
componentOptions.lifetimes.onInit = function onInit (query) {
// 百度小程序后续可能移除 pageinstance 属性,为向后兼容进行补充
if (!this.pageinstance || !this.pageinstance.setData) {
const pages = getCurrentPages()
this.pageinstance = pages[pages.length - 1]
}
// 处理百度小程序 onInit 生命周期调用 setData 无效的问题
const setData = this.setData
const setDataArgs = []
......
......@@ -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.
先完成此消息的编辑!
想要评论请 注册