diff --git a/build/rollup.config.js b/build/rollup.config.js index 94e782a9fcffef928385b485c8cdd1971b224f35..f261bbc7c2560b53675382387cf8703df9cac3c4 100644 --- a/build/rollup.config.js +++ b/build/rollup.config.js @@ -41,6 +41,7 @@ module.exports = { replace({ __GLOBAL__: platform.prefix, __PLATFORM_TITLE__: platform.title, + __PLATFORM_PREFIX__: JSON.stringify(platform.prefix), __PLATFORM__: JSON.stringify(process.env.UNI_PLATFORM) }) ], diff --git a/package.json b/package.json index 0e017e0ff76bc1a3ffb359e0e795924e42f03869..9ab868b0b30c6c48338886e9570cbdb83615e79d 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,8 @@ "__PLATFORM__": true, "__VERSION__": true, "__GLOBAL__": true, - "__PLATFORM_TITLE__": true + "__PLATFORM_TITLE__": true, + "__PLATFORM_PREFIX__":true }, "rules": { "no-tabs": 0, diff --git a/packages/uni-app-plus/dist/index.js b/packages/uni-app-plus/dist/index.js index b463c38d3c655c0dec3e7f890acf604d547832c8..1fe07d7a8f173e33b479fb557695fc1c56dc4e88 100644 --- a/packages/uni-app-plus/dist/index.js +++ b/packages/uni-app-plus/dist/index.js @@ -402,8 +402,32 @@ function createObserver (name) { } } -function getBehaviors (vueExtends, vueMixins) { +function getBehaviors (vueOptions) { + const vueBehaviors = vueOptions['behaviors']; + const vueExtends = vueOptions['extends']; + const vueMixins = vueOptions['mixins']; + + let vueProps = vueOptions['props']; + + if (!vueProps) { + vueOptions['props'] = vueProps = []; + } + const behaviors = []; + if (Array.isArray(vueBehaviors)) { + vueBehaviors.forEach(behavior => { + behaviors.push(behavior.replace('uni://', `${"wx"}://`)); + if (behavior === 'uni://form-field') { + if (Array.isArray(vueProps)) { + vueProps.push('name'); + vueProps.push('value'); + } else { + vueProps['name'] = String; + vueProps['value'] = null; + } + } + }); + } if (isPlainObject(vueExtends) && vueExtends.props) { behaviors.push( Behavior({ @@ -486,6 +510,11 @@ function getProperties (props, isBehavior = false, file = '') { } function wrapper$1 (event) { + // TODO 又得兼容 mpvue 的 mp 对象 + try { + event.mp = JSON.parse(JSON.stringify(event)); + } catch (e) {} + event.stopPropagation = noop; event.preventDefault = noop; @@ -495,9 +524,6 @@ function wrapper$1 (event) { event.detail = {}; } - // TODO 又得兼容 mpvue 的 mp 对象 - event.mp = event; - if (isPlainObject(event.detail)) { event.target = Object.assign({}, event.target, event.detail); } @@ -887,9 +913,9 @@ function initVm$2 (VueComponent) { function createComponent (vueOptions) { vueOptions = vueOptions.default || vueOptions; - const properties = getProperties(vueOptions.props, false, vueOptions.__file); + const behaviors = getBehaviors(vueOptions); - const behaviors = getBehaviors(vueOptions['extends'], vueOptions['mixins']); + const properties = getProperties(vueOptions.props, false, vueOptions.__file); const VueComponent = Vue.extend(vueOptions); diff --git a/packages/uni-app-plus/package.json b/packages/uni-app-plus/package.json index d472d910627a6d3be1e6c2530613f84fcd87db33..50ba1b2b20f0864a2d7e400d35509dbbf2ea0180 100644 --- a/packages/uni-app-plus/package.json +++ b/packages/uni-app-plus/package.json @@ -1,6 +1,6 @@ { "name": "@dcloudio/uni-app-plus", - "version": "0.0.227", + "version": "0.0.228", "description": "uni-app app-plus", "main": "dist/index.js", "scripts": { diff --git a/packages/uni-mp-baidu/dist/index.js b/packages/uni-mp-baidu/dist/index.js index b185b9411518bdc9ed8a5c06f9e64879dabfcbd5..a981de4e9d253950ae3fec8d7ead67f7d0e16fb8 100644 --- a/packages/uni-mp-baidu/dist/index.js +++ b/packages/uni-mp-baidu/dist/index.js @@ -535,8 +535,32 @@ function createObserver (name) { } } -function getBehaviors (vueExtends, vueMixins) { +function getBehaviors (vueOptions) { + const vueBehaviors = vueOptions['behaviors']; + const vueExtends = vueOptions['extends']; + const vueMixins = vueOptions['mixins']; + + let vueProps = vueOptions['props']; + + if (!vueProps) { + vueOptions['props'] = vueProps = []; + } + const behaviors = []; + if (Array.isArray(vueBehaviors)) { + vueBehaviors.forEach(behavior => { + behaviors.push(behavior.replace('uni://', `${"swan"}://`)); + if (behavior === 'uni://form-field') { + if (Array.isArray(vueProps)) { + vueProps.push('name'); + vueProps.push('value'); + } else { + vueProps['name'] = String; + vueProps['value'] = null; + } + } + }); + } if (isPlainObject(vueExtends) && vueExtends.props) { behaviors.push( Behavior({ @@ -635,6 +659,11 @@ function getProperties (props, isBehavior = false, file = '') { } function wrapper$1 (event) { + // TODO 又得兼容 mpvue 的 mp 对象 + try { + event.mp = JSON.parse(JSON.stringify(event)); + } catch (e) {} + event.stopPropagation = noop; event.preventDefault = noop; @@ -654,9 +683,6 @@ function wrapper$1 (event) { } } - // TODO 又得兼容 mpvue 的 mp 对象 - event.mp = event; - if (isPlainObject(event.detail)) { event.target = Object.assign({}, event.target, event.detail); } @@ -1070,9 +1096,9 @@ function initVm$2 (VueComponent) { function createComponent (vueOptions) { vueOptions = vueOptions.default || vueOptions; - const properties = getProperties(vueOptions.props, false, vueOptions.__file); + const behaviors = getBehaviors(vueOptions); - const behaviors = getBehaviors(vueOptions['extends'], vueOptions['mixins']); + const properties = getProperties(vueOptions.props, false, vueOptions.__file); const VueComponent = Vue.extend(vueOptions); diff --git a/packages/uni-mp-baidu/package.json b/packages/uni-mp-baidu/package.json index 2f95943b316cd7c10f9c4337a396a2d3cd6ff320..fd9ce10f1a3eeedf0c945321f2e1de4e7a721309 100644 --- a/packages/uni-mp-baidu/package.json +++ b/packages/uni-mp-baidu/package.json @@ -1,6 +1,6 @@ { "name": "@dcloudio/uni-mp-baidu", - "version": "0.0.824", + "version": "0.0.825", "description": "uni-app mp-baidu", "main": "dist/index.js", "scripts": { diff --git a/packages/uni-mp-toutiao/dist/index.js b/packages/uni-mp-toutiao/dist/index.js index 32ce4f37554d2c300d8ea44e0e6d52ab1d6063ce..7db66e24c8825882952e10ff52ef8dfeeb27ddc1 100644 --- a/packages/uni-mp-toutiao/dist/index.js +++ b/packages/uni-mp-toutiao/dist/index.js @@ -619,8 +619,32 @@ function createObserver (name) { } } -function getBehaviors (vueExtends, vueMixins) { +function getBehaviors (vueOptions) { + const vueBehaviors = vueOptions['behaviors']; + const vueExtends = vueOptions['extends']; + const vueMixins = vueOptions['mixins']; + + let vueProps = vueOptions['props']; + + if (!vueProps) { + vueOptions['props'] = vueProps = []; + } + const behaviors = []; + if (Array.isArray(vueBehaviors)) { + vueBehaviors.forEach(behavior => { + behaviors.push(behavior.replace('uni://', `${"tt"}://`)); + if (behavior === 'uni://form-field') { + if (Array.isArray(vueProps)) { + vueProps.push('name'); + vueProps.push('value'); + } else { + vueProps['name'] = String; + vueProps['value'] = null; + } + } + }); + } if (isPlainObject(vueExtends) && vueExtends.props) { behaviors.push( Behavior({ @@ -703,6 +727,11 @@ function getProperties (props, isBehavior = false, file = '') { } function wrapper$1 (event) { + // TODO 又得兼容 mpvue 的 mp 对象 + try { + event.mp = JSON.parse(JSON.stringify(event)); + } catch (e) {} + event.stopPropagation = noop; event.preventDefault = noop; @@ -712,9 +741,6 @@ function wrapper$1 (event) { event.detail = {}; } - // TODO 又得兼容 mpvue 的 mp 对象 - event.mp = event; - if (isPlainObject(event.detail)) { event.target = Object.assign({}, event.target, event.detail); } @@ -1078,9 +1104,9 @@ function initVm$2 (VueComponent) { function createComponent (vueOptions) { vueOptions = vueOptions.default || vueOptions; - const properties = getProperties(vueOptions.props, false, vueOptions.__file); + const behaviors = getBehaviors(vueOptions); - const behaviors = getBehaviors(vueOptions['extends'], vueOptions['mixins']); + const properties = getProperties(vueOptions.props, false, vueOptions.__file); const VueComponent = Vue.extend(vueOptions); diff --git a/packages/uni-mp-toutiao/package.json b/packages/uni-mp-toutiao/package.json index 47f0c2aa29c25f0d27f1c513ec8e70e8004ffb39..b9a406ffff794e6ea1eca24d3b0356db3323ecff 100644 --- a/packages/uni-mp-toutiao/package.json +++ b/packages/uni-mp-toutiao/package.json @@ -1,6 +1,6 @@ { "name": "@dcloudio/uni-mp-toutiao", - "version": "0.0.322", + "version": "0.0.323", "description": "uni-app mp-toutiao", "main": "dist/index.js", "scripts": { diff --git a/packages/uni-mp-weixin/dist/index.js b/packages/uni-mp-weixin/dist/index.js index daf672760b136c1d369579b4aa52f66a1ae10293..cc49efb8b2919fb56893e2e36cbd94650f50e398 100644 --- a/packages/uni-mp-weixin/dist/index.js +++ b/packages/uni-mp-weixin/dist/index.js @@ -419,8 +419,32 @@ function createObserver (name) { } } -function getBehaviors (vueExtends, vueMixins) { +function getBehaviors (vueOptions) { + const vueBehaviors = vueOptions['behaviors']; + const vueExtends = vueOptions['extends']; + const vueMixins = vueOptions['mixins']; + + let vueProps = vueOptions['props']; + + if (!vueProps) { + vueOptions['props'] = vueProps = []; + } + const behaviors = []; + if (Array.isArray(vueBehaviors)) { + vueBehaviors.forEach(behavior => { + behaviors.push(behavior.replace('uni://', `${"wx"}://`)); + if (behavior === 'uni://form-field') { + if (Array.isArray(vueProps)) { + vueProps.push('name'); + vueProps.push('value'); + } else { + vueProps['name'] = String; + vueProps['value'] = null; + } + } + }); + } if (isPlainObject(vueExtends) && vueExtends.props) { behaviors.push( Behavior({ @@ -503,6 +527,11 @@ function getProperties (props, isBehavior = false, file = '') { } function wrapper$1 (event) { + // TODO 又得兼容 mpvue 的 mp 对象 + try { + event.mp = JSON.parse(JSON.stringify(event)); + } catch (e) {} + event.stopPropagation = noop; event.preventDefault = noop; @@ -512,9 +541,6 @@ function wrapper$1 (event) { event.detail = {}; } - // TODO 又得兼容 mpvue 的 mp 对象 - event.mp = event; - if (isPlainObject(event.detail)) { event.target = Object.assign({}, event.target, event.detail); } @@ -907,9 +933,9 @@ function initVm$2 (VueComponent) { function createComponent (vueOptions) { vueOptions = vueOptions.default || vueOptions; - const properties = getProperties(vueOptions.props, false, vueOptions.__file); + const behaviors = getBehaviors(vueOptions); - const behaviors = getBehaviors(vueOptions['extends'], vueOptions['mixins']); + const properties = getProperties(vueOptions.props, false, vueOptions.__file); const VueComponent = Vue.extend(vueOptions); diff --git a/packages/uni-mp-weixin/package.json b/packages/uni-mp-weixin/package.json index a3a35705581be8c306bef2c17f6421783c01191b..4f2cdbc02063224bc661043e94556b56e3114339 100644 --- a/packages/uni-mp-weixin/package.json +++ b/packages/uni-mp-weixin/package.json @@ -1,6 +1,6 @@ { "name": "@dcloudio/uni-mp-weixin", - "version": "0.0.946", + "version": "0.0.947", "description": "uni-app mp-weixin", "main": "dist/index.js", "scripts": { diff --git a/src/core/runtime/wrapper/create-component.js b/src/core/runtime/wrapper/create-component.js index d492e0169660c497ab0021bc6401fe66b764f52d..f987c017784c4fe2ad652bb8e7c98e179246415b 100644 --- a/src/core/runtime/wrapper/create-component.js +++ b/src/core/runtime/wrapper/create-component.js @@ -43,9 +43,9 @@ function initVm (VueComponent) { export function createComponent (vueOptions) { vueOptions = vueOptions.default || vueOptions - const properties = getProperties(vueOptions.props, false, vueOptions.__file) + const behaviors = getBehaviors(vueOptions) - const behaviors = getBehaviors(vueOptions['extends'], vueOptions['mixins']) + const properties = getProperties(vueOptions.props, false, vueOptions.__file) const VueComponent = Vue.extend(vueOptions) diff --git a/src/core/runtime/wrapper/util.js b/src/core/runtime/wrapper/util.js index 3287d4e50cf55deb0d487e5e7db5723c7f3ebfe4..e08c4cf68cf3fd3c8d40bf4e1abc000ae1ce5444 100644 --- a/src/core/runtime/wrapper/util.js +++ b/src/core/runtime/wrapper/util.js @@ -64,8 +64,32 @@ function createObserver (name) { } } -export function getBehaviors (vueExtends, vueMixins) { +export function getBehaviors (vueOptions) { + const vueBehaviors = vueOptions['behaviors'] + const vueExtends = vueOptions['extends'] + const vueMixins = vueOptions['mixins'] + + let vueProps = vueOptions['props'] + + if (!vueProps) { + vueOptions['props'] = vueProps = [] + } + const behaviors = [] + if (Array.isArray(vueBehaviors)) { + vueBehaviors.forEach(behavior => { + behaviors.push(behavior.replace('uni://', `${__PLATFORM_PREFIX__}://`)) + if (behavior === 'uni://form-field') { + if (Array.isArray(vueProps)) { + vueProps.push('name') + vueProps.push('value') + } else { + vueProps['name'] = String + vueProps['value'] = null + } + } + }) + } if (isPlainObject(vueExtends) && vueExtends.props) { behaviors.push( Behavior({ @@ -164,6 +188,11 @@ export function getProperties (props, isBehavior = false, file = '') { } function wrapper (event) { + // TODO 又得兼容 mpvue 的 mp 对象 + try { + event.mp = JSON.parse(JSON.stringify(event)) + } catch (e) {} + event.stopPropagation = noop event.preventDefault = noop @@ -183,9 +212,6 @@ function wrapper (event) { } } - // TODO 又得兼容 mpvue 的 mp 对象 - event.mp = event - if (isPlainObject(event.detail)) { event.target = Object.assign({}, event.target, event.detail) } diff --git a/src/core/view/plugins/behaviors/form-field.js b/src/core/view/plugins/behaviors/form-field.js new file mode 100644 index 0000000000000000000000000000000000000000..56548ab864dcddaaf2930fd2ea7a77e6ce198112 --- /dev/null +++ b/src/core/view/plugins/behaviors/form-field.js @@ -0,0 +1,103 @@ +/** + * uni://form-field + */ +import { + hasOwn +} from 'uni-shared' + +import { + emitter +} from 'uni-mixins' + +function created () { + this.$dispatch('Form', 'uni-form-group-update', { + type: 'add', + vm: this + }) +} + +function beforeDestroy () { + this.$dispatch('Form', 'uni-form-group-update', { + type: 'remove', + vm: this + }) +} + +export default { + name: 'uni://form-field', + init (options, vm) { + if ( + !vm.constructor.options.props.name || + !vm.constructor.options.props.value + ) { // 未初始化 props + if (!vm.constructor.options.props.name) { + vm.constructor.options.props.name = options.props.name = { + type: String + } + } + if (!vm.constructor.options.props.value) { + vm.constructor.options.props.value = options.props.value = { + type: null + } + } + } + + if (!options.propsData) { + options.propsData = {} + } + + const $vnode = vm.$vnode + if ($vnode && $vnode.data && $vnode.data.attrs) { + if (hasOwn($vnode.data.attrs, 'name')) { + options.propsData.name = $vnode.data.attrs.name + } + if (hasOwn($vnode.data.attrs, 'value')) { + options.propsData.value = $vnode.data.attrs.value + } + } + + if ( + !vm.constructor.options.methods || + !vm.constructor.options.methods._getFormData + ) { // 未初始化 methods + if (!vm.constructor.options.methods) { + vm.constructor.options.methods = {} + } + + if (!options.methods) { + options.methods = {} + } + + const formMethods = { + _getFormData () { + return this.name ? { + key: this.name, + value: this.value + } : {} + }, + _resetFormData () { + this.value = '' + } + } + + Object.assign(vm.constructor.options.methods, formMethods) + Object.assign(options.methods, formMethods) + + // add $dispatch + Object.assign(vm.constructor.options.methods, emitter.methods) + Object.assign(options.methods, emitter.methods) + + const createdHooks = options['created'] + vm.constructor.options['created'] = options['created'] = + createdHooks ? [].concat(created, createdHooks) : [ + created + ] + + const beforeDestroyHooks = options['beforeDestroy'] + vm.constructor.options['beforeDestroy'] = options['beforeDestroy'] = + beforeDestroyHooks ? [].concat(beforeDestroy, beforeDestroyHooks) : [ + beforeDestroy + ] + } + } +} diff --git a/src/core/view/plugins/behaviors/index.js b/src/core/view/plugins/behaviors/index.js new file mode 100644 index 0000000000000000000000000000000000000000..fa1a4265f3747b059e02cda71b161607b7886117 --- /dev/null +++ b/src/core/view/plugins/behaviors/index.js @@ -0,0 +1,12 @@ +import formField from './form-field' + +const behaviors = { + [formField.name]: formField +} + +export default function initBehaviors (options, vm) { + options.behaviors.forEach(name => { + const behavior = behaviors[name] + behavior && behavior.init(options, vm) + }) +} diff --git a/src/core/view/plugins/index.js b/src/core/view/plugins/index.js index 643d1f08d4fe8455f1dcb19fc1a8a0795ef3f0c6..f0e0dccf0c210be9d3fe109fc77a880181ecbb25 100644 --- a/src/core/view/plugins/index.js +++ b/src/core/view/plugins/index.js @@ -7,6 +7,8 @@ import { processEvent } from './events' +import initBehaviors from './behaviors' + function pageMounted () { // 通知 Service,View 层已 ready UniViewJSBridge.publishHandler('onPageReady', {}, this.$page.id) @@ -34,13 +36,18 @@ export default { } } $event = processEvent.call(this, $event.type, $event, {}, target || $event.target, $event.currentTarget) - } + } return $event } Vue.mixin({ beforeCreate () { const options = this.$options + + if (options.behaviors && options.behaviors.length) { + initBehaviors(options, this) + } + if (isPage(this)) { options.mounted = options.mounted ? [].concat(pageMounted, options.mounted) : [pageMounted] }