diff --git a/packages/uni-cli-shared/lib/nvue.css b/packages/uni-cli-shared/lib/nvue.css
index 57cd934c499cfbc9ec6c6e30e2bcfcdea715dbbe..b0e67664d45a85f785ad4849a8b7668195626fef 100644
--- a/packages/uni-cli-shared/lib/nvue.css
+++ b/packages/uni-cli-shared/lib/nvue.css
@@ -1,31 +1 @@
-view,
-label,
-swiper-item,
-scroll-view {
- display: flex;
- flex-direction: column;
- flex-shrink: 0;
- flex-grow: 0;
- flex-basis: auto;
- align-items: stretch;
- align-content: flex-start;
-}
-view,
-image,
-input,
-scroll-view,
-swiper,
-swiper-item,
-text,
-textarea,
-video {
- position: relative;
- border: 0px solid #000000;
- box-sizing: border-box;
-}
-swiper-item {
- position: absolute;
-}
-button {
- margin: 0;
-}
+label,scroll-view,swiper-item,view{display:flex;flex-direction:column;flex-shrink:0;flex-grow:0;flex-basis:auto;align-items:stretch;align-content:flex-start}image,input,scroll-view,swiper,swiper-item,text,textarea,video,view{position:relative;border:0 solid #000;box-sizing:border-box}swiper-item{position:absolute}button{margin:0}
\ No newline at end of file
diff --git a/packages/uni-mp-compiler/__tests__/scope.spec.ts b/packages/uni-mp-compiler/__tests__/scope.spec.ts
index 7fe5343de7473ce1b714f1a3edfc92ada6fc59bb..8cf56b7fe21f34f279cb72c7d77f64452289fa40 100644
--- a/packages/uni-mp-compiler/__tests__/scope.spec.ts
+++ b/packages/uni-mp-compiler/__tests__/scope.spec.ts
@@ -38,7 +38,7 @@ describe('compiler: scope', () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _vFor(_ctx.items, (item, k0, i0) => { return { ...(true ? { a: _ctx.id } : {}) }; }) }
+ return { a: _vFor(_ctx.items, (item, k0, i0) => { return true ? { a: _ctx.id } : {}; }) }
}`
)
})
@@ -47,7 +47,7 @@ describe('compiler: scope', () => {
`{{ok}}{{ok1}}{{ok2}}{{ok3}}`,
`{{b}}{{d}}{{f}}{{g}}`,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? { b: _toDisplayString(_ctx.ok) } : _ctx.ok1 ? { d: _toDisplayString(_ctx.ok1) } : _ctx.ok2 ? { f: _toDisplayString(_ctx.ok2) } : { g: _toDisplayString(_ctx.ok3) }), c: _ctx.ok1, e: _ctx.ok2 }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? { b: _toDisplayString(_ctx.ok) } : _ctx.ok1 ? { d: _toDisplayString(_ctx.ok1) } : _ctx.ok2 ? { f: _toDisplayString(_ctx.ok2) } : { g: _toDisplayString(_ctx.ok3) }, { c: _ctx.ok1, e: _ctx.ok2 })
}`
)
})
@@ -56,7 +56,7 @@ describe('compiler: scope', () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? { b: _vFor(_ctx.items, (item, k0, i0) => { return { a: item.id, b: item.title }; }), c: _ctx.foo, d: _vOn(_ctx.onClick) } : _ctx.ok1 ? { f: _vFor(_ctx.items, (item, k0, i0) => { return { a: item.id, b: item.title }; }), g: _ctx.foo, h: _vOn(_ctx.onClick) } : { i: _vFor(_ctx.items, (item, k0, i0) => { return { a: item.id, b: item.title }; }), j: _ctx.foo, k: _vOn(_ctx.onClick) }), e: _ctx.ok1 }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? { b: _vFor(_ctx.items, (item, k0, i0) => { return { a: item.id, b: item.title }; }), c: _ctx.foo, d: _vOn(_ctx.onClick) } : _ctx.ok1 ? { f: _vFor(_ctx.items, (item, k0, i0) => { return { a: item.id, b: item.title }; }), g: _ctx.foo, h: _vOn(_ctx.onClick) } : { i: _vFor(_ctx.items, (item, k0, i0) => { return { a: item.id, b: item.title }; }), j: _ctx.foo, k: _vOn(_ctx.onClick) }, { e: _ctx.ok1 })
}`
)
})
diff --git a/packages/uni-mp-compiler/__tests__/test.spec.ts b/packages/uni-mp-compiler/__tests__/test.spec.ts
index c4813a75a2b841531c4635dde0d1ecfdb44147f6..05752244c5126fde21cfa6c996bc4c9c24246cdd 100644
--- a/packages/uni-mp-compiler/__tests__/test.spec.ts
+++ b/packages/uni-mp-compiler/__tests__/test.spec.ts
@@ -37,11 +37,14 @@ function assert(
describe('compiler', () => {
test('scope', () => {
assert(
- ``,
- ``,
+ ``,
+ `{{b}}`,
`(_ctx, _cache) => {
- return { a: _ctx.isRed ? 1 : 0 }
-}`
+ return { a: _vFor(_ctx.items, (item, k0, i0) => { return _ctx.ok ? {} : {}; }), b: _ctx.ok }
+}`,
+ {
+ renderDataSpread: false,
+ }
)
})
})
diff --git a/packages/uni-mp-compiler/__tests__/vFor.spec.ts b/packages/uni-mp-compiler/__tests__/vFor.spec.ts
index 9e226c073503608fd1b723f353cedcc1e21d4f56..e52be1b6d09a2bb21f2fcc63f443ba54f6fd414b 100644
--- a/packages/uni-mp-compiler/__tests__/vFor.spec.ts
+++ b/packages/uni-mp-compiler/__tests__/vFor.spec.ts
@@ -201,7 +201,7 @@ describe(`compiler: v-for`, () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? { b: _vFor(_ctx.list, (i, k0, i0) => { return {}; }) } : {}) }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? { b: _vFor(_ctx.list, (i, k0, i0) => { return {}; }) } : {})
}`
)
})
@@ -211,7 +211,7 @@ describe(`compiler: v-for`, () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? { b: _vFor(_ctx.list, (i, k0, i0) => { return {}; }) } : {}) }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? { b: _vFor(_ctx.list, (i, k0, i0) => { return {}; }) } : {})
}`
)
})
diff --git a/packages/uni-mp-compiler/__tests__/vIf.spec.ts b/packages/uni-mp-compiler/__tests__/vIf.spec.ts
index e2459d7ffea4717e53909f2985d953de3e415c9c..82aba6e2fa61ff7649a1aed1e742f6e4df23d425 100644
--- a/packages/uni-mp-compiler/__tests__/vIf.spec.ts
+++ b/packages/uni-mp-compiler/__tests__/vIf.spec.ts
@@ -29,7 +29,7 @@ describe(`compiler: v-if`, () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : {})
}`
)
})
@@ -38,7 +38,7 @@ describe(`compiler: v-if`, () => {
`hello`,
`hello`,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : {})
}`
)
})
@@ -47,7 +47,7 @@ describe(`compiler: v-if`, () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : {})
}`
)
})
@@ -56,7 +56,7 @@ describe(`compiler: v-if`, () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : {})
}`
)
})
@@ -65,7 +65,7 @@ describe(`compiler: v-if`, () => {
// ``,
// ``,
// `(_ctx, _cache) => {
- // return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
+ // return _extend({ a: _ctx.ok }, _ctx.ok ? {} : {})
// }`
// )
})
@@ -74,7 +74,7 @@ describe(`compiler: v-if`, () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : {})
}`
)
})
@@ -83,7 +83,7 @@ describe(`compiler: v-if`, () => {
``,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.orNot ? {} : {}), b: _ctx.orNot }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : _ctx.orNot ? {} : {}, { b: _ctx.orNot })
}`
)
})
@@ -92,7 +92,7 @@ describe(`compiler: v-if`, () => {
`fine`,
`fine`,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.orNot ? {} : {}), b: _ctx.orNot }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : _ctx.orNot ? {} : {}, { b: _ctx.orNot })
}`
)
})
@@ -119,7 +119,7 @@ describe(`compiler: v-if`, () => {
`fine`,
`fine`,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.orNot ? {} : 3 ? {} : {}), b: _ctx.orNot }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : _ctx.orNot ? {} : 3 ? {} : {}, { b: _ctx.orNot })
}`
)
})
@@ -134,7 +134,7 @@ describe(`compiler: v-if`, () => {
`,
`fine`,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.orNot ? {} : {}), b: _ctx.orNot }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : _ctx.orNot ? {} : {}, { b: _ctx.orNot })
}`
)
})
@@ -143,7 +143,7 @@ describe(`compiler: v-if`, () => {
` `,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.no ? {} : {}), b: _ctx.no }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? {} : _ctx.no ? {} : {}, { b: _ctx.no })
}`
)
})
@@ -163,7 +163,7 @@ describe(`compiler: v-if`, () => {
`,
``,
`(_ctx, _cache) => {
- return { a: _ctx.ok, ...(_ctx.ok ? { b: _ctx.ok2, ...(_ctx.ok2 ? {} : {}) } : {}) }
+ return _extend({ a: _ctx.ok }, _ctx.ok ? _extend({ b: _ctx.ok2 }, _ctx.ok2 ? {} : {}) : {})
}`
)
})
diff --git a/packages/uni-mp-compiler/src/codegen.ts b/packages/uni-mp-compiler/src/codegen.ts
index bbe5232cfe71c3a9ce0df7e293ca39bd7da2e3b7..7f63f41c40d1803f9052d4e6333ecc6074ffbdc1 100644
--- a/packages/uni-mp-compiler/src/codegen.ts
+++ b/packages/uni-mp-compiler/src/codegen.ts
@@ -14,7 +14,6 @@ import { Expression } from '@babel/types'
import { default as babelGenerate } from '@babel/generator'
import { addImportDeclaration, matchEasycom } from '@dcloudio/uni-cli-shared'
import { CodegenOptions, CodegenRootNode } from './options'
-import { createObjectExpression } from './ast'
import {
BindingComponentTypes,
@@ -22,7 +21,7 @@ import {
TransformContext,
} from './transform'
-interface CodegenContext extends CodegenOptions {
+interface CodegenContext extends Omit {
code: string
bindingComponents: TransformContext['bindingComponents']
indentLevel: number
@@ -89,7 +88,7 @@ export function generate(
}
push(`return `)
- push(genBabelExpr(createObjectExpression(ast.scope.properties)))
+ push(genBabelExpr(ast.renderData))
if (useWithBlock) {
deindent()
push(`}`)
diff --git a/packages/uni-mp-compiler/src/compile.ts b/packages/uni-mp-compiler/src/compile.ts
index 09319287b28935ec9835d6c109c1ba4d49a520d2..07203eb7e8e05cd3053d3dec7eee878c49a5d5dc 100644
--- a/packages/uni-mp-compiler/src/compile.ts
+++ b/packages/uni-mp-compiler/src/compile.ts
@@ -4,7 +4,12 @@ import { isString, extend } from '@vue/shared'
import { hash, parseFilterNames } from '@dcloudio/uni-cli-shared'
import { generate } from './codegen'
import { CompilerOptions } from './options'
-import { DirectiveTransform, NodeTransform, transform } from './transform'
+import {
+ DirectiveTransform,
+ NodeTransform,
+ transform,
+ TransformContext,
+} from './transform'
import { transformExpression } from './transforms/transformExpression'
import { transformIdentifier } from './transforms/transformIdentifier'
import { transformIf } from './transforms/vIf'
@@ -14,6 +19,27 @@ import { transformOn } from './transforms/vOn'
import { transformElement } from './transforms/transformElement'
import { transformBind } from './transforms/vBind'
import { transformComponent } from './transforms/transformComponent'
+import {
+ ArrowFunctionExpression,
+ BlockStatement,
+ CallExpression,
+ callExpression,
+ ConditionalExpression,
+ identifier,
+ isCallExpression,
+ isConditionalExpression,
+ isIdentifier,
+ isObjectExpression,
+ isObjectProperty,
+ isSpreadElement,
+ objectExpression,
+ ObjectExpression,
+ ObjectProperty,
+ ReturnStatement,
+ SpreadElement,
+} from '@babel/types'
+import { createObjectExpression } from './ast'
+import { EXTEND } from './runtimeHelpers'
export type TransformPreset = [
NodeTransform[],
@@ -74,7 +100,7 @@ export function baseCompile(template: string, options: CompilerOptions = {}) {
const result = extend(
generate(
extend(ast, {
- scope: context.scope,
+ renderData: createRenderDataExpr(context.scope.properties, context),
bindingComponents: context.bindingComponents,
}),
options
@@ -114,3 +140,114 @@ function parseFilters(lang: string, filename: string) {
}
return []
}
+
+function createRenderDataExpr(
+ properties: (ObjectProperty | SpreadElement)[],
+ context: TransformContext
+) {
+ const objExpr = createObjectExpression(properties)
+ if (context.renderDataSpread || !hasSpreadElement(objExpr)) {
+ return objExpr
+ }
+ return transformObjectSpreadExpr(objExpr, context)
+}
+
+function hasSpreadElement(expr: ObjectExpression): boolean {
+ return expr.properties.some((prop) => {
+ if (isSpreadElement(prop)) {
+ return true
+ } else {
+ const objExpr = parseReturnObjExpr(prop as ObjectProperty)
+ if (objExpr) {
+ return hasSpreadElement(objExpr)
+ }
+ }
+ })
+}
+
+function parseReturnObjExpr(prop: ObjectProperty) {
+ if (
+ isObjectProperty(prop) &&
+ isCallExpression(prop.value) &&
+ isIdentifier(prop.value.callee) &&
+ prop.value.callee.name === '_vFor'
+ ) {
+ // 目前硬编码
+ return (
+ (
+ (prop.value.arguments[1] as ArrowFunctionExpression)
+ .body as BlockStatement
+ ).body[0] as ReturnStatement
+ ).argument as ObjectExpression
+ }
+}
+
+function transformObjectPropertyExpr(
+ prop: ObjectProperty,
+ context: TransformContext
+) {
+ // vFor
+ const objExpr = parseReturnObjExpr(prop)
+ if (objExpr) {
+ if (hasSpreadElement(objExpr)) {
+ ;(
+ (
+ (
+ (prop.value as CallExpression)
+ .arguments[1] as ArrowFunctionExpression
+ ).body as BlockStatement
+ ).body[0] as ReturnStatement
+ ).argument = transformObjectSpreadExpr(objExpr, context)
+ }
+ }
+ return prop
+}
+
+function transformObjectSpreadExpr(
+ objExpr: ObjectExpression,
+ context: TransformContext
+) {
+ const properties = objExpr.properties as (ObjectProperty | SpreadElement)[]
+ const args: (ObjectExpression | ConditionalExpression)[] = []
+ let objExprProperties: ObjectProperty[] = []
+ properties.forEach((prop) => {
+ if (isObjectProperty(prop)) {
+ objExprProperties.push(transformObjectPropertyExpr(prop, context))
+ } else {
+ if (objExprProperties.length) {
+ args.push(objectExpression(objExprProperties))
+ }
+ args.push(
+ transformConditionalExpression(
+ prop.argument as ConditionalExpression,
+ context
+ )
+ )
+ objExprProperties = []
+ }
+ })
+ if (objExprProperties.length) {
+ args.push(objectExpression(objExprProperties))
+ }
+ if (args.length === 1) {
+ return args[0] as ObjectExpression
+ }
+ return callExpression(identifier(context.helperString(EXTEND)), args)
+}
+function transformConditionalExpression(
+ expr: ConditionalExpression,
+ context: TransformContext
+) {
+ const { consequent, alternate } = expr
+ if (isObjectExpression(consequent) && hasSpreadElement(consequent)) {
+ expr.consequent = transformObjectSpreadExpr(consequent, context)
+ }
+ if (isObjectExpression(alternate)) {
+ if (hasSpreadElement(alternate)) {
+ expr.alternate = transformObjectSpreadExpr(alternate, context)
+ }
+ } else if (isConditionalExpression(alternate)) {
+ transformConditionalExpression(alternate, context)
+ }
+ return expr
+}
diff --git a/packages/uni-mp-compiler/src/options.ts b/packages/uni-mp-compiler/src/options.ts
index a6bea0b5f85087984d24b85c155d9e3781e31da0..e2290a40a30e531a4645b17a6de546938fa4d906 100644
--- a/packages/uni-mp-compiler/src/options.ts
+++ b/packages/uni-mp-compiler/src/options.ts
@@ -1,5 +1,11 @@
import { ParserPlugin } from '@babel/parser'
-import { Expression, ObjectProperty, SpreadElement } from '@babel/types'
+import {
+ CallExpression,
+ Expression,
+ ObjectExpression,
+ ObjectProperty,
+ SpreadElement,
+} from '@babel/types'
import { MiniProgramCompilerOptions } from '@dcloudio/uni-cli-shared'
import { BindingMetadata, CompilerError, RootNode } from '@vue/compiler-core'
import IdentifierGenerator from './identifier'
@@ -11,7 +17,7 @@ import {
import { VForOptions } from './transforms/vFor'
export interface CodegenRootNode extends RootNode {
- scope: CodegenScope
+ renderData: ObjectExpression | CallExpression
bindingComponents: TransformContext['bindingComponents']
}
@@ -49,6 +55,7 @@ export interface TransformOptions
hashId?: string | null
scopeId?: string | null
filters?: string[]
+ renderDataSpread?: boolean
cacheHandlers?: boolean
nodeTransforms?: NodeTransform[]
directiveTransforms?: Record
diff --git a/packages/uni-mp-compiler/src/runtimeHelpers.ts b/packages/uni-mp-compiler/src/runtimeHelpers.ts
index cf0b8d2a323bdea9807f14fc30d5f44e89dbb9de..d8fe870214889e64cbab645893043e6671058756 100644
--- a/packages/uni-mp-compiler/src/runtimeHelpers.ts
+++ b/packages/uni-mp-compiler/src/runtimeHelpers.ts
@@ -2,11 +2,13 @@ import { registerRuntimeHelpers } from '@vue/compiler-core'
export const V_ON = Symbol(`vOn`)
export const V_FOR = Symbol(`vFor`)
+export const EXTEND = Symbol(`extend`)
export const HYPHENATE = Symbol(`hyphenate`)
export const STRINGIFY_STYLE = Symbol(`stringifyStyle`)
registerRuntimeHelpers({
[V_ON]: 'vOn',
[V_FOR]: 'vFor',
+ [EXTEND]: 'extend',
[HYPHENATE]: 'hyphenate',
[STRINGIFY_STYLE]: 'stringifyStyle',
})
diff --git a/packages/uni-mp-compiler/src/transform.ts b/packages/uni-mp-compiler/src/transform.ts
index 13d3b69585e7fc190a8640bf2b8dc04e98ce07ec..75eea49aa3f15d4673b86e450bdb7f641b0cc2e5 100644
--- a/packages/uni-mp-compiler/src/transform.ts
+++ b/packages/uni-mp-compiler/src/transform.ts
@@ -223,6 +223,7 @@ export function createTransformContext(
cacheHandlers = false,
prefixIdentifiers = false,
skipTransformIdentifier = false,
+ renderDataSpread = false,
nodeTransforms = [],
directiveTransforms = {},
isBuiltInComponent = NOOP,
@@ -285,6 +286,7 @@ export function createTransformContext(
directiveTransforms,
expressionPlugins,
skipTransformIdentifier,
+ renderDataSpread,
isBuiltInComponent,
isCustomElement,
onError,
diff --git a/packages/uni-mp-vue/dist/vue.runtime.esm.js b/packages/uni-mp-vue/dist/vue.runtime.esm.js
index c61a3cfbe106cf09e0c324c626659f7073f0f18c..ae9b42ae0fb1fa455a70ca74a345688960466de9 100644
--- a/packages/uni-mp-vue/dist/vue.runtime.esm.js
+++ b/packages/uni-mp-vue/dist/vue.runtime.esm.js
@@ -1,5 +1,5 @@
import { extend, isSymbol, isObject, toRawType, def, hasChanged, isArray, isFunction, NOOP, remove, toHandlerKey, camelize, capitalize, isString, normalizeClass, normalizeStyle, isOn, isPromise, EMPTY_OBJ, isSet, isMap, isPlainObject, invokeArrayFns, hasOwn, NO, isIntegerKey, toNumber, hyphenate, isReservedProp, EMPTY_ARR, makeMap, toTypeString, stringifyStyle as stringifyStyle$1 } from '@vue/shared';
-export { camelize, hyphenate, normalizeClass, normalizeProps, normalizeStyle, toDisplayString, toHandlerKey } from '@vue/shared';
+export { camelize, extend, hyphenate, normalizeClass, normalizeProps, normalizeStyle, toDisplayString, toHandlerKey } from '@vue/shared';
// lifecycle
// App and Page
diff --git a/packages/uni-mp-vue/src/index.ts b/packages/uni-mp-vue/src/index.ts
index 9f121ba7f137f92abf2633e618765ea6d9d87ae9..75b8969175cde4744aaae090d3531dc4a1892655 100644
--- a/packages/uni-mp-vue/src/index.ts
+++ b/packages/uni-mp-vue/src/index.ts
@@ -7,6 +7,6 @@ export function createApp(rootComponent: unknown, rootProps = null) {
}
export const createSSRApp = createApp
export * from './helpers'
-export { hyphenate } from '@vue/shared'
+export { extend, hyphenate } from '@vue/shared'
// @ts-ignore
export * from '../lib/vue.runtime.esm.js'