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

wip(mp): vFor

上级 f59898be
import { assert } from './testUtils'
describe('compiler: codegen', () => {
test('module mode preamble', () => {
assert(
`<view v-for="item in items" @click="onClick"></view>`,
`<view wx:for="{{a}}" wx:for-item="item" bindtap="{{a}}"></view>`,
`import { vOn as _vOn, vFor as _vFor } from "vue"
export function render(_ctx, _cache) {
return { a: _vFor(_ctx.items, item => { return { a: _vOn(_ctx.onClick) }; }) }
}`,
{ inline: false, mode: 'module', prefixIdentifiers: false }
)
})
test('module mode preamble w/ optimizeImports: true', () => {
assert(
`<view v-for="item in items" @click="onClick"></view>`,
`<view wx:for="{{a}}" wx:for-item="item" bindtap="{{a}}"></view>`,
`import { vOn as _vOn, vFor as _vFor } from "vue"
export function render(_ctx, _cache) {
return { a: _vFor(_ctx.items, item => { return { a: _vOn(_ctx.onClick) }; }) }
}`,
{ inline: false, mode: 'module' }
)
})
test('function mode preamble', () => {
assert(
`<view v-for="item in items" @click="onClick"></view>`,
`<view wx:for="{{a}}" wx:for-item="item" bindtap="{{a}}"></view>`,
`const _Vue = Vue
return function render(_ctx, _cache) {
with (_ctx) {
const { vOn: _vOn, vFor: _vFor } = _Vue
return { a: _vFor(items, item => { return { a: _vOn(onClick) }; }) }
}
}`,
{ inline: false, mode: 'function', prefixIdentifiers: false }
)
})
test('function mode preamble w/ prefixIdentifiers: true', () => {
assert(
`<view v-for="item in items" @click="onClick"></view>`,
`<view wx:for="{{a}}" wx:for-item="item" bindtap="{{a}}"></view>`,
`const { vOn: _vOn, vFor: _vFor } = Vue
return function render(_ctx, _cache) {
return { a: _vFor(_ctx.items, item => { return { a: _vOn(_ctx.onClick) }; }) }
}`,
{ inline: false, mode: 'function' }
)
})
test('static text', () => {
assert(
`hello`,
`hello`,
`(_ctx, _cache) => {
return {}
}`
)
})
test('interpolation', () => {
assert(
`{{hello}}`,
`{{a}}`,
`(_ctx, _cache) => {
return { a: _toDisplayString(_ctx.hello) }
}`
)
})
test('comment', () => {
assert(
`<!--foo-->`,
``,
`(_ctx, _cache) => {
return {}
}`
)
})
test('compound expression', () => {
assert(
`{{foo}}{{bar}}nested`,
`{{a}}{{b}}nested`,
`(_ctx, _cache) => {
return { a: _toDisplayString(_ctx.foo), b: _toDisplayString(_ctx.bar) }
}`
)
})
})
import { compile } from '../src/index'
function assert(template: string, templateCode: string, renderCode: string) {
const res = compile(template, {
filename: 'foo.vue',
prefixIdentifiers: true,
inline: true,
emitFile({ source }) {
// console.log(source)
expect(source).toBe(templateCode)
return ''
},
})
// expect(res.template).toBe(templateCode)
// expect(res.code).toBe(renderCode)
// console.log(require('util').inspect(res.code, { colors: true, depth: null }))
// console.log(require('util').inspect(res, { colors: true, depth: null }))
expect(res.code).toBe(renderCode)
}
describe('compiler', () => {
test(`v-for directive`, () => {
assert(
`<view><view v-for="item in items" :key="item.uid" :data-title="data.title" :data-id="item.id">{{item.title}}</view></view>`,
`<view><view wx:for="{{b}}" wx:for-item="item" wx:key="b" data-title="{{a}}" data-id="{{item.c}}">{{item.a}}</view></view>`,
`(_ctx, _cache) => {
return {
a: _ctx.data.title,
b: vFor(_ctx.items, item => {
return {
a: item.title,
b: item.uid,
c: item.id
};
})
}
}`
)
})
test(`v-for directive with key`, () => {
assert(
`<view><view v-for="(item, i) in items" :data-id="item.id">{{item.title}}</view></view>`,
`<view><view wx:for="{{a}}" wx:for-item="item" wx:for-index="i" data-id="{{item.b}}">{{item.a}}</view></view>`,
`(_ctx, _cache) => {
return {
a: vFor(_ctx.items, (item, i) => {
return {
a: item.title,
b: item.id
};
})
}
}`
)
})
test(`generate v-for with v-if`, () => {
assert(
`<view v-for="item in items"><view v-if="item.show">{{item.title}}</view></view>`,
`<view wx:for="{{a}}" wx:for-item="item"><view wx:if="{{item.b}}">{{item.a}}</view></view>`,
`(_ctx, _cache) => {
return {
a: vFor(_ctx.items, item => {
return {
b: item.show,
...(item.show ? {
a: item.title
} : {})
};
})
}
}`
)
})
test(`generate v-if directive`, () => {
assert(
`<view v-if="show">hello</view>`,
`<view wx:if="{{a}}">hello</view>`,
`(_ctx, _cache) => {
return {
a: _ctx.show,
...(_ctx.show ? {} : {})
}
}`
)
})
test(`generate v-else directive`, () => {
assert(
`<view><view v-if="show">hello</view><view v-else>world</view></view>`,
`<view><view wx:if="{{a}}">hello</view><view wx:else>world</view></view>`,
`(_ctx, _cache) => {
return {
a: _ctx.show,
...(_ctx.show ? {} : {})
}
}`
)
})
test(`generate v-else-if directive`, () => {
assert(
`<view><view v-if="show">hello</view><view v-else-if="hide">world</view></view>`,
`<view><view wx:if="{{a}}">hello</view><view wx:elif="{{b}}">world</view></view>`,
`(_ctx, _cache) => {
return {
a: _ctx.show,
...(_ctx.show ? {} : _ctx.hide ? {} : {}),
b: _ctx.hide
}
}`
)
})
test(`generate v-else-if with v-else directive`, () => {
assert(
`<view><view v-if="show">hello</view><view v-else-if="hide">world</view><view v-else>bye</view></view>`,
`<view><view wx:if="{{a}}">hello</view><view wx:elif="{{b}}">world</view><view wx:else>bye</view></view>`,
`(_ctx, _cache) => {
return {
a: _ctx.show,
...(_ctx.show ? {} : _ctx.hide ? {} : {}),
b: _ctx.hide
}
}`
)
})
test(`generate multi v-else-if with v-else directive`, () => {
assert(
`<view><view v-if="show">hello</view><view v-else-if="hide">world</view><view v-else-if="3">elseif</view><view v-else>bye</view></view>`,
`<view><view wx:if="{{a}}">hello</view><view wx:elif="{{b}}">world</view><view wx:elif="{{3}}">elseif</view><view wx:else>bye</view></view>`,
`(_ctx, _cache) => {
return {
a: _ctx.show,
...(_ctx.show ? {} : _ctx.hide ? {} : 3 ? {} : {}),
b: _ctx.hide
}
}`
)
})
})
...@@ -33,12 +33,10 @@ function assert( ...@@ -33,12 +33,10 @@ function assert(
describe('compiler', () => { describe('compiler', () => {
test('should wrap as function if expression is inline statement', () => { test('should wrap as function if expression is inline statement', () => {
assert( assert(
`<div v-on:click="foo" />`, `{{hello}}`,
`<view bindtap="{{a}}"/>`, `{{a}}`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _toDisplayString(_ctx.hello) }
a: _vOn(_ctx.foo)
}
}`, }`,
{} {}
) )
......
...@@ -10,6 +10,7 @@ export function assert( ...@@ -10,6 +10,7 @@ export function assert(
options: CompilerOptions = {} options: CompilerOptions = {}
) { ) {
const res = compile(template, { const res = compile(template, {
mode: 'module',
filename: 'foo.vue', filename: 'foo.vue',
prefixIdentifiers: true, prefixIdentifiers: true,
inline: true, inline: true,
......
...@@ -29,11 +29,7 @@ describe(`compiler: v-for`, () => { ...@@ -29,11 +29,7 @@ describe(`compiler: v-for`, () => {
`<view v-for="index in 5" />`, `<view v-for="index in 5" />`,
`<view wx:for="{{a}}" wx:for-item="index"/>`, `<view wx:for="{{a}}" wx:for-item="index"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor([1, 2, 3, 4, 5], index => { return {}; }) }
a: _vFor([1, 2, 3, 4, 5], index => {
return {};
})
}
}` }`
) )
}) })
...@@ -42,11 +38,7 @@ return { ...@@ -42,11 +38,7 @@ return {
`<view v-for="(item) in items" />`, `<view v-for="(item) in items" />`,
`<view wx:for="{{a}}" wx:for-item="item"/>`, `<view wx:for="{{a}}" wx:for-item="item"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return {}; }) }
a: _vFor(_ctx.items, item => {
return {};
})
}
}` }`
) )
}) })
...@@ -55,14 +47,7 @@ return { ...@@ -55,14 +47,7 @@ return {
`<view v-for="({ id, value }) in items" />`, `<view v-for="({ id, value }) in items" />`,
`<view wx:for="{{a}}" wx:for-item="v0"/>`, `<view wx:for="{{a}}" wx:for-item="v0"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, ({ id, value }) => { return {}; }) }
a: _vFor(_ctx.items, ({
id,
value
}) => {
return {};
})
}
}` }`
) )
}) })
...@@ -71,11 +56,7 @@ return { ...@@ -71,11 +56,7 @@ return {
`<view v-for="([ id, value ]) in items" />`, `<view v-for="([ id, value ]) in items" />`,
`<view wx:for="{{a}}" wx:for-item="v0"/>`, `<view wx:for="{{a}}" wx:for-item="v0"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, ([id, value]) => { return {}; }) }
a: _vFor(_ctx.items, ([id, value]) => {
return {};
})
}
}` }`
) )
}) })
...@@ -84,11 +65,7 @@ return { ...@@ -84,11 +65,7 @@ return {
`<view v-for="(item, key) in items" />`, `<view v-for="(item, key) in items" />`,
`<view wx:for="{{a}}" wx:for-item="item" wx:for-index="key"/>`, `<view wx:for="{{a}}" wx:for-item="item" wx:for-index="key"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, (item, key) => { return {}; }) }
a: _vFor(_ctx.items, (item, key) => {
return {};
})
}
}` }`
) )
}) })
...@@ -97,11 +74,7 @@ return { ...@@ -97,11 +74,7 @@ return {
`<view v-for="(item, key, index) in items" />`, `<view v-for="(item, key, index) in items" />`,
`<view wx:for="{{a}}" wx:for-item="item" wx:for-index="key"/>`, `<view wx:for="{{a}}" wx:for-item="item" wx:for-index="key"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, (item, key, index) => { return {}; }) }
a: _vFor(_ctx.items, (item, key, index) => {
return {};
})
}
}` }`
) )
}) })
...@@ -110,11 +83,7 @@ return { ...@@ -110,11 +83,7 @@ return {
`<view v-for="(value,,index) in items" />`, `<view v-for="(value,,index) in items" />`,
`<view wx:for="{{a}}" wx:for-item="value"/>`, `<view wx:for="{{a}}" wx:for-item="value"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, (value, __, index) => { return {}; }) }
a: _vFor(_ctx.items, (value, __, index) => {
return {};
})
}
}` }`
) )
}) })
...@@ -123,11 +92,7 @@ return { ...@@ -123,11 +92,7 @@ return {
`<view v-for="(,,index) in items" />`, `<view v-for="(,,index) in items" />`,
`<view wx:for="{{a}}" wx:for-item="v0"/>`, `<view wx:for="{{a}}" wx:for-item="v0"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, (_, __, index) => { return {}; }) }
a: _vFor(_ctx.items, (_, __, index) => {
return {};
})
}
}` }`
) )
}) })
...@@ -136,11 +101,7 @@ return { ...@@ -136,11 +101,7 @@ return {
`<view v-for="item in items" />`, `<view v-for="item in items" />`,
`<view wx:for="{{a}}" wx:for-item="item"/>`, `<view wx:for="{{a}}" wx:for-item="item"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return {}; }) }
a: _vFor(_ctx.items, item => {
return {};
})
}
}` }`
) )
}) })
...@@ -149,11 +110,7 @@ return { ...@@ -149,11 +110,7 @@ return {
`<view v-for="item, key in items" />`, `<view v-for="item, key in items" />`,
`<view wx:for="{{a}}" wx:for-item="item" wx:for-index="key"/>`, `<view wx:for="{{a}}" wx:for-item="item" wx:for-index="key"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, (item, key) => { return {}; }) }
a: _vFor(_ctx.items, (item, key) => {
return {};
})
}
}` }`
) )
}) })
...@@ -162,11 +119,7 @@ return { ...@@ -162,11 +119,7 @@ return {
`<view v-for="value, key, index in items" />`, `<view v-for="value, key, index in items" />`,
`<view wx:for="{{a}}" wx:for-item="value" wx:for-index="key"/>`, `<view wx:for="{{a}}" wx:for-item="value" wx:for-index="key"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, (value, key, index) => { return {}; }) }
a: _vFor(_ctx.items, (value, key, index) => {
return {};
})
}
}` }`
) )
}) })
...@@ -175,11 +128,7 @@ return { ...@@ -175,11 +128,7 @@ return {
`<view v-for="value, , index in items" />`, `<view v-for="value, , index in items" />`,
`<view wx:for="{{a}}" wx:for-item="value"/>`, `<view wx:for="{{a}}" wx:for-item="value"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, (value, __, index) => { return {}; }) }
a: _vFor(_ctx.items, (value, __, index) => {
return {};
})
}
}` }`
) )
}) })
...@@ -188,11 +137,7 @@ return { ...@@ -188,11 +137,7 @@ return {
`<view v-for=", , index in items" />`, `<view v-for=", , index in items" />`,
`<view wx:for="{{a}}" wx:for-item="v0"/>`, `<view wx:for="{{a}}" wx:for-item="v0"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, (_, __, index) => { return {}; }) }
a: _vFor(_ctx.items, (_, __, index) => {
return {};
})
}
}` }`
) )
}) })
...@@ -201,11 +146,7 @@ return { ...@@ -201,11 +146,7 @@ return {
`<template v-for="item in items">hello<view/></template>`, `<template v-for="item in items">hello<view/></template>`,
`<block wx:for="{{a}}" wx:for-item="item">hello<view/></block>`, `<block wx:for="{{a}}" wx:for-item="item">hello<view/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return {}; }) }
a: _vFor(_ctx.items, item => {
return {};
})
}
}` }`
) )
}) })
...@@ -214,11 +155,7 @@ return { ...@@ -214,11 +155,7 @@ return {
`<template v-for="item in items"><slot/></template>`, `<template v-for="item in items"><slot/></template>`,
`<block wx:for="{{a}}" wx:for-item="item"><slot/></block>`, `<block wx:for="{{a}}" wx:for-item="item"><slot/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return {}; }) }
a: _vFor(_ctx.items, item => {
return {};
})
}
}` }`
) )
}) })
...@@ -228,14 +165,7 @@ return { ...@@ -228,14 +165,7 @@ return {
`<template v-for="item in items" :key="item.id"><view :id="item.id" /></template>`, `<template v-for="item in items" :key="item.id"><view :id="item.id" /></template>`,
`<block wx:for="{{a}}" wx:for-item="item" wx:key="b"><view id="{{item.a}}"/></block>`, `<block wx:for="{{a}}" wx:for-item="item" wx:key="b"><view id="{{item.a}}"/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return { a: item.id, b: item.id }; }) }
a: _vFor(_ctx.items, item => {
return {
a: item.id,
b: item.id
};
})
}
}` }`
) )
}) })
...@@ -244,11 +174,7 @@ return { ...@@ -244,11 +174,7 @@ return {
`<slot v-for="item in items"></slot>`, `<slot v-for="item in items"></slot>`,
`<slot wx:for="{{a}}" wx:for-item="item"></slot>`, `<slot wx:for="{{a}}" wx:for-item="item"></slot>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return {}; }) }
a: _vFor(_ctx.items, item => {
return {};
})
}
}` }`
) )
}) })
...@@ -257,11 +183,7 @@ return { ...@@ -257,11 +183,7 @@ return {
`<view v-for="(item) in items" :key="item" />`, `<view v-for="(item) in items" :key="item" />`,
`<view wx:for="{{a}}" wx:for-item="item" wx:key="*this"/>`, `<view wx:for="{{a}}" wx:for-item="item" wx:key="*this"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return {}; }) }
a: _vFor(_ctx.items, item => {
return {};
})
}
}` }`
) )
}) })
...@@ -270,11 +192,7 @@ return { ...@@ -270,11 +192,7 @@ return {
`<template v-for="item in items" :key="item">hello<view/></template>`, `<template v-for="item in items" :key="item">hello<view/></template>`,
`<block wx:for="{{a}}" wx:for-item="item" wx:key="*this">hello<view/></block>`, `<block wx:for="{{a}}" wx:for-item="item" wx:key="*this">hello<view/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return {}; }) }
a: _vFor(_ctx.items, item => {
return {};
})
}
}` }`
) )
}) })
...@@ -283,14 +201,7 @@ return { ...@@ -283,14 +201,7 @@ return {
`<view v-if="ok" v-for="i in list"/>`, `<view v-if="ok" v-for="i in list"/>`,
`<view wx:if="{{b}}" wx:for="{{a}}" wx:for-item="i"/>`, `<view wx:if="{{b}}" wx:for="{{a}}" wx:for-item="i"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { b: _ctx.ok, ...(_ctx.ok ? { a: _vFor(_ctx.list, i => { return {}; }) } : {}) }
b: _ctx.ok,
...(_ctx.ok ? {
a: _vFor(_ctx.list, i => {
return {};
})
} : {})
}
}` }`
) )
}) })
...@@ -300,14 +211,7 @@ return { ...@@ -300,14 +211,7 @@ return {
`<template v-if="ok" v-for="i in list"/>`, `<template v-if="ok" v-for="i in list"/>`,
`<block wx:if="{{b}}" wx:for="{{a}}" wx:for-item="i"/>`, `<block wx:if="{{b}}" wx:for="{{a}}" wx:for-item="i"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { b: _ctx.ok, ...(_ctx.ok ? { a: _vFor(_ctx.list, i => { return {}; }) } : {}) }
b: _ctx.ok,
...(_ctx.ok ? {
a: _vFor(_ctx.list, i => {
return {};
})
} : {})
}
}` }`
) )
}) })
...@@ -708,13 +612,7 @@ return { ...@@ -708,13 +612,7 @@ return {
`<view v-for="item in items" :key="itemKey(item)">test</view>`, `<view v-for="item in items" :key="itemKey(item)">test</view>`,
`<view wx:for="{{a}}" wx:for-item="item" wx:key="a">test</view>`, `<view wx:for="{{a}}" wx:for-item="item" wx:key="a">test</view>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return { a: _ctx.itemKey(item) }; }) }
a: _vFor(_ctx.items, item => {
return {
a: _ctx.itemKey(item)
};
})
}
}` }`
) )
}) })
...@@ -725,13 +623,7 @@ return { ...@@ -725,13 +623,7 @@ return {
`<template v-for="item in items" :key="itemKey(item)">test</template>`, `<template v-for="item in items" :key="itemKey(item)">test</template>`,
`<block wx:for="{{a}}" wx:for-item="item" wx:key="a">test</block>`, `<block wx:for="{{a}}" wx:for-item="item" wx:key="a">test</block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return { a: _ctx.itemKey(item) }; }) }
a: _vFor(_ctx.items, item => {
return {
a: _ctx.itemKey(item)
};
})
}
}` }`
) )
}) })
...@@ -741,11 +633,7 @@ return { ...@@ -741,11 +633,7 @@ return {
`<template v-for="item in items" key="key">test</template>`, `<template v-for="item in items" key="key">test</template>`,
`<block wx:for="{{a}}" wx:for-item="item" key="key">test</block>`, `<block wx:for="{{a}}" wx:for-item="item" key="key">test</block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vFor(_ctx.items, item => { return {}; }) }
a: _vFor(_ctx.items, item => {
return {};
})
}
}` }`
) )
}) })
......
...@@ -29,10 +29,7 @@ describe(`compiler: v-if`, () => { ...@@ -29,10 +29,7 @@ describe(`compiler: v-if`, () => {
`<view v-if="ok"/>`, `<view v-if="ok"/>`,
`<view wx:if="{{a}}"/>`, `<view wx:if="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
a: _ctx.ok,
...(_ctx.ok ? {} : {})
}
}` }`
) )
}) })
...@@ -41,10 +38,7 @@ return { ...@@ -41,10 +38,7 @@ return {
`<template v-if="ok"><view/>hello<view/></template>`, `<template v-if="ok"><view/>hello<view/></template>`,
`<block wx:if="{{a}}"><view/>hello<view/></block>`, `<block wx:if="{{a}}"><view/>hello<view/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
a: _ctx.ok,
...(_ctx.ok ? {} : {})
}
}` }`
) )
}) })
...@@ -53,10 +47,7 @@ return { ...@@ -53,10 +47,7 @@ return {
`<template v-if="ok"><slot/></template>`, `<template v-if="ok"><slot/></template>`,
`<block wx:if="{{a}}"><slot/></block>`, `<block wx:if="{{a}}"><slot/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
a: _ctx.ok,
...(_ctx.ok ? {} : {})
}
}` }`
) )
}) })
...@@ -65,10 +56,7 @@ return { ...@@ -65,10 +56,7 @@ return {
`<slot v-if="ok"/>`, `<slot v-if="ok"/>`,
`<slot wx:if="{{a}}"/>`, `<slot wx:if="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
a: _ctx.ok,
...(_ctx.ok ? {} : {})
}
}` }`
) )
}) })
...@@ -77,10 +65,7 @@ return { ...@@ -77,10 +65,7 @@ return {
`<Component v-if="ok"></Component>`, `<Component v-if="ok"></Component>`,
`<Component wx:if="{{a}}"></Component>`, `<Component wx:if="{{a}}"></Component>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
a: _ctx.ok,
...(_ctx.ok ? {} : {})
}
}` }`
) )
}) })
...@@ -89,10 +74,7 @@ return { ...@@ -89,10 +74,7 @@ return {
`<view v-if="ok"/><view v-else/>`, `<view v-if="ok"/><view v-else/>`,
`<view wx:if="{{a}}"/><view wx:else/>`, `<view wx:if="{{a}}"/><view wx:else/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : {}) }
a: _ctx.ok,
...(_ctx.ok ? {} : {})
}
}` }`
) )
}) })
...@@ -101,11 +83,7 @@ return { ...@@ -101,11 +83,7 @@ return {
`<view v-if="ok"/><view v-else-if="orNot"/>`, `<view v-if="ok"/><view v-else-if="orNot"/>`,
`<view wx:if="{{a}}"/><view wx:elif="{{b}}"/>`, `<view wx:if="{{a}}"/><view wx:elif="{{b}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.orNot ? {} : {}), b: _ctx.orNot }
a: _ctx.ok,
...(_ctx.ok ? {} : _ctx.orNot ? {} : {}),
b: _ctx.orNot
}
}` }`
) )
}) })
...@@ -114,11 +92,7 @@ return { ...@@ -114,11 +92,7 @@ return {
`<view v-if="ok"/><view v-else-if="orNot"/><template v-else>fine</template>`, `<view v-if="ok"/><view v-else-if="orNot"/><template v-else>fine</template>`,
`<view wx:if="{{a}}"/><view wx:elif="{{b}}"/><block wx:else>fine</block>`, `<view wx:if="{{a}}"/><view wx:elif="{{b}}"/><block wx:else>fine</block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.orNot ? {} : {}), b: _ctx.orNot }
a: _ctx.ok,
...(_ctx.ok ? {} : _ctx.orNot ? {} : {}),
b: _ctx.orNot
}
}` }`
) )
}) })
...@@ -145,11 +119,7 @@ return { ...@@ -145,11 +119,7 @@ return {
`<view v-if="ok"/><view v-else-if="orNot"/><view v-else-if="3"/><template v-else>fine</template>`, `<view v-if="ok"/><view v-else-if="orNot"/><view v-else-if="3"/><template v-else>fine</template>`,
`<view wx:if="{{a}}"/><view wx:elif="{{b}}"/><view wx:elif="{{3}}"/><block wx:else>fine</block>`, `<view wx:if="{{a}}"/><view wx:elif="{{b}}"/><view wx:elif="{{3}}"/><block wx:else>fine</block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.orNot ? {} : 3 ? {} : {}), b: _ctx.orNot }
a: _ctx.ok,
...(_ctx.ok ? {} : _ctx.orNot ? {} : 3 ? {} : {}),
b: _ctx.orNot
}
}` }`
) )
}) })
...@@ -164,11 +134,7 @@ return { ...@@ -164,11 +134,7 @@ return {
`, `,
`<view wx:if="{{a}}"/><view wx:elif="{{b}}"/><block wx:else>fine</block>`, `<view wx:if="{{a}}"/><view wx:elif="{{b}}"/><block wx:else>fine</block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.orNot ? {} : {}), b: _ctx.orNot }
a: _ctx.ok,
...(_ctx.ok ? {} : _ctx.orNot ? {} : {}),
b: _ctx.orNot
}
}` }`
) )
}) })
...@@ -177,11 +143,7 @@ return { ...@@ -177,11 +143,7 @@ return {
`<view v-if="ok"/> <view v-else-if="no"/> <view v-else/>`, `<view v-if="ok"/> <view v-else-if="no"/> <view v-else/>`,
`<view wx:if="{{a}}"/><view wx:elif="{{b}}"/><view wx:else/>`, `<view wx:if="{{a}}"/><view wx:elif="{{b}}"/><view wx:else/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _ctx.ok, ...(_ctx.ok ? {} : _ctx.no ? {} : {}), b: _ctx.no }
a: _ctx.ok,
...(_ctx.ok ? {} : _ctx.no ? {} : {}),
b: _ctx.no
}
}` }`
) )
}) })
...@@ -201,13 +163,7 @@ return { ...@@ -201,13 +163,7 @@ return {
`, `,
`<block wx:if="{{b}}"><view wx:if="{{a}}"></view><view wx:else/><view/></block>`, `<block wx:if="{{b}}"><view wx:if="{{a}}"></view><view wx:else/><view/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { b: _ctx.ok, ...(_ctx.ok ? { a: _ctx.ok2, ...(_ctx.ok2 ? {} : {}) } : {}) }
b: _ctx.ok,
...(_ctx.ok ? {
a: _ctx.ok2,
...(_ctx.ok2 ? {} : {})
} : {})
}
}` }`
) )
}) })
......
...@@ -17,9 +17,7 @@ describe('compiler: transform v-on', () => { ...@@ -17,9 +17,7 @@ describe('compiler: transform v-on', () => {
`<view v-on:click="onClick"/>`, `<view v-on:click="onClick"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn(_ctx.onClick) }
a: _vOn(_ctx.onClick)
}
}` }`
) )
}) })
...@@ -37,9 +35,7 @@ return { ...@@ -37,9 +35,7 @@ return {
`<view @click="i++"/>`, `<view @click="i++"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn($event => _ctx.i++) }
a: _vOn($event => _ctx.i++)
}
}` }`
) )
}) })
...@@ -48,13 +44,7 @@ return { ...@@ -48,13 +44,7 @@ return {
`<view @click="foo();bar()"/>`, `<view @click="foo();bar()"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn($event => { _ctx.foo(); _ctx.bar(); }) }
a: _vOn($event => {
_ctx.foo();
_ctx.bar();
})
}
}` }`
) )
}) })
...@@ -63,14 +53,13 @@ return { ...@@ -63,14 +53,13 @@ return {
`<view @click="\nfoo();\nbar()\n"/>`, `<view @click="\nfoo();\nbar()\n"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { with (_ctx) {
a: _vOn($event => { const { vOn: _vOn } = _Vue
foo();
bar(); return { a: _vOn($event => { foo(); bar(); }) }
}) }
}
}`, }`,
{ prefixIdentifiers: false } { prefixIdentifiers: false, mode: 'function' }
) )
}) })
test('inline statement w/ prefixIdentifiers: true', () => { test('inline statement w/ prefixIdentifiers: true', () => {
...@@ -78,9 +67,7 @@ return { ...@@ -78,9 +67,7 @@ return {
`<view @click="foo($event)"/>`, `<view @click="foo($event)"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn($event => _ctx.foo($event)) }
a: _vOn($event => _ctx.foo($event))
}
}` }`
) )
}) })
...@@ -89,13 +76,7 @@ return { ...@@ -89,13 +76,7 @@ return {
`<view @click="foo($event);bar()"/>`, `<view @click="foo($event);bar()"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn($event => { _ctx.foo($event); _ctx.bar(); }) }
a: _vOn($event => {
_ctx.foo($event);
_ctx.bar();
})
}
}` }`
) )
}) })
...@@ -104,9 +85,7 @@ return { ...@@ -104,9 +85,7 @@ return {
`<view @click="$event => foo($event)"/>`, `<view @click="$event => foo($event)"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn($event => _ctx.foo($event)) }
a: _vOn($event => _ctx.foo($event))
}
}` }`
) )
}) })
...@@ -119,11 +98,7 @@ return { ...@@ -119,11 +98,7 @@ return {
"/>`, "/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn($event => { _ctx.foo($event); }) }
a: _vOn($event => {
_ctx.foo($event);
})
}
}` }`
) )
}) })
...@@ -136,11 +111,7 @@ return { ...@@ -136,11 +111,7 @@ return {
"/>`, "/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn(function ($event) { _ctx.foo($event); }) }
a: _vOn(function ($event) {
_ctx.foo($event);
})
}
}` }`
) )
}) })
...@@ -149,12 +120,15 @@ return { ...@@ -149,12 +120,15 @@ return {
`<view @click="a['b' + c]"/>`, `<view @click="a['b' + c]"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { with (_ctx) {
a: _vOn(a['b' + c]) const { vOn: _vOn } = _Vue
}
return { a: _vOn(a['b' + c]) }
}
}`, }`,
{ {
prefixIdentifiers: false, prefixIdentifiers: false,
mode: 'function',
} }
) )
}) })
...@@ -163,9 +137,7 @@ return { ...@@ -163,9 +137,7 @@ return {
`<view @click="a['b' + c]"/>`, `<view @click="a['b' + c]"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn(_ctx.a['b' + _ctx.c]) }
a: _vOn(_ctx.a['b' + _ctx.c])
}
}` }`
) )
}) })
...@@ -174,9 +146,7 @@ return { ...@@ -174,9 +146,7 @@ return {
`<view @click="e => foo(e)"/>`, `<view @click="e => foo(e)"/>`,
`<view bindtap="{{a}}"/>`, `<view bindtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn(e => _ctx.foo(e)) }
a: _vOn(e => _ctx.foo(e))
}
}` }`
) )
}) })
...@@ -208,9 +178,7 @@ return { ...@@ -208,9 +178,7 @@ return {
`<view v-on:foo-bar="onMount"/>`, `<view v-on:foo-bar="onMount"/>`,
`<view bind:foo-bar="{{a}}"/>`, `<view bind:foo-bar="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn(_ctx.onMount) }
a: _vOn(_ctx.onMount)
}
}` }`
) )
}) })
...@@ -220,9 +188,7 @@ return { ...@@ -220,9 +188,7 @@ return {
`<view v-on:vnode-mounted="onMount"/>`, `<view v-on:vnode-mounted="onMount"/>`,
`<view bind:vnode-mounted="{{a}}"/>`, `<view bind:vnode-mounted="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn(_ctx.onMount) }
a: _vOn(_ctx.onMount)
}
}` }`
) )
}) })
...@@ -233,9 +199,7 @@ return { ...@@ -233,9 +199,7 @@ return {
`<view v-on:click.prevent />`, `<view v-on:click.prevent />`,
`<view catchtap="{{a}}"/>`, `<view catchtap="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { return { a: _vOn(() => {}) }
a: _vOn(() => {})
}
}` }`
) )
}) })
......
...@@ -5,6 +5,7 @@ import { ...@@ -5,6 +5,7 @@ import {
helperNameMap, helperNameMap,
InterpolationNode, InterpolationNode,
NodeTypes, NodeTypes,
RootNode,
SimpleExpressionNode, SimpleExpressionNode,
TextNode, TextNode,
TO_DISPLAY_STRING, TO_DISPLAY_STRING,
...@@ -13,11 +14,40 @@ import { default as babelGenerate } from '@babel/generator' ...@@ -13,11 +14,40 @@ import { default as babelGenerate } from '@babel/generator'
import { CodegenOptions, CodegenScope } from './options' import { CodegenOptions, CodegenScope } from './options'
import { createObjectExpression } from './ast' import { createObjectExpression } from './ast'
interface CodegenContext extends CodegenOptions {
code: string
indentLevel: number
push(code: string, node?: CodegenNode): void
indent(): void
deindent(withoutNewLine?: boolean): void
newline(): void
}
export function generate( export function generate(
ast: RootNode,
scope: CodegenScope, scope: CodegenScope,
options: CodegenOptions options: CodegenOptions
): Omit<CodegenResult, 'ast'> { ): Omit<CodegenResult, 'ast'> {
const context = createCodegenContext(ast, options)
const { mode, push, indent, deindent, newline, prefixIdentifiers } = context
const hasHelpers = ast.helpers.length > 0
const useWithBlock = !prefixIdentifiers && mode !== 'module'
const isSetupInlined = !!options.inline const isSetupInlined = !!options.inline
// preambles
// in setup() inline mode, the preamble is generated in a sub context
// and returned separately.
const preambleContext = isSetupInlined
? createCodegenContext(ast, options)
: context
if (mode === 'module') {
genModulePreamble(ast, preambleContext, isSetupInlined)
} else {
genFunctionPreamble(ast, preambleContext)
}
// enter render function // enter render function
const functionName = `render` const functionName = `render`
const args = ['_ctx', '_cache'] const args = ['_ctx', '_cache']
...@@ -28,23 +58,126 @@ export function generate( ...@@ -28,23 +58,126 @@ export function generate(
const signature = options.isTS const signature = options.isTS
? args.map((arg) => `${arg}: any`).join(',') ? args.map((arg) => `${arg}: any`).join(',')
: args.join(', ') : args.join(', ')
const codes: string[] = []
if (isSetupInlined) { if (isSetupInlined) {
codes.push(`(${signature}) => {`) push(`(${signature}) => {`)
} else { } else {
codes.push(`\nexport function ${functionName}(${signature}) {`) push(`function ${functionName}(${signature}) {`)
}
indent()
if (useWithBlock) {
push(`with (_ctx) {`)
indent()
if (hasHelpers) {
push(
`const { ${ast.helpers
.map((s) => `${helperNameMap[s]}: _${helperNameMap[s]}`)
.join(', ')} } = _Vue`
)
push(`\n`)
newline()
}
} }
codes.push(
`return ` +
babelGenerate(createObjectExpression(scope.properties), {
// concise: true,
}).code
)
codes.push(`}`)
push(`return `)
push(
babelGenerate(createObjectExpression(scope.properties), {
concise: true,
}).code
)
if (useWithBlock) {
deindent()
push(`}`)
}
deindent()
push(`}`)
return { return {
code: codes.join('\n'), code: context.code,
preamble: '', preamble: isSetupInlined ? preambleContext.code : ``,
}
}
function createCodegenContext(
ast: RootNode,
{
mode = 'function',
prefixIdentifiers = mode === 'module',
filename = `template.vue.html`,
scopeId = null,
runtimeGlobalName = `Vue`,
runtimeModuleName = `vue`,
isTS = false,
}: CodegenOptions
): CodegenContext {
const context: CodegenContext = {
mode,
prefixIdentifiers,
filename,
scopeId,
runtimeGlobalName,
runtimeModuleName,
isTS,
code: ``,
indentLevel: 0,
push(code, node) {
context.code += code
},
indent() {
newline(++context.indentLevel)
},
deindent(withoutNewLine = false) {
if (withoutNewLine) {
--context.indentLevel
} else {
newline(--context.indentLevel)
}
},
newline() {
newline(context.indentLevel)
},
}
function newline(n: number) {
context.push('\n' + ` `.repeat(n))
}
return context
}
function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
const { prefixIdentifiers, push, newline, runtimeGlobalName } = context
const VueBinding = runtimeGlobalName
const aliasHelper = (s: symbol) => `${helperNameMap[s]}: _${helperNameMap[s]}`
if (ast.helpers.length > 0) {
if (prefixIdentifiers) {
push(
`const { ${ast.helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`
)
} else {
push(`const _Vue = ${VueBinding}\n`)
}
}
newline()
push(`return `)
}
function genModulePreamble(
ast: RootNode,
context: CodegenContext,
inline?: boolean
) {
const { push, newline, runtimeModuleName } = context
if (ast.helpers.length) {
push(
`import { ${ast.helpers
.map((s) => `${helperNameMap[s]} as _${helperNameMap[s]}`)
.join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
)
}
newline()
if (!inline) {
push(`export `)
} }
} }
......
...@@ -55,7 +55,7 @@ export function baseCompile(template: string, options: CompilerOptions = {}) { ...@@ -55,7 +55,7 @@ export function baseCompile(template: string, options: CompilerOptions = {}) {
), ),
}) })
) )
const result = extend(generate(context.scope, options), { ast }) const result = extend(generate(ast, context.scope, options), { ast })
if (options.filename && options.miniProgram?.emitFile) { if (options.filename && options.miniProgram?.emitFile) {
genTemplate(ast, { genTemplate(ast, {
filename: options.filename, filename: options.filename,
......
...@@ -105,6 +105,10 @@ export function isVForScope(scope: CodegenScope): scope is CodegenVForScope { ...@@ -105,6 +105,10 @@ export function isVForScope(scope: CodegenScope): scope is CodegenVForScope {
export function transform(root: RootNode, options: TransformOptions) { export function transform(root: RootNode, options: TransformOptions) {
const context = createTransformContext(root, options) const context = createTransformContext(root, options)
traverseNode(root, context) traverseNode(root, context)
// finalize meta information
root.helpers = [...context.helpers.keys()]
root.components = [...context.components]
root.cached = context.cached
return context return context
} }
......
...@@ -95,7 +95,6 @@ function processProps(node: ElementNode, context: TransformContext) { ...@@ -95,7 +95,6 @@ function processProps(node: ElementNode, context: TransformContext) {
if (directiveTransform) { if (directiveTransform) {
const { props } = directiveTransform(prop, node, context) const { props } = directiveTransform(prop, node, context)
prop.exp = props[0].value as ExpressionNode prop.exp = props[0].value as ExpressionNode
console.log('prop', prop)
} }
} }
} }
......
...@@ -2,10 +2,12 @@ import { BaseNode } from 'estree' ...@@ -2,10 +2,12 @@ import { BaseNode } from 'estree'
import { walk } from 'estree-walker' import { walk } from 'estree-walker'
import { Expression, isIdentifier, isReferenced } from '@babel/types' import { Expression, isIdentifier, isReferenced } from '@babel/types'
import { import {
createCompoundExpression,
createSimpleExpression, createSimpleExpression,
ExpressionNode, ExpressionNode,
NodeTypes, NodeTypes,
SimpleExpressionNode, SimpleExpressionNode,
TO_DISPLAY_STRING,
} from '@vue/compiler-core' } from '@vue/compiler-core'
import { createObjectProperty, parseExpr } from '../ast' import { createObjectProperty, parseExpr } from '../ast'
import { genExpr } from '../codegen' import { genExpr } from '../codegen'
...@@ -22,7 +24,14 @@ import { isForElementNode } from './vFor' ...@@ -22,7 +24,14 @@ import { isForElementNode } from './vFor'
export const transformIdentifier: NodeTransform = (node, context) => { export const transformIdentifier: NodeTransform = (node, context) => {
return () => { return () => {
if (node.type === NodeTypes.INTERPOLATION) { if (node.type === NodeTypes.INTERPOLATION) {
node.content = rewriteExpression(node.content, context) node.content = rewriteExpression(
createCompoundExpression([
`${context.helperString(TO_DISPLAY_STRING)}(`,
node.content,
`)`,
]),
context
)
} else if (node.type === NodeTypes.ELEMENT) { } else if (node.type === NodeTypes.ELEMENT) {
const vFor = isForElementNode(node) && node.vFor const vFor = isForElementNode(node) && node.vFor
for (let i = 0; i < node.props.length; i++) { for (let i = 0; i < node.props.length; i++) {
......
...@@ -4650,6 +4650,7 @@ const getFunctionalFallthrough = (attrs) => { ...@@ -4650,6 +4650,7 @@ const getFunctionalFallthrough = (attrs) => {
}; };
function renderComponentRoot(instance) { function renderComponentRoot(instance) {
const { type: Component, vnode, proxy, withProxy, props, slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance; const { type: Component, vnode, proxy, withProxy, props, slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance;
instance.$ei = 0;
let result; let result;
const prev = setCurrentRenderingInstance(instance); const prev = setCurrentRenderingInstance(instance);
try { try {
...@@ -4951,6 +4952,46 @@ var plugin = { ...@@ -4951,6 +4952,46 @@ var plugin = {
}, },
}; };
/**
* Actual implementation
*/
function vFor(source, renderItem) {
let ret;
if (isArray(source) || isString(source)) {
ret = new Array(source.length);
for (let i = 0, l = source.length; i < l; i++) {
ret[i] = renderItem(source[i], i, undefined);
}
}
else if (typeof source === 'number') {
if ((process.env.NODE_ENV !== 'production') && !Number.isInteger(source)) {
warn$1(`The v-for range expect an integer value but got ${source}.`);
return [];
}
ret = new Array(source);
for (let i = 0; i < source; i++) {
ret[i] = renderItem(i + 1, i, undefined);
}
}
else if (isObject(source)) {
if (source[Symbol.iterator]) {
ret = Array.from(source, (item, i) => renderItem(item, i, undefined));
}
else {
const keys = Object.keys(source);
ret = new Array(keys.length);
for (let i = 0, l = keys.length; i < l; i++) {
const key = keys[i];
ret[i] = renderItem(source[key], key, i);
}
}
}
else {
ret = [];
}
return ret;
}
function vOn(value) { function vOn(value) {
const instance = getCurrentInstance(); const instance = getCurrentInstance();
const name = 'e' + instance.$ei++; const name = 'e' + instance.$ei++;
...@@ -4998,4 +5039,4 @@ function createApp(rootComponent, rootProps = null) { ...@@ -4998,4 +5039,4 @@ function createApp(rootComponent, rootProps = null) {
} }
const createSSRApp = createApp; const createSSRApp = createApp;
export { EffectScope, ReactiveEffect, callWithAsyncErrorHandling, callWithErrorHandling, computed, createApp, createSSRApp, createVNode$1 as createVNode, createVueApp, customRef, defineComponent, defineEmits, defineExpose, defineProps, effect, effectScope, getCurrentInstance, getCurrentScope, inject, injectHook, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, logError, markRaw, mergeDefaults, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onUnmounted, onUpdated, provide, proxyRefs, queuePostFlushCb, reactive, readonly, ref, resolveComponent, resolveDirective, resolveFilter, shallowReactive, shallowReadonly, shallowRef, stop, toHandlers, toRaw, toRef, toRefs, triggerRef, unref, useAttrs, useSSRContext, useSlots, vOn, version, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withModifiers, withScopeId }; export { EffectScope, ReactiveEffect, callWithAsyncErrorHandling, callWithErrorHandling, computed, createApp, createSSRApp, createVNode$1 as createVNode, createVueApp, customRef, defineComponent, defineEmits, defineExpose, defineProps, effect, effectScope, getCurrentInstance, getCurrentScope, inject, injectHook, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, logError, markRaw, mergeDefaults, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onUnmounted, onUpdated, provide, proxyRefs, queuePostFlushCb, reactive, readonly, ref, resolveComponent, resolveDirective, resolveFilter, shallowReactive, shallowReadonly, shallowRef, stop, toHandlers, toRaw, toRef, toRefs, triggerRef, unref, useAttrs, useSSRContext, useSlots, vFor, vOn, version, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withModifiers, withScopeId };
...@@ -4582,6 +4582,7 @@ const getFunctionalFallthrough = (attrs) => { ...@@ -4582,6 +4582,7 @@ const getFunctionalFallthrough = (attrs) => {
}; };
function renderComponentRoot(instance) { function renderComponentRoot(instance) {
const { type: Component, vnode, proxy, withProxy, props, slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance; const { type: Component, vnode, proxy, withProxy, props, slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance;
instance.$ei = 0;
let result; let result;
const prev = setCurrentRenderingInstance(instance); const prev = setCurrentRenderingInstance(instance);
try { try {
......
export { vFor } from './vFor'
export { vOn } from './vOn'
import { isArray, isObject, isString } from '@vue/shared'
import { warn } from 'vue'
type VForItem = Record<string, unknown>
/**
* v-for string
* @private
*/
export function vFor(
source: string,
renderItem: (value: string, index: number) => VForItem
): VForItem[]
/**
* v-for number
*/
export function vFor(
source: number,
renderItem: (value: number, index: number) => VForItem
): VForItem[]
/**
* v-for array
*/
export function vFor<T>(
source: T[],
renderItem: (value: T, index: number) => VForItem
): VForItem[]
/**
* v-for iterable
*/
export function vFor<T>(
source: Iterable<T>,
renderItem: (value: T, index: number) => VForItem
): VForItem[]
/**
* v-for object
*/
export function vFor<T>(
source: T,
renderItem: <K extends keyof T>(
value: T[K],
key: K,
index: number
) => VForItem
): VForItem[]
/**
* Actual implementation
*/
export function vFor(
source: any,
renderItem: (...args: any[]) => VForItem
): VForItem[] {
let ret: VForItem[]
if (isArray(source) || isString(source)) {
ret = new Array(source.length)
for (let i = 0, l = source.length; i < l; i++) {
ret[i] = renderItem(source[i], i, undefined)
}
} else if (typeof source === 'number') {
if (__DEV__ && !Number.isInteger(source)) {
warn(`The v-for range expect an integer value but got ${source}.`)
return []
}
ret = new Array(source)
for (let i = 0; i < source; i++) {
ret[i] = renderItem(i + 1, i, undefined)
}
} else if (isObject(source)) {
if (source[Symbol.iterator as any]) {
ret = Array.from(source as Iterable<any>, (item, i) =>
renderItem(item, i, undefined)
)
} else {
const keys = Object.keys(source)
ret = new Array(keys.length)
for (let i = 0, l = keys.length; i < l; i++) {
const key = keys[i]
ret[i] = renderItem(source[key], key, i)
}
}
} else {
ret = []
}
return ret
}
...@@ -5,7 +5,7 @@ export function createApp(rootComponent: unknown, rootProps = null) { ...@@ -5,7 +5,7 @@ export function createApp(rootComponent: unknown, rootProps = null) {
rootComponent && ((rootComponent as any).mpType = 'app') rootComponent && ((rootComponent as any).mpType = 'app')
return createVueApp(rootComponent, rootProps).use(plugin) return createVueApp(rootComponent, rootProps).use(plugin)
} }
export { vOn } from './helpers/vOn'
export const createSSRApp = createApp export const createSSRApp = createApp
export * from './helpers'
// @ts-ignore // @ts-ignore
export * from '../lib/vue.runtime.esm.js' export * from '../lib/vue.runtime.esm.js'
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册