From 89208a284e9882dcd0f5a33d41a4d2bf9227851d Mon Sep 17 00:00:00 2001 From: qiang Date: Tue, 18 Jan 2022 16:49:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(mp-alipay):=20=E6=94=AF=E4=BB=98=E5=AE=9D?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=8F=92=E4=BB=B6=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81=E4=BA=8B=E4=BB=B6=E7=9B=91?= =?UTF-8?q?=E5=90=AC=20#2410?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__tests__/compiler-mp-alipay.spec.js | 2 +- .../uni-template-compiler/lib/constants.js | 2 + .../lib/script/traverse/data/index.js | 71 ++++++++++++++++++- .../lib/script/traverse/visitor.js | 3 +- .../lib/plugin/generate-component.js | 36 ++++++++++ .../lib/plugin/generate-json.js | 8 +++ .../runtime/wrapper/component-parser.js | 20 +++--- .../mp-alipay/runtime/wrapper/page-parser.js | 2 + .../mp-alipay/runtime/wrapper/util.js | 18 ++++- 9 files changed, 148 insertions(+), 14 deletions(-) diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js index 72e063b39..47a77a431 100644 --- a/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js +++ b/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js @@ -56,7 +56,7 @@ describe('mp:compiler-mp-alipay', () => { ) assertCodegen( 'text', - 'text', + 'text', undefined, undefined, { diff --git a/packages/uni-template-compiler/lib/constants.js b/packages/uni-template-compiler/lib/constants.js index 9cd51b9c6..8d35520f7 100644 --- a/packages/uni-template-compiler/lib/constants.js +++ b/packages/uni-template-compiler/lib/constants.js @@ -28,6 +28,7 @@ const INTERNAL_GET_EVENT = '__get_event' const INTERNAL_GET_REFS = '__get_refs' const INTERNAL_EVENT_PROXY = '__e' const INTERNAL_EVENT_LINK = '__l' +const INTERNAL_EVENT_WRAP = '__w' const ALLOWED_GLOBAL_OBJECT = [ 'Math', @@ -72,6 +73,7 @@ module.exports = { INTERNAL_GET_REFS, INTERNAL_EVENT_PROXY, INTERNAL_EVENT_LINK, + INTERNAL_EVENT_WRAP, INTERNAL_SET_MODEL, INTERNAL_SET_SYNC, METHOD_BUILT_IN: [ diff --git a/packages/uni-template-compiler/lib/script/traverse/data/index.js b/packages/uni-template-compiler/lib/script/traverse/data/index.js index 16996f7bf..1f78c491f 100644 --- a/packages/uni-template-compiler/lib/script/traverse/data/index.js +++ b/packages/uni-template-compiler/lib/script/traverse/data/index.js @@ -1,8 +1,13 @@ const t = require('@babel/types') const { + METHOD_CREATE_ELEMENT, + ATTR_DATA_EVENT_OPTS, ATTR_DATA_COM_TYPE, - ATTR_DATA_EVENT_LIST + ATTR_DATA_EVENT_LIST, + ATTR_DATA_EVENT_PARAMS, + ATTE_DATA_CUSTOM_HIDDEN, + INTERNAL_EVENT_WRAP } = require('../../../constants') const processRef = require('./ref') @@ -38,7 +43,8 @@ module.exports = function traverseData (path, state, tagName) { }) // 该组件是引入的小程序组件 - if (state.options.wxComponents[tagName]) { + const wxComponent = state.options.wxComponents[tagName] + if (wxComponent) { addAttrProperties.push( t.objectProperty( t.stringLiteral(ATTR_DATA_COM_TYPE), @@ -66,6 +72,67 @@ module.exports = function traverseData (path, state, tagName) { t.stringLiteral(list.join(',')) ) ) + if (wxComponent.startsWith('plugin://')) { + const wrapperTag = 'plugin-wrapper' + const orgPath = path.parentPath + const orgNode = orgPath.node + const args = orgNode.arguments + const orgTag = args[0] + orgTag.$mpPlugin = true + args[0] = t.stringLiteral(wrapperTag) + const orgOptions = args[1] + const orgOptionsProps = orgOptions.properties + const targetAttrs = [] + const targetOptionsProps = [ + t.objectProperty(t.identifier('attrs'), t.objectExpression(targetAttrs)) + ] + const uniAttrs = [ + ATTR_DATA_EVENT_OPTS, + ATTR_DATA_COM_TYPE, + ATTR_DATA_EVENT_PARAMS, + ATTR_DATA_EVENT_LIST, + ATTE_DATA_CUSTOM_HIDDEN, + 'vue-id' + ] + for (let a = orgOptionsProps.length - 1; a >= 0; a--) { + const prop = orgOptionsProps[a] + if (prop.key.name === 'attrs') { + const attrs = prop.value.properties + for (let b = attrs.length - 1; b >= 0; b--) { + const element = attrs[b] + const key = element.key.value + if (!uniAttrs.includes(key)) { + attrs.splice(b, 1) + targetAttrs.push(element) + } + } + attrs.push(t.objectProperty(t.stringLiteral('onPluginWrap'), t.stringLiteral(INTERNAL_EVENT_WRAP))) + } else if (prop.key.name === 'on') { + const ons = prop.value.properties + ons.forEach(item => { + const attrs = path.node.properties.find(prop => prop.key.name === 'attrs').value.properties + const vueId = attrs.find(prop => prop.key.value === 'vue-id').value + const eventName = item.key.value + targetAttrs.push(t.objectProperty(t.stringLiteral(eventName), t.binaryExpression('+', t.stringLiteral(eventName), vueId))) + }) + } else { + orgOptionsProps.splice(a, 1) + targetOptionsProps.push(prop) + } + } + const orgChild = args[2] + const targetOptions = t.objectExpression(targetOptionsProps) + targetOptions.$mpProcessed = true + const targetArguments = [ + orgTag, + targetOptions + ] + if (orgChild) { + targetArguments.push(orgChild) + } + const targetNode = t.callExpression(t.identifier(METHOD_CREATE_ELEMENT), targetArguments) + args[2] = targetNode + } } } diff --git a/packages/uni-template-compiler/lib/script/traverse/visitor.js b/packages/uni-template-compiler/lib/script/traverse/visitor.js index 572149fe7..bec219549 100644 --- a/packages/uni-template-compiler/lib/script/traverse/visitor.js +++ b/packages/uni-template-compiler/lib/script/traverse/visitor.js @@ -167,7 +167,8 @@ module.exports = { tagNode.value = getComponentName(hyphenate(tagName)) // 组件增加 vueId - if (this.options.platform.isComponent(tagNode.value)) { + // 跳过支付宝插件组件 + if (this.options.platform.isComponent(tagNode.value) && !tagNode.$mpPlugin) { addVueId(path, this) } diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js index e52a14a74..73fcbaa03 100644 --- a/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js @@ -236,6 +236,42 @@ module.exports = function generateComponent (compilation, jsonpFunction = 'webpa }) } } + // fix mp-alipay plugin + if (process.env.UNI_PLATFORM === 'mp-alipay' && appJsonFile) { + const obj = JSON.parse(appJsonFile.source()) + if (obj && obj.usingComponents && !Object.keys(obj.usingComponents).length) { + const componentName = 'plugin-wrapper' + obj.usingComponents[componentName] = `/${componentName}` + const source = JSON.stringify(obj, null, 2) + appJsonFile.source = function () { + return source + } + const files = [ + { + ext: 'axml', + source: '' + }, + { + ext: 'js', + source: 'Component({onInit(){this.props.onPluginWrap(this)},didUnmount(){this.props.onPluginWrap(this,false)}})' + }, + { + ext: 'json', + source: '{"component":true}' + } + ] + files.forEach(({ ext, source }) => { + compilation.assets[`${componentName}.${ext}`] = { + size () { + return Buffer.byteLength(source, 'utf8') + }, + source () { + return source + } + } + }) + } + } if (process.env.UNI_FEATURE_OBSOLETE !== 'false') { if (lastComponents.length) { for (const name of lastComponents) { diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js index 493b6f477..2fe7b1acd 100644 --- a/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js @@ -154,6 +154,14 @@ module.exports = function generateJson (compilation) { } }) } + // fix mp-alipay plugin + if (process.env.UNI_PLATFORM === 'mp-alipay') { + const usingComponents = jsonObj.usingComponents || {} + if (Object.values(usingComponents).find(value => value.startsWith('plugin://'))) { + const componentName = 'plugin-wrapper' + usingComponents[componentName] = '/' + componentName + } + } if (jsonObj.genericComponents && jsonObj.genericComponents.length) { // scoped slots // 生成genericComponents json diff --git a/src/platforms/mp-alipay/runtime/wrapper/component-parser.js b/src/platforms/mp-alipay/runtime/wrapper/component-parser.js index 3bb329d01..5dc4c94cf 100644 --- a/src/platforms/mp-alipay/runtime/wrapper/component-parser.js +++ b/src/platforms/mp-alipay/runtime/wrapper/component-parser.js @@ -12,6 +12,7 @@ import { import { handleRef, handleLink, + handleWrap, initBehavior, initRelation, triggerEvent, @@ -115,6 +116,7 @@ export default function parseComponent (vueComponentOptions) { __r: handleRef, __e: handleEvent, __l: handleLink, + __w: handleWrap, triggerEvent } } @@ -126,15 +128,15 @@ export default function parseComponent (vueComponentOptions) { componentOptions.deriveDataFromProps = createObserver() } else { componentOptions.didUpdate = createObserver(true) - } - - if (Array.isArray(vueOptions.wxsCallMethods)) { - vueOptions.wxsCallMethods.forEach(callMethod => { - componentOptions.methods[callMethod] = function (args) { - return this.$vm[callMethod](args) - } - }) + } + + if (Array.isArray(vueOptions.wxsCallMethods)) { + vueOptions.wxsCallMethods.forEach(callMethod => { + componentOptions.methods[callMethod] = function (args) { + return this.$vm[callMethod](args) + } + }) } return componentOptions -} +} diff --git a/src/platforms/mp-alipay/runtime/wrapper/page-parser.js b/src/platforms/mp-alipay/runtime/wrapper/page-parser.js index 500bdff6e..756a6534f 100644 --- a/src/platforms/mp-alipay/runtime/wrapper/page-parser.js +++ b/src/platforms/mp-alipay/runtime/wrapper/page-parser.js @@ -16,6 +16,7 @@ import { import { handleRef, handleLink, + handleWrap, initBehavior, triggerEvent, initChildVues, @@ -87,6 +88,7 @@ export default function parsePage (vuePageOptions) { __r: handleRef, __e: handleEvent, __l: handleLink, + __w: handleWrap, triggerEvent } diff --git a/src/platforms/mp-alipay/runtime/wrapper/util.js b/src/platforms/mp-alipay/runtime/wrapper/util.js index cae35cd61..bfa4757f4 100644 --- a/src/platforms/mp-alipay/runtime/wrapper/util.js +++ b/src/platforms/mp-alipay/runtime/wrapper/util.js @@ -115,7 +115,7 @@ export function handleRef (ref) { if (ref.props['data-com-type'] === 'wx') { const eventProps = {} let refProps = ref.props - let eventList = refProps['data-event-list'].split(',') + const eventList = refProps['data-event-list'].split(',') // 初始化支付宝小程序组件事件 Object.keys(refProps).forEach(key => { if (eventList.includes(key)) { @@ -220,3 +220,19 @@ export const handleLink = (function () { (this._$childVues || (this._$childVues = [])).unshift(detail) } })() + +export const handleWrap = function (mp, destory) { + const vueId = mp.props.vueId + const list = mp.props['data-event-list'].split(',') + list.forEach(eventName => { + const key = `${eventName}${vueId}` + if (destory) { + delete this[key] + } else { + // TODO remove handleRef + this[key] = function () { + mp.props[eventName].apply(this, arguments) + } + } + }) +} -- GitLab