提交 9fa6f69f 编写于 作者: fxy060608's avatar fxy060608

wip(mp): mp-alipay

上级 b6527b85
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
"@babel/parser": "^7.15.0", "@babel/parser": "^7.15.0",
"@babel/types": "^7.15.0", "@babel/types": "^7.15.0",
"@rollup/pluginutils": "^4.1.1", "@rollup/pluginutils": "^4.1.1",
"@vue/compiler-core": "^3.2.20",
"chokidar": "^3.5.2", "chokidar": "^3.5.2",
"compare-versions": "^3.6.0", "compare-versions": "^3.6.0",
"debug": "^4.3.1", "debug": "^4.3.1",
......
export * from './transformComponent' export * from './transformRef'
export * from './transformPageHead' export * from './transformPageHead'
export * from './transformComponent'
...@@ -7,10 +7,11 @@ import { ...@@ -7,10 +7,11 @@ import {
TransformContext, TransformContext,
} from '@vue/compiler-core' } from '@vue/compiler-core'
import { COMPONENT_BIND_LINK, COMPONENT_ON_LINK } from '../../mp/constants' import { COMPONENT_BIND_LINK, COMPONENT_ON_LINK } from '../../mp/constants'
import { isUserComponent } from '../utils' import { isUserComponent, createAttributeNode } from '../utils'
export function createTransformComponentLink( export function createTransformComponentLink(
name: typeof COMPONENT_BIND_LINK | typeof COMPONENT_ON_LINK name: typeof COMPONENT_BIND_LINK | typeof COMPONENT_ON_LINK,
type: NodeTypes.ATTRIBUTE | NodeTypes.DIRECTIVE = NodeTypes.DIRECTIVE
) { ) {
return function transformComponentLink( return function transformComponentLink(
node: RootNode | TemplateChildNode, node: RootNode | TemplateChildNode,
...@@ -19,13 +20,17 @@ export function createTransformComponentLink( ...@@ -19,13 +20,17 @@ export function createTransformComponentLink(
if (!isUserComponent(node, context)) { if (!isUserComponent(node, context)) {
return return
} }
node.props.push({ if (type === NodeTypes.DIRECTIVE) {
type: NodeTypes.DIRECTIVE, node.props.push({
name: 'on', type: NodeTypes.DIRECTIVE,
modifiers: [], name: 'on',
loc: locStub, modifiers: [],
arg: createSimpleExpression(name, true), loc: locStub,
exp: createSimpleExpression('__l', true), arg: createSimpleExpression(name, true),
}) exp: createSimpleExpression('__l', true),
})
} else {
node.props.push(createAttributeNode(name, '__l'))
}
} }
} }
import {
ComponentNode,
findProp,
NodeTypes,
RootNode,
SimpleExpressionNode,
TemplateChildNode,
TransformContext,
} from '@vue/compiler-core'
import {
addStaticClass,
VUE_REF,
VUE_REF_IN_FOR,
isUserComponent,
} from '../utils'
export function transformRef(
node: RootNode | TemplateChildNode,
context: TransformContext
) {
if (!isUserComponent(node, context)) {
return
}
addVueRef(node, context)
}
function addVueRef(node: ComponentNode, context: TransformContext) {
// 仅配置了 ref 属性的,才需要增补 vue-ref
const refProp = findProp(node, 'ref')
if (!refProp) {
return
}
if (refProp.type === NodeTypes.ATTRIBUTE) {
refProp.name = 'data-' + VUE_REF
} else {
;(refProp.arg as SimpleExpressionNode).content = 'data-' + VUE_REF
}
return addStaticClass(
node,
// ref-in-for
// ref
(context as unknown as { inVFor: boolean }).inVFor
? VUE_REF_IN_FOR
: VUE_REF
)
}
import { isComponentTag } from '@dcloudio/uni-shared' import { isComponentTag } from '@dcloudio/uni-shared'
import { import {
AttributeNode,
ComponentNode, ComponentNode,
ElementNode,
ElementTypes, ElementTypes,
isCoreComponent, isCoreComponent,
locStub,
NodeTypes, NodeTypes,
RootNode, RootNode,
TemplateChildNode, TemplateChildNode,
TransformContext, TransformContext,
} from '@vue/compiler-core' } from '@vue/compiler-core'
export const VUE_REF = 'r'
export const VUE_REF_IN_FOR = 'r-i-f'
export function isUserComponent( export function isUserComponent(
node: RootNode | TemplateChildNode, node: RootNode | TemplateChildNode,
context: TransformContext context: TransformContext
...@@ -21,3 +27,42 @@ export function isUserComponent( ...@@ -21,3 +27,42 @@ export function isUserComponent(
!context.isBuiltInComponent(node.tag) !context.isBuiltInComponent(node.tag)
) )
} }
export function createAttributeNode(
name: string,
content: string
): AttributeNode {
return {
type: NodeTypes.ATTRIBUTE,
loc: locStub,
name,
value: {
type: NodeTypes.TEXT,
loc: locStub,
content,
},
}
}
function createClassAttribute(clazz: string): AttributeNode {
return createAttributeNode('class', clazz)
}
export function addStaticClass(node: ElementNode, clazz: string) {
const classProp = node.props.find(
(prop) => prop.type === NodeTypes.ATTRIBUTE && prop.name === 'class'
) as AttributeNode | undefined
if (!classProp) {
return node.props.unshift(createClassAttribute(clazz))
}
if (classProp.value) {
return (classProp.value.content = classProp.value.content + ' ' + clazz)
}
classProp.value = {
type: NodeTypes.TEXT,
loc: locStub,
content: clazz,
}
}
import { assert } from './testUtils'
describe('compiler: transform ref', () => {
test('without ref', () => {
assert(
`<custom/>`,
`<custom v-i="2a9ec0b0-0" onVI="__l"/>`,
`(_ctx, _cache) => {
return {}
}`
)
assert(
`<custom/><custom/><custom1/>`,
`<custom v-i="2a9ec0b0-0" onVI="__l"/><custom v-i="2a9ec0b0-1" onVI="__l"/><custom1 v-i="2a9ec0b0-2" onVI="__l"/>`,
`(_ctx, _cache) => {
return {}
}`
)
})
test('static ref', () => {
assert(
`<custom ref="custom"/>`,
`<custom ref="__r" data-r="custom" v-i="2a9ec0b0-0" onVI="__l"/>`,
`(_ctx, _cache) => {
return {}
}`
)
assert(
`<custom v-for="item in items" ref="custom"/>`,
`<custom a:for="{{a}}" a:for-item="item" ref="__r" data-r-i-f="custom" v-i="{{item.a}}" onVI="__l"/>`,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-0' + '-' + i0 }; }) }
}`
)
})
test('dynamic ref', () => {
assert(
`<custom :ref="custom"/>`,
`<custom ref="__r" data-r="{{a}}" v-i="2a9ec0b0-0" onVI="__l"/>`,
`(_ctx, _cache) => {
return { a: _ctx.custom }
}`
)
assert(
`<custom v-for="item in items" :ref="custom"/>`,
`<custom a:for="{{a}}" a:for-item="item" ref="__r" data-r-i-f="{{b}}" v-i="{{item.a}}" onVI="__l"/>`,
`(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-0' + '-' + i0 }; }), b: _ctx.custom }
}`
)
})
})
import { isCustomElement, isNativeTag } from '@dcloudio/uni-shared'
import { compile, CompilerOptions } from '@dcloudio/uni-mp-compiler'
import { miniProgram, nodeTransforms } from '../src/compiler/options'
export function assert(
template: string,
templateCode: string,
renderCode: string,
options: CompilerOptions = {}
) {
const res = compile(template, {
mode: 'module',
filename: 'foo.vue',
prefixIdentifiers: true,
inline: true,
isNativeTag,
isCustomElement,
generatorOpts: {
concise: true,
},
nodeTransforms,
miniProgram: {
...miniProgram,
emitFile({ source }) {
// console.log(source)
if (!options.onError) {
expect(source).toBe(templateCode)
}
return ''
},
},
...options,
})
if (!options.onError) {
expect(res.code).toBe(renderCode)
}
}
...@@ -2,13 +2,27 @@ import path from 'path' ...@@ -2,13 +2,27 @@ import path from 'path'
import { import {
COMPONENT_ON_LINK, COMPONENT_ON_LINK,
createTransformComponentLink, createTransformComponentLink,
MiniProgramCompilerOptions,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite' import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
import { NodeTypes } from '@vue/compiler-core'
import source from './mini.project.json' import source from './mini.project.json'
import { transformRef } from './transforms/transformRef'
const projectConfigFilename = 'mini.project.json' const projectConfigFilename = 'mini.project.json'
export const miniProgram: MiniProgramCompilerOptions = {
class: {
array: false,
},
slot: {
fallback: true,
},
directive: 'a:',
}
export const nodeTransforms = [
transformRef,
createTransformComponentLink(COMPONENT_ON_LINK, NodeTypes.ATTRIBUTE),
]
export const options: UniMiniProgramPluginOptions = { export const options: UniMiniProgramPluginOptions = {
vite: { vite: {
inject: { inject: {
...@@ -31,9 +45,8 @@ export const options: UniMiniProgramPluginOptions = { ...@@ -31,9 +45,8 @@ export const options: UniMiniProgramPluginOptions = {
source, source,
}, },
template: { template: {
class: { /* eslint-disable no-restricted-syntax */
array: false, ...miniProgram,
},
filter: { filter: {
extname: '.sjs', extname: '.sjs',
lang: 'sjs', lang: 'sjs',
...@@ -46,13 +59,9 @@ ${filter.code} ...@@ -46,13 +59,9 @@ ${filter.code}
</sjs>` </sjs>`
}, },
}, },
slot: {
fallback: true,
},
extname: '.axml', extname: '.axml',
directive: 'a:',
compilerOptions: { compilerOptions: {
nodeTransforms: [createTransformComponentLink(COMPONENT_ON_LINK)], nodeTransforms,
}, },
}, },
style: { style: {
......
import {
createAttributeNode,
isUserComponent,
VUE_REF,
VUE_REF_IN_FOR,
} from '@dcloudio/uni-cli-shared'
import {
ComponentNode,
findProp,
NodeTypes,
RootNode,
SimpleExpressionNode,
TemplateChildNode,
TransformContext,
} from '@vue/compiler-core'
export function transformRef(
node: RootNode | TemplateChildNode,
context: TransformContext
) {
if (!isUserComponent(node, context)) {
return
}
addVueRef(node, context)
}
function addVueRef(node: ComponentNode, context: TransformContext) {
// 仅配置了 ref 属性的,才需要增补 vue-ref
const refProp = findProp(node, 'ref')
if (!refProp) {
return
}
const dataRef =
'data-' +
((context as unknown as { inVFor: boolean }).inVFor
? VUE_REF_IN_FOR
: VUE_REF)
if (refProp.type === NodeTypes.ATTRIBUTE) {
refProp.name = dataRef
} else {
;(refProp.arg as SimpleExpressionNode).content = dataRef
}
const { props } = node
props.splice(props.indexOf(refProp), 0, createAttributeNode('ref', '__r'))
}
...@@ -4,6 +4,7 @@ import { transformFor } from '../src/compiler/transforms/vFor' ...@@ -4,6 +4,7 @@ import { transformFor } from '../src/compiler/transforms/vFor'
import { transformOn } from '../src/compiler/transforms/vOn' import { transformOn } from '../src/compiler/transforms/vOn'
import { transformModel } from '../src/compiler/transforms/vModel' import { transformModel } from '../src/compiler/transforms/vModel'
import { miniProgram } from '../src/compiler/options' import { miniProgram } from '../src/compiler/options'
import { transformRef } from '@dcloudio/uni-cli-shared'
export function assert( export function assert(
template: string, template: string,
...@@ -21,7 +22,7 @@ export function assert( ...@@ -21,7 +22,7 @@ export function assert(
generatorOpts: { generatorOpts: {
concise: true, concise: true,
}, },
nodeTransforms: [transformFor], nodeTransforms: [transformRef, transformFor],
directiveTransforms: { directiveTransforms: {
on: transformOn, on: transformOn,
model: transformModel, model: transformModel,
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
var initMiniProgramPlugin = require('@dcloudio/uni-mp-vite'); var initMiniProgramPlugin = require('@dcloudio/uni-mp-vite');
var path = require('path'); var path = require('path');
var uniMpCompiler = require('@dcloudio/uni-mp-compiler');
var uniCliShared = require('@dcloudio/uni-cli-shared'); var uniCliShared = require('@dcloudio/uni-cli-shared');
var uniMpCompiler = require('@dcloudio/uni-mp-compiler');
var compilerCore = require('@vue/compiler-core'); var compilerCore = require('@vue/compiler-core');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
...@@ -187,7 +187,7 @@ const options = { ...@@ -187,7 +187,7 @@ const options = {
</import-sjs>`; </import-sjs>`;
}, },
}, extname: '.swan', compilerOptions: { }, extname: '.swan', compilerOptions: {
nodeTransforms: [transformFor], nodeTransforms: [uniCliShared.transformRef, transformFor],
directiveTransforms: { directiveTransforms: {
on: transformOn, on: transformOn,
model: transformModel, model: transformModel,
......
...@@ -367,7 +367,7 @@ function initWxsCallMethods(methods, wxsCallMethods) { ...@@ -367,7 +367,7 @@ function initWxsCallMethods(methods, wxsCallMethods) {
function selectAllComponents(mpInstance, selector, $refs) { function selectAllComponents(mpInstance, selector, $refs) {
const components = mpInstance.selectAllComponents(selector); const components = mpInstance.selectAllComponents(selector);
components.forEach((component) => { components.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
$refs[ref] = component.$vm || component; $refs[ref] = component.$vm || component;
}); });
} }
...@@ -375,10 +375,10 @@ function initRefs(instance, mpInstance) { ...@@ -375,10 +375,10 @@ function initRefs(instance, mpInstance) {
Object.defineProperty(instance, 'refs', { Object.defineProperty(instance, 'refs', {
get() { get() {
const $refs = {}; const $refs = {};
selectAllComponents(mpInstance, '.v-r', $refs); selectAllComponents(mpInstance, '.r', $refs);
const forComponents = mpInstance.selectAllComponents('.v-r-i-f'); const forComponents = mpInstance.selectAllComponents('.r-i-f');
forComponents.forEach((component) => { forComponents.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
if (!$refs[ref]) { if (!$refs[ref]) {
$refs[ref] = []; $refs[ref] = [];
} }
......
import path from 'path' import path from 'path'
import { MiniProgramCompilerOptions } from '@dcloudio/uni-cli-shared' import {
MiniProgramCompilerOptions,
transformRef,
} from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite' import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
import source from './project.swan.json' import source from './project.swan.json'
...@@ -57,7 +60,7 @@ export const options: UniMiniProgramPluginOptions = { ...@@ -57,7 +60,7 @@ export const options: UniMiniProgramPluginOptions = {
}, },
extname: '.swan', extname: '.swan',
compilerOptions: { compilerOptions: {
nodeTransforms: [transformFor], nodeTransforms: [transformRef, transformFor],
directiveTransforms: { directiveTransforms: {
on: transformOn, on: transformOn,
model: transformModel, model: transformModel,
......
import { transformRef } from '@dcloudio/uni-cli-shared'
import { assert } from './testUtils' import { assert } from './testUtils'
const nodeTransforms = [transformRef]
describe('compiler: transform ref', () => { describe('compiler: transform ref', () => {
test('without ref', () => { test('without ref', () => {
assert( assert(
...@@ -7,46 +9,64 @@ describe('compiler: transform ref', () => { ...@@ -7,46 +9,64 @@ describe('compiler: transform ref', () => {
`<custom v-i="2a9ec0b0-0"/>`, `<custom v-i="2a9ec0b0-0"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`,
{
nodeTransforms,
}
) )
assert( assert(
`<custom/><custom/><custom1/>`, `<custom/><custom/><custom1/>`,
`<custom v-i="2a9ec0b0-0"/><custom v-i="2a9ec0b0-1"/><custom1 v-i="2a9ec0b0-2"/>`, `<custom v-i="2a9ec0b0-0"/><custom v-i="2a9ec0b0-1"/><custom1 v-i="2a9ec0b0-2"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`,
{
nodeTransforms,
}
) )
}) })
test('static ref', () => { test('static ref', () => {
assert( assert(
`<custom ref="custom"/>`, `<custom ref="custom"/>`,
`<custom class="v-r" data-ref="custom" v-i="2a9ec0b0-0"/>`, `<custom class="r" data-r="custom" v-i="2a9ec0b0-0"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`,
{
nodeTransforms,
}
) )
assert( assert(
`<custom v-for="item in items" ref="custom"/>`, `<custom v-for="item in items" ref="custom"/>`,
`<custom wx:for="{{a}}" wx:for-item="item" class="v-r-i-f" data-ref="custom" v-i="{{item.a}}"/>`, `<custom wx:for="{{a}}" wx:for-item="item" class="r-i-f" data-r="custom" v-i="{{item.a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-0' + '-' + i0 }; }) } return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-0' + '-' + i0 }; }) }
}` }`,
{
nodeTransforms,
}
) )
}) })
test('dynamic ref', () => { test('dynamic ref', () => {
assert( assert(
`<custom :ref="custom"/>`, `<custom :ref="custom"/>`,
`<custom class="v-r" data-ref="{{a}}" v-i="2a9ec0b0-0"/>`, `<custom class="r" data-r="{{a}}" v-i="2a9ec0b0-0"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _ctx.custom } return { a: _ctx.custom }
}` }`,
{
nodeTransforms,
}
) )
assert( assert(
`<custom v-for="item in items" :ref="custom"/>`, `<custom v-for="item in items" :ref="custom"/>`,
`<custom wx:for="{{a}}" wx:for-item="item" class="v-r-i-f" data-ref="{{b}}" v-i="{{item.a}}"/>`, `<custom wx:for="{{a}}" wx:for-item="item" class="r-i-f" data-r="{{b}}" v-i="{{item.a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-0' + '-' + i0 }; }), b: _ctx.custom } return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-0' + '-' + i0 }; }), b: _ctx.custom }
}` }`,
{
nodeTransforms,
}
) )
}) })
}) })
...@@ -26,7 +26,6 @@ import { ...@@ -26,7 +26,6 @@ import {
isNullLiteral, isNullLiteral,
} from '@babel/types' } from '@babel/types'
import { import {
AttributeNode,
createCompilerError, createCompilerError,
createSimpleExpression, createSimpleExpression,
DirectiveNode, DirectiveNode,
...@@ -174,19 +173,3 @@ export function createOnDirectiveNode(name: string, value: string) { ...@@ -174,19 +173,3 @@ export function createOnDirectiveNode(name: string, value: string) {
export function createBindDirectiveNode(name: string, value: string) { export function createBindDirectiveNode(name: string, value: string) {
return createDirectiveNode('bind', name, value) return createDirectiveNode('bind', name, value)
} }
export function createAttributeNode(
name: string,
content: string
): AttributeNode {
return {
type: NodeTypes.ATTRIBUTE,
loc: locStub,
name,
value: {
type: NodeTypes.TEXT,
loc: locStub,
content,
},
}
}
...@@ -57,6 +57,7 @@ import { ...@@ -57,6 +57,7 @@ import {
} from './options' } from './options'
import { EXTEND } from './runtimeHelpers' import { EXTEND } from './runtimeHelpers'
import { createObjectExpression } from './ast' import { createObjectExpression } from './ast'
import { SCOPED_SLOT_IDENTIFIER } from './transforms/utils'
export interface ImportItem { export interface ImportItem {
exp: string | ExpressionNode exp: string | ExpressionNode
...@@ -114,6 +115,7 @@ export interface TransformContext ...@@ -114,6 +115,7 @@ export interface TransformContext
currentVueId: string currentVueId: string
vueIds: string[] vueIds: string[]
inVOnce: boolean inVOnce: boolean
inVFor: boolean
helper<T extends symbol>(name: T): T helper<T extends symbol>(name: T): T
removeHelper<T extends symbol>(name: T): void removeHelper<T extends symbol>(name: T): void
helperString(name: symbol): string helperString(name: symbol): string
...@@ -140,6 +142,17 @@ export function isVForScope(scope: CodegenScope): scope is CodegenVForScope { ...@@ -140,6 +142,17 @@ export function isVForScope(scope: CodegenScope): scope is CodegenVForScope {
return !!(scope as CodegenVForScope).source return !!(scope as CodegenVForScope).source
} }
export function isScopedSlotVFor({ source }: CodegenVForScope) {
if (source.type !== NodeTypes.COMPOUND_EXPRESSION) {
return false
}
const first = source.children[0] as ExpressionNode
return (
first.type === NodeTypes.SIMPLE_EXPRESSION &&
first.content.includes(SCOPED_SLOT_IDENTIFIER)
)
}
export function transform(root: CodegenRootNode, options: TransformOptions) { export function transform(root: CodegenRootNode, options: TransformOptions) {
const context = createTransformContext(root, options) const context = createTransformContext(root, options)
traverseNode(root, context) traverseNode(root, context)
...@@ -346,6 +359,16 @@ export function createTransformContext( ...@@ -346,6 +359,16 @@ export function createTransformContext(
return vueIds[vueIds.length - 1] return vueIds[vueIds.length - 1]
}, },
inVOnce: false, inVOnce: false,
get inVFor() {
let parent: CodegenScope | null = scopes[scopes.length - 1]
while (parent) {
if (isVForScope(parent) && !isScopedSlotVFor(parent)) {
return true
}
parent = parent.parent
}
return false
},
// methods // methods
popScope() { popScope() {
return scopes.pop() return scopes.pop()
......
import { import { ComponentNode } from '@vue/compiler-core'
ComponentNode, import { createAttributeNode, isUserComponent } from '@dcloudio/uni-cli-shared'
findProp,
NodeTypes,
SimpleExpressionNode,
} from '@vue/compiler-core'
import { isUserComponent } from '@dcloudio/uni-cli-shared'
import { isVForScope, NodeTransform, TransformContext } from '../transform' import { isVForScope, NodeTransform, TransformContext } from '../transform'
import { createAttributeNode, createBindDirectiveNode } from '../ast' import { createBindDirectiveNode } from '../ast'
import { addStaticClass } from './transformElement' import { ATTR_VUE_ID } from './utils'
import { ATTR_VUE_ID, CLASS_VUE_REF, CLASS_VUE_REF_IN_FOR } from './utils'
import { CodegenScope } from '../options'
import { isScopedSlotVFor } from './vSlot'
export const transformComponent: NodeTransform = (node, context) => { export const transformComponent: NodeTransform = (node, context) => {
if (!isUserComponent(node, context as any)) { if (!isUserComponent(node, context as any)) {
return return
} }
addVueRef(node, context)
addVueId(node, context) addVueId(node, context)
return function postTransformComponent() { return function postTransformComponent() {
context.vueIds.pop() context.vueIds.pop()
...@@ -60,34 +51,3 @@ function addVueId(node: ComponentNode, context: TransformContext) { ...@@ -60,34 +51,3 @@ function addVueId(node: ComponentNode, context: TransformContext) {
} }
return node.props.push(createAttributeNode(ATTR_VUE_ID, value)) return node.props.push(createAttributeNode(ATTR_VUE_ID, value))
} }
function addVueRef(node: ComponentNode, context: TransformContext) {
// 仅配置了 ref 属性的,才需要增补 vue-ref
const refProp = findProp(node, 'ref')
if (!refProp) {
return
}
if (refProp.type === NodeTypes.ATTRIBUTE) {
refProp.name = 'data-ref'
} else {
;(refProp.arg as SimpleExpressionNode).content = 'data-ref'
}
return addStaticClass(
node,
// vue-ref-in-for
// vue-ref
isInVFor(context.currentScope) ? CLASS_VUE_REF_IN_FOR : CLASS_VUE_REF
)
}
function isInVFor(scope: CodegenScope) {
let parent: CodegenScope | null = scope
while (parent) {
if (isVForScope(parent) && !isScopedSlotVFor(parent)) {
return true
}
parent = parent.parent
}
return false
}
...@@ -14,8 +14,6 @@ import { ...@@ -14,8 +14,6 @@ import {
UNREF, UNREF,
toValidAssetId, toValidAssetId,
findDir, findDir,
locStub,
AttributeNode,
DirectiveNode, DirectiveNode,
ComponentNode, ComponentNode,
} from '@vue/compiler-core' } from '@vue/compiler-core'
...@@ -29,8 +27,8 @@ import { ...@@ -29,8 +27,8 @@ import {
NodeTransform, NodeTransform,
TransformContext, TransformContext,
} from '../transform' } from '../transform'
import { createAttributeNode } from '../ast'
import { transformModel } from './vModel' import { transformModel } from './vModel'
import { addStaticClass } from '@dcloudio/uni-cli-shared'
export interface DirectiveTransformResult { export interface DirectiveTransformResult {
props: Property[] props: Property[]
...@@ -63,29 +61,6 @@ export const transformElement: NodeTransform = (node, context) => { ...@@ -63,29 +61,6 @@ export const transformElement: NodeTransform = (node, context) => {
} }
} }
function createClassAttribute(clazz: string): AttributeNode {
return createAttributeNode('class', clazz)
}
export function addStaticClass(node: ElementNode, clazz: string) {
const classProp = node.props.find(
(prop) => prop.type === NodeTypes.ATTRIBUTE && prop.name === 'class'
) as AttributeNode | undefined
if (!classProp) {
return node.props.unshift(createClassAttribute(clazz))
}
if (classProp.value) {
return (classProp.value.content = classProp.value.content + ' ' + clazz)
}
classProp.value = {
type: NodeTypes.TEXT,
loc: locStub,
content: clazz,
}
}
function addScopeId(node: ElementNode, scopeId: string) { function addScopeId(node: ElementNode, scopeId: string) {
return addStaticClass(node, scopeId) return addStaticClass(node, scopeId)
} }
......
...@@ -25,8 +25,6 @@ import { isVForScope, isVIfScope, TransformContext } from '../transform' ...@@ -25,8 +25,6 @@ import { isVForScope, isVIfScope, TransformContext } from '../transform'
export const ATTR_VUE_ID = 'v-i' export const ATTR_VUE_ID = 'v-i'
export const ATTR_VUE_SLOTS = 'v-s' export const ATTR_VUE_SLOTS = 'v-s'
export const CLASS_VUE_REF = 'v-r'
export const CLASS_VUE_REF_IN_FOR = 'v-r-i-f'
export const SCOPED_SLOT_IDENTIFIER = '__SCOPED_SLOT__' export const SCOPED_SLOT_IDENTIFIER = '__SCOPED_SLOT__'
export function rewriteSpreadElement( export function rewriteSpreadElement(
......
...@@ -17,6 +17,7 @@ import { ...@@ -17,6 +17,7 @@ import {
import { parseExpr, parseParam } from '../ast' import { parseExpr, parseParam } from '../ast'
import { import {
createStructuralDirectiveTransform, createStructuralDirectiveTransform,
isScopedSlotVFor,
NodeTransform, NodeTransform,
TransformContext, TransformContext,
} from '../transform' } from '../transform'
...@@ -39,7 +40,7 @@ import { ...@@ -39,7 +40,7 @@ import {
import { rewriteExpression } from './utils' import { rewriteExpression } from './utils'
import { CodegenVForScope } from '../options' import { CodegenVForScope } from '../options'
import { V_FOR } from '../runtimeHelpers' import { V_FOR } from '../runtimeHelpers'
import { createVSlotCallExpression, isScopedSlotVFor } from './vSlot' import { createVSlotCallExpression } from './vSlot'
export type VForOptions = Omit<ForParseResult, 'tagType'> & { export type VForOptions = Omit<ForParseResult, 'tagType'> & {
sourceExpr?: Expression sourceExpr?: Expression
...@@ -62,6 +63,7 @@ export type ForElementNode = ElementNode & { ...@@ -62,6 +63,7 @@ export type ForElementNode = ElementNode & {
export function isForElementNode(node: unknown): node is ForElementNode { export function isForElementNode(node: unknown): node is ForElementNode {
return !!(node as ForElementNode).vFor return !!(node as ForElementNode).vFor
} }
export const transformFor = createStructuralDirectiveTransform( export const transformFor = createStructuralDirectiveTransform(
'for', 'for',
(node, dir, context) => { (node, dir, context) => {
......
...@@ -164,17 +164,6 @@ export function findSlotName(slotDir: DirectiveNode) { ...@@ -164,17 +164,6 @@ export function findSlotName(slotDir: DirectiveNode) {
} }
} }
export function isScopedSlotVFor({ source }: CodegenVForScope) {
if (source.type !== NodeTypes.COMPOUND_EXPRESSION) {
return false
}
const first = source.children[0] as ExpressionNode
return (
first.type === NodeTypes.SIMPLE_EXPRESSION &&
first.content.includes(SCOPED_SLOT_IDENTIFIER)
)
}
function findCurrentVForValueAlias(context: TransformContext) { function findCurrentVForValueAlias(context: TransformContext) {
let scope: CodegenScope | null = context.currentScope let scope: CodegenScope | null = context.currentScope
while (scope) { while (scope) {
......
...@@ -63,7 +63,7 @@ function selectAllComponents( ...@@ -63,7 +63,7 @@ function selectAllComponents(
) { ) {
const components = mpInstance.selectAllComponents(selector) const components = mpInstance.selectAllComponents(selector)
components.forEach((component) => { components.forEach((component) => {
const ref = component.dataset.ref const ref = component.dataset.r
$refs[ref] = component.$vm || component $refs[ref] = component.$vm || component
if (__PLATFORM__ === 'mp-weixin') { if (__PLATFORM__ === 'mp-weixin') {
if (component.dataset.vueGeneric === 'scoped') { if (component.dataset.vueGeneric === 'scoped') {
...@@ -88,10 +88,10 @@ export function initRefs( ...@@ -88,10 +88,10 @@ export function initRefs(
Object.defineProperty(instance, 'refs', { Object.defineProperty(instance, 'refs', {
get() { get() {
const $refs: Record<string, any> = {} const $refs: Record<string, any> = {}
selectAllComponents(mpInstance, '.v-r', $refs) selectAllComponents(mpInstance, '.r', $refs)
const forComponents = mpInstance.selectAllComponents('.v-r-i-f') const forComponents = mpInstance.selectAllComponents('.r-i-f')
forComponents.forEach((component) => { forComponents.forEach((component) => {
const ref = component.dataset.ref const ref = component.dataset.r
if (!$refs[ref]) { if (!$refs[ref]) {
$refs[ref] = [] $refs[ref] = []
} }
......
...@@ -364,7 +364,7 @@ function initWxsCallMethods(methods, wxsCallMethods) { ...@@ -364,7 +364,7 @@ function initWxsCallMethods(methods, wxsCallMethods) {
function selectAllComponents(mpInstance, selector, $refs) { function selectAllComponents(mpInstance, selector, $refs) {
const components = mpInstance.selectAllComponents(selector); const components = mpInstance.selectAllComponents(selector);
components.forEach((component) => { components.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
$refs[ref] = component.$vm || component; $refs[ref] = component.$vm || component;
}); });
} }
...@@ -372,10 +372,10 @@ function initRefs(instance, mpInstance) { ...@@ -372,10 +372,10 @@ function initRefs(instance, mpInstance) {
Object.defineProperty(instance, 'refs', { Object.defineProperty(instance, 'refs', {
get() { get() {
const $refs = {}; const $refs = {};
selectAllComponents(mpInstance, '.v-r', $refs); selectAllComponents(mpInstance, '.r', $refs);
const forComponents = mpInstance.selectAllComponents('.v-r-i-f'); const forComponents = mpInstance.selectAllComponents('.r-i-f');
forComponents.forEach((component) => { forComponents.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
if (!$refs[ref]) { if (!$refs[ref]) {
$refs[ref] = []; $refs[ref] = [];
} }
......
...@@ -82,6 +82,10 @@ var source = { ...@@ -82,6 +82,10 @@ var source = {
condition: condition condition: condition
}; };
const nodeTransforms = [
uniCliShared.transformRef,
uniCliShared.createTransformComponentLink(uniCliShared.COMPONENT_BIND_LINK),
];
const options = { const options = {
vite: { vite: {
inject: { inject: {
...@@ -133,7 +137,7 @@ const options = { ...@@ -133,7 +137,7 @@ const options = {
extname: '.qml', extname: '.qml',
directive: 'qq:', directive: 'qq:',
compilerOptions: { compilerOptions: {
nodeTransforms: [uniCliShared.createTransformComponentLink(uniCliShared.COMPONENT_BIND_LINK)], nodeTransforms,
}, },
}, },
style: { style: {
......
...@@ -364,7 +364,7 @@ function initWxsCallMethods(methods, wxsCallMethods) { ...@@ -364,7 +364,7 @@ function initWxsCallMethods(methods, wxsCallMethods) {
function selectAllComponents(mpInstance, selector, $refs) { function selectAllComponents(mpInstance, selector, $refs) {
const components = mpInstance.selectAllComponents(selector); const components = mpInstance.selectAllComponents(selector);
components.forEach((component) => { components.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
$refs[ref] = component.$vm || component; $refs[ref] = component.$vm || component;
}); });
} }
...@@ -372,10 +372,10 @@ function initRefs(instance, mpInstance) { ...@@ -372,10 +372,10 @@ function initRefs(instance, mpInstance) {
Object.defineProperty(instance, 'refs', { Object.defineProperty(instance, 'refs', {
get() { get() {
const $refs = {}; const $refs = {};
selectAllComponents(mpInstance, '.v-r', $refs); selectAllComponents(mpInstance, '.r', $refs);
const forComponents = mpInstance.selectAllComponents('.v-r-i-f'); const forComponents = mpInstance.selectAllComponents('.r-i-f');
forComponents.forEach((component) => { forComponents.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
if (!$refs[ref]) { if (!$refs[ref]) {
$refs[ref] = []; $refs[ref] = [];
} }
......
...@@ -3,11 +3,16 @@ import path from 'path' ...@@ -3,11 +3,16 @@ import path from 'path'
import { import {
COMPONENT_BIND_LINK, COMPONENT_BIND_LINK,
createTransformComponentLink, createTransformComponentLink,
transformRef,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite' import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
import source from './project.config.json' import source from './project.config.json'
export const nodeTransforms = [
transformRef,
createTransformComponentLink(COMPONENT_BIND_LINK),
]
export const options: UniMiniProgramPluginOptions = { export const options: UniMiniProgramPluginOptions = {
vite: { vite: {
inject: { inject: {
...@@ -59,7 +64,7 @@ export const options: UniMiniProgramPluginOptions = { ...@@ -59,7 +64,7 @@ export const options: UniMiniProgramPluginOptions = {
extname: '.qml', extname: '.qml',
directive: 'qq:', directive: 'qq:',
compilerOptions: { compilerOptions: {
nodeTransforms: [createTransformComponentLink(COMPONENT_BIND_LINK)], nodeTransforms,
}, },
}, },
style: { style: {
......
...@@ -74,7 +74,10 @@ ${filter.code} ...@@ -74,7 +74,10 @@ ${filter.code}
extname: '.ttml', extname: '.ttml',
directive: 'tt:', directive: 'tt:',
compilerOptions: { compilerOptions: {
nodeTransforms: [uniCliShared.createTransformComponentLink(uniCliShared.COMPONENT_BIND_LINK)], nodeTransforms: [
uniCliShared.transformRef,
uniCliShared.createTransformComponentLink(uniCliShared.COMPONENT_BIND_LINK),
],
}, },
}, },
style: { style: {
......
...@@ -367,7 +367,7 @@ function initWxsCallMethods(methods, wxsCallMethods) { ...@@ -367,7 +367,7 @@ function initWxsCallMethods(methods, wxsCallMethods) {
function selectAllComponents(mpInstance, selector, $refs) { function selectAllComponents(mpInstance, selector, $refs) {
const components = mpInstance.selectAllComponents(selector); const components = mpInstance.selectAllComponents(selector);
components.forEach((component) => { components.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
$refs[ref] = component.$vm || component; $refs[ref] = component.$vm || component;
}); });
} }
...@@ -375,10 +375,10 @@ function initRefs(instance, mpInstance) { ...@@ -375,10 +375,10 @@ function initRefs(instance, mpInstance) {
Object.defineProperty(instance, 'refs', { Object.defineProperty(instance, 'refs', {
get() { get() {
const $refs = {}; const $refs = {};
selectAllComponents(mpInstance, '.v-r', $refs); selectAllComponents(mpInstance, '.r', $refs);
const forComponents = mpInstance.selectAllComponents('.v-r-i-f'); const forComponents = mpInstance.selectAllComponents('.r-i-f');
forComponents.forEach((component) => { forComponents.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
if (!$refs[ref]) { if (!$refs[ref]) {
$refs[ref] = []; $refs[ref] = [];
} }
......
...@@ -2,6 +2,7 @@ import path from 'path' ...@@ -2,6 +2,7 @@ import path from 'path'
import { import {
COMPONENT_BIND_LINK, COMPONENT_BIND_LINK,
createTransformComponentLink, createTransformComponentLink,
transformRef,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite' import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
...@@ -52,7 +53,10 @@ ${filter.code} ...@@ -52,7 +53,10 @@ ${filter.code}
extname: '.ttml', extname: '.ttml',
directive: 'tt:', directive: 'tt:',
compilerOptions: { compilerOptions: {
nodeTransforms: [createTransformComponentLink(COMPONENT_BIND_LINK)], nodeTransforms: [
transformRef,
createTransformComponentLink(COMPONENT_BIND_LINK),
],
}, },
}, },
style: { style: {
......
...@@ -120,7 +120,10 @@ ${filter.code} ...@@ -120,7 +120,10 @@ ${filter.code}
isCustomElement: (tag) => { isCustomElement: (tag) => {
return ['page-meta', 'navigation-bar', 'match-media'].includes(tag); return ['page-meta', 'navigation-bar', 'match-media'].includes(tag);
}, },
nodeTransforms: [uniCliShared.createTransformComponentLink(uniCliShared.COMPONENT_BIND_LINK)], nodeTransforms: [
uniCliShared.transformRef,
uniCliShared.createTransformComponentLink(uniCliShared.COMPONENT_BIND_LINK),
],
}, },
}, },
style: { style: {
......
...@@ -301,7 +301,7 @@ function initWxsCallMethods(methods, wxsCallMethods) { ...@@ -301,7 +301,7 @@ function initWxsCallMethods(methods, wxsCallMethods) {
function selectAllComponents(mpInstance, selector, $refs) { function selectAllComponents(mpInstance, selector, $refs) {
const components = mpInstance.selectAllComponents(selector); const components = mpInstance.selectAllComponents(selector);
components.forEach((component) => { components.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
$refs[ref] = component.$vm || component; $refs[ref] = component.$vm || component;
{ {
if (component.dataset.vueGeneric === 'scoped') { if (component.dataset.vueGeneric === 'scoped') {
...@@ -318,10 +318,10 @@ function initRefs(instance, mpInstance) { ...@@ -318,10 +318,10 @@ function initRefs(instance, mpInstance) {
Object.defineProperty(instance, 'refs', { Object.defineProperty(instance, 'refs', {
get() { get() {
const $refs = {}; const $refs = {};
selectAllComponents(mpInstance, '.v-r', $refs); selectAllComponents(mpInstance, '.r', $refs);
const forComponents = mpInstance.selectAllComponents('.v-r-i-f'); const forComponents = mpInstance.selectAllComponents('.r-i-f');
forComponents.forEach((component) => { forComponents.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
if (!$refs[ref]) { if (!$refs[ref]) {
$refs[ref] = []; $refs[ref] = [];
} }
......
...@@ -3,6 +3,7 @@ import path from 'path' ...@@ -3,6 +3,7 @@ import path from 'path'
import { import {
COMPONENT_BIND_LINK, COMPONENT_BIND_LINK,
createTransformComponentLink, createTransformComponentLink,
transformRef,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite' import { UniMiniProgramPluginOptions } from '@dcloudio/uni-mp-vite'
...@@ -71,7 +72,10 @@ ${filter.code} ...@@ -71,7 +72,10 @@ ${filter.code}
isCustomElement: (tag) => { isCustomElement: (tag) => {
return ['page-meta', 'navigation-bar', 'match-media'].includes(tag) return ['page-meta', 'navigation-bar', 'match-media'].includes(tag)
}, },
nodeTransforms: [createTransformComponentLink(COMPONENT_BIND_LINK)], nodeTransforms: [
transformRef,
createTransformComponentLink(COMPONENT_BIND_LINK),
],
}, },
}, },
style: { style: {
......
...@@ -364,7 +364,7 @@ function initWxsCallMethods(methods, wxsCallMethods) { ...@@ -364,7 +364,7 @@ function initWxsCallMethods(methods, wxsCallMethods) {
function selectAllComponents(mpInstance, selector, $refs) { function selectAllComponents(mpInstance, selector, $refs) {
const components = mpInstance.selectAllComponents(selector); const components = mpInstance.selectAllComponents(selector);
components.forEach((component) => { components.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
$refs[ref] = component.$vm || component; $refs[ref] = component.$vm || component;
}); });
} }
...@@ -372,10 +372,10 @@ function initRefs(instance, mpInstance) { ...@@ -372,10 +372,10 @@ function initRefs(instance, mpInstance) {
Object.defineProperty(instance, 'refs', { Object.defineProperty(instance, 'refs', {
get() { get() {
const $refs = {}; const $refs = {};
selectAllComponents(mpInstance, '.v-r', $refs); selectAllComponents(mpInstance, '.r', $refs);
const forComponents = mpInstance.selectAllComponents('.v-r-i-f'); const forComponents = mpInstance.selectAllComponents('.r-i-f');
forComponents.forEach((component) => { forComponents.forEach((component) => {
const ref = component.dataset.ref; const ref = component.dataset.r;
if (!$refs[ref]) { if (!$refs[ref]) {
$refs[ref] = []; $refs[ref] = [];
} }
......
...@@ -8462,7 +8462,7 @@ prettier@^1.18.2: ...@@ -8462,7 +8462,7 @@ prettier@^1.18.2:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
prettier@^2.2.1: prettier@^2.4.1:
version "2.4.1" version "2.4.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册