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

fix(mp): default slot (#3094)

上级 bc8110fe
...@@ -4,14 +4,14 @@ describe('mp-alipay: transform v-slot', () => { ...@@ -4,14 +4,14 @@ describe('mp-alipay: transform v-slot', () => {
test('default slot', () => { test('default slot', () => {
assert( assert(
`<custom><template v-slot/></custom>`, `<custom><template v-slot/></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" onVI="__l"><view slot="d"/></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" onVI="__l"><view/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<custom>test</custom>`, `<custom>test</custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" onVI="__l"><view slot="d">test</view></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" onVI="__l">test</custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
...@@ -20,14 +20,14 @@ describe('mp-alipay: transform v-slot', () => { ...@@ -20,14 +20,14 @@ describe('mp-alipay: transform v-slot', () => {
test('named slots', () => { test('named slots', () => {
assert( assert(
`<custom><template v-slot:header/><template v-slot:default/><template v-slot:footer/></custom>`, `<custom><template v-slot:header/><template v-slot:default/><template v-slot:footer/></custom>`,
`<custom u-s="{{['header','d','footer']}}" u-i="2a9ec0b0-0" onVI="__l"><view slot="header"/><view slot="d"/><view slot="footer"/></custom>`, `<custom u-s="{{['header','d','footer']}}" u-i="2a9ec0b0-0" onVI="__l"><view slot="header"/><view/><view slot="footer"/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<unicloud-db v-slot:default="{data, loading, error, options}"><view v-if="error">{{error.message}}</view><view v-else></view></unicloud-db>`, `<unicloud-db v-slot:default="{data, loading, error, options}"><view v-if="error">{{error.message}}</view><view v-else></view></unicloud-db>`,
`<unicloud-db u-s="{{['d']}}" slot="d" u-i="2a9ec0b0-0" onVI="__l"><view a:for="{{a}}" a:for-item="v0" a:key="c" slot="{{v0.d}}"><view a:if="{{v0.a}}">{{v0.b}}</view><view a:else></view></view></unicloud-db>`, `<unicloud-db u-s="{{['d']}}" u-i="2a9ec0b0-0" onVI="__l"><view a:for="{{a}}" a:for-item="v0" a:key="c" slot="{{v0.d}}"><view a:if="{{v0.a}}">{{v0.b}}</view><view a:else></view></view></unicloud-db>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _w(({ data, loading, error, options }, s0, i0) => { return _e({ a: error }, error ? { b: _t(error.message) } : {}, { c: i0, d: s0 }); }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) } return { a: _w(({ data, loading, error, options }, s0, i0) => { return _e({ a: error }, error ? { b: _t(error.message) } : {}, { c: i0, d: s0 }); }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) }
}` }`
......
...@@ -4,14 +4,14 @@ describe('compiler: transform v-slot', () => { ...@@ -4,14 +4,14 @@ describe('compiler: transform v-slot', () => {
test('default slot', () => { test('default slot', () => {
assert( assert(
`<custom><template v-slot/></custom>`, `<custom><template v-slot/></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d"/></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<custom>test</custom>`, `<custom>test</custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d">test</view></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0">test</custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
...@@ -20,14 +20,14 @@ describe('compiler: transform v-slot', () => { ...@@ -20,14 +20,14 @@ describe('compiler: transform v-slot', () => {
test('named slots', () => { test('named slots', () => {
assert( assert(
`<custom><template v-slot:header/><template v-slot:default/><template v-slot:footer/></custom>`, `<custom><template v-slot:header/><template v-slot:default/><template v-slot:footer/></custom>`,
`<custom u-s="{{['header','d','footer']}}" u-i="2a9ec0b0-0"><view slot="header"/><view slot="d"/><view slot="footer"/></custom>`, `<custom u-s="{{['header','d','footer']}}" u-i="2a9ec0b0-0"><view slot="header"/><view/><view slot="footer"/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<unicloud-db v-slot:default="{data, loading, error, options}"><view v-if="error">{{error.message}}</view><view v-else></view></unicloud-db>`, `<unicloud-db v-slot:default="{data, loading, error, options}"><view v-if="error">{{error.message}}</view><view v-else></view></unicloud-db>`,
`<unicloud-db u-s="{{['d']}}" slot="d" u-i="2a9ec0b0-0"><view slot="d"><block s-for="v0 in a trackBy v0.a"><view s-if="{{v0.b}}">{{v0.c}}</view><view s-else></view></block></view></unicloud-db>`, `<unicloud-db u-s="{{['d']}}" u-i="2a9ec0b0-0"><view><block s-for="v0 in a trackBy v0.a"><view s-if="{{v0.b}}">{{v0.c}}</view><view s-else></view></block></view></unicloud-db>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _w(({ data, loading, error, options }, s0, i0) => { return _e({ a: i0, b: error }, error ? { c: _t(error.message) } : {}); }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) } return { a: _w(({ data, loading, error, options }, s0, i0) => { return _e({ a: i0, b: error }, error ? { c: _t(error.message) } : {}); }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) }
}` }`
...@@ -37,7 +37,7 @@ describe('compiler: transform v-slot', () => { ...@@ -37,7 +37,7 @@ describe('compiler: transform v-slot', () => {
test('scoped slots', () => { test('scoped slots', () => {
assert( assert(
`<custom><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`, `<custom><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d"><block s-for="slotProps in a trackBy slotProps.a"><view>{{slotProps.b}}</view></block></view></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view><block s-for="slotProps in a trackBy slotProps.a"><view>{{slotProps.b}}</view></block></view></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _w((slotProps, s0, i0) => { return { a: i0, b: _t(slotProps.item) }; }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) } return { a: _w((slotProps, s0, i0) => { return { a: i0, b: _t(slotProps.item) }; }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) }
}` }`
...@@ -47,7 +47,7 @@ describe('compiler: transform v-slot', () => { ...@@ -47,7 +47,7 @@ describe('compiler: transform v-slot', () => {
test('scoped slots + scoped slots', () => { test('scoped slots + scoped slots', () => {
assert( assert(
`<custom><template v-slot:default="slotProps"><custom1><template v-slot:default="slotProps1">{{ slotProps.item }}{{ slotProps1.item }}</template></custom1></template></custom>`, `<custom><template v-slot:default="slotProps"><custom1><template v-slot:default="slotProps1">{{ slotProps.item }}{{ slotProps1.item }}</template></custom1></template></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d"><block s-for="slotProps in a trackBy slotProps.a"><custom1 u-s="{{['d']}}" u-i="{{slotProps.d}}"><view slot="d"><block s-for="slotProps1 in slotProps.b trackBy slotProps1.a">{{slotProps.c}}{{slotProps1.b}}</block></view></custom1></block></view></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view><block s-for="slotProps in a trackBy slotProps.a"><custom1 u-s="{{['d']}}" u-i="{{slotProps.d}}"><view><block s-for="slotProps1 in slotProps.b trackBy slotProps1.a">{{slotProps.c}}{{slotProps1.b}}</block></view></custom1></block></view></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _w((slotProps, s0, i0) => { return { a: i0, b: _w((slotProps1, s1, i1) => { return { a: i1, b: _t(slotProps1.item) }; }, { name: 'd', path: 'a[' + i0 + '].' + 'b', vueId: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0' }), c: _t(slotProps.item), d: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0' }; }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) } return { a: _w((slotProps, s0, i0) => { return { a: i0, b: _w((slotProps1, s1, i1) => { return { a: i1, b: _t(slotProps1.item) }; }, { name: 'd', path: 'a[' + i0 + '].' + 'b', vueId: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0' }), c: _t(slotProps.item), d: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0' }; }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) }
}` }`
...@@ -57,7 +57,7 @@ describe('compiler: transform v-slot', () => { ...@@ -57,7 +57,7 @@ describe('compiler: transform v-slot', () => {
test('v-if + scoped slots', () => { test('v-if + scoped slots', () => {
assert( assert(
`<custom><template v-if="ok" v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`, `<custom><template v-if="ok" v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view s-if="{{a}}" slot="d"><block s-for="slotProps in b trackBy slotProps.a"><view>{{slotProps.b}}</view></block></view></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view s-if="{{a}}"><block s-for="slotProps in b trackBy slotProps.a"><view>{{slotProps.b}}</view></block></view></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return _e({ a: _ctx.ok }, _ctx.ok ? { b: _w((slotProps, s0, i0) => { return { a: i0, b: _t(slotProps.item) }; }, { name: 'd', path: 'b', vueId: '2a9ec0b0-0' }) } : {}) return _e({ a: _ctx.ok }, _ctx.ok ? { b: _w((slotProps, s0, i0) => { return { a: i0, b: _t(slotProps.item) }; }, { name: 'd', path: 'b', vueId: '2a9ec0b0-0' }) } : {})
}` }`
...@@ -67,7 +67,7 @@ describe('compiler: transform v-slot', () => { ...@@ -67,7 +67,7 @@ describe('compiler: transform v-slot', () => {
test('v-for + scoped slots', () => { test('v-for + scoped slots', () => {
assert( assert(
`<custom v-for="item in items"><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`, `<custom v-for="item in items"><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom>`,
`<custom s-for="item in a" u-s="{{['d']}}" u-i="{{item.b}}"><view slot="d"><block s-for="slotProps in item.a trackBy slotProps.a"><view>{{slotProps.b}}</view></block></view></custom>`, `<custom s-for="item in a" u-s="{{['d']}}" u-i="{{item.b}}"><view><block s-for="slotProps in item.a trackBy slotProps.a"><view>{{slotProps.b}}</view></block></view></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _w((slotProps, s1, i1) => { return { a: i1, b: _t(slotProps.item) }; }, { name: 'd', path: 'a[' + i0 + '].' + 'a', vueId: '2a9ec0b0-0' + '-' + i0 }), b: '2a9ec0b0-0' + '-' + i0 }; }) } return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _w((slotProps, s1, i1) => { return { a: i1, b: _t(slotProps.item) }; }, { name: 'd', path: 'a[' + i0 + '].' + 'a', vueId: '2a9ec0b0-0' + '-' + i0 }), b: '2a9ec0b0-0' + '-' + i0 }; }) }
}` }`
...@@ -77,7 +77,7 @@ describe('compiler: transform v-slot', () => { ...@@ -77,7 +77,7 @@ describe('compiler: transform v-slot', () => {
test('v-for + v-for + scoped slots', () => { test('v-for + v-for + scoped slots', () => {
assert( assert(
`<view v-for="item in items"><custom v-for="item1 in item.list" :item="item1"><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom></view>`, `<view v-for="item in items"><custom v-for="item1 in item.list" :item="item1"><template v-slot:default="slotProps"><view>{{ slotProps.item }}</view></template></custom></view>`,
`<view s-for="item in a"><custom s-for="item1 in item.a" u-s="{{['d']}}" u-i="{{item1.b}}" u-p="{{item1.c}}"><view slot="d"><block s-for="slotProps in item1.a trackBy slotProps.a"><view>{{slotProps.b}}</view></block></view></custom></view>`, `<view s-for="item in a"><custom s-for="item1 in item.a" u-s="{{['d']}}" u-i="{{item1.b}}" u-p="{{item1.c}}"><view><block s-for="slotProps in item1.a trackBy slotProps.a"><view>{{slotProps.b}}</view></block></view></custom></view>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _f(item.list, (item1, k1, i1) => { return { a: _w((slotProps, s2, i2) => { return { a: i2, b: _t(slotProps.item) }; }, { name: 'd', path: 'a[' + i0 + '].' + ('a[' + i1 + '].') + 'a', vueId: '2a9ec0b0-0' + '-' + i0 + '-' + i1 }), b: '2a9ec0b0-0' + '-' + i0 + '-' + i1, c: _p({ item: item1 }) }; }) }; }) } return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _f(item.list, (item1, k1, i1) => { return { a: _w((slotProps, s2, i2) => { return { a: i2, b: _t(slotProps.item) }; }, { name: 'd', path: 'a[' + i0 + '].' + ('a[' + i1 + '].') + 'a', vueId: '2a9ec0b0-0' + '-' + i0 + '-' + i1 }), b: '2a9ec0b0-0' + '-' + i0 + '-' + i1, c: _p({ item: item1 }) }; }) }; }) }
}` }`
......
...@@ -635,6 +635,29 @@ function initProps(mpComponentOptions) { ...@@ -635,6 +635,29 @@ function initProps(mpComponentOptions) {
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
} }
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
{
if (
// [String,Boolean]=>Boolean
defaultValue === false &&
isArray(type) &&
type.length === 2 &&
type.indexOf(String) !== -1 &&
type.indexOf(Boolean) !== -1) {
return Boolean;
}
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type, defaultValue);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
/** /**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为'' * 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param * @param param
...@@ -651,10 +674,26 @@ function initPageProps({ properties }, rawProps) { ...@@ -651,10 +674,26 @@ function initPageProps({ properties }, rawProps) {
} }
else if (isPlainObject(rawProps)) { else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => { Object.keys(rawProps).forEach((key) => {
properties[key] = { const opts = rawProps[key];
type: String, if (isPlainObject(opts)) {
value: '', // title:{type:String,default:''}
}; let value = opts.default;
if (isFunction(value)) {
value = value();
}
const type = opts.type;
opts.type = normalizePropType(type, value);
properties[key] = {
type: opts.type,
value,
};
}
else {
// content:String
properties[key] = {
type: normalizePropType(opts, null),
};
}
}); });
} }
} }
......
...@@ -10,7 +10,7 @@ describe('compiler: transform component', () => { ...@@ -10,7 +10,7 @@ describe('compiler: transform component', () => {
test('component + component', () => { test('component + component', () => {
assert( assert(
`<custom><custom1/></custom>`, `<custom><custom1/></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" bind:__l="__l"><custom1 u-i="2a9ec0b0-1,2a9ec0b0-0" bind:__l="__l" slot="d"/></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" bind:__l="__l"><custom1 u-i="2a9ec0b0-1,2a9ec0b0-0" bind:__l="__l"/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}`, }`,
...@@ -22,7 +22,7 @@ describe('compiler: transform component', () => { ...@@ -22,7 +22,7 @@ describe('compiler: transform component', () => {
test('component + component + component', () => { test('component + component + component', () => {
assert( assert(
`<custom><custom1><custom2/><custom2/></custom1></custom>`, `<custom><custom1><custom2/><custom2/></custom1></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" bind:__l="__l"><custom1 u-s="{{['d']}}" u-i="2a9ec0b0-1,2a9ec0b0-0" bind:__l="__l" slot="d"><view slot="d"><custom2 u-i="2a9ec0b0-2,2a9ec0b0-1" bind:__l="__l"/><custom2 u-i="2a9ec0b0-3,2a9ec0b0-1" bind:__l="__l"/></view></custom1></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" bind:__l="__l"><custom1 u-s="{{['d']}}" u-i="2a9ec0b0-1,2a9ec0b0-0" bind:__l="__l"><custom2 u-i="2a9ec0b0-2,2a9ec0b0-1" bind:__l="__l"/><custom2 u-i="2a9ec0b0-3,2a9ec0b0-1" bind:__l="__l"/></custom1></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}`, }`,
...@@ -56,7 +56,7 @@ describe('compiler: transform component', () => { ...@@ -56,7 +56,7 @@ describe('compiler: transform component', () => {
test('component + component with v-for', () => { test('component + component with v-for', () => {
assert( assert(
`<custom><custom1 v-for="item in items"/></custom>`, `<custom><custom1 v-for="item in items"/></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" bind:__l="__l"><view slot="d"><custom1 wx:for="{{a}}" wx:for-item="item" u-i="{{item.a}}" bind:__l="__l"/></view></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0" bind:__l="__l"><custom1 wx:for="{{a}}" wx:for-item="item" u-i="{{item.a}}" bind:__l="__l"/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0' }; }) } return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-1' + '-' + i0 + ',' + '2a9ec0b0-0' }; }) }
}`, }`,
...@@ -68,7 +68,7 @@ describe('compiler: transform component', () => { ...@@ -68,7 +68,7 @@ describe('compiler: transform component', () => {
test('component with v-for + component', () => { test('component with v-for + component', () => {
assert( assert(
`<custom v-for="item in items"><custom1/></custom>`, `<custom v-for="item in items"><custom1/></custom>`,
`<custom wx:for="{{a}}" wx:for-item="item" u-s="{{['d']}}" u-i="{{item.b}}" bind:__l="__l"><custom1 u-i="{{item.a}}" bind:__l="__l" slot="d"/></custom>`, `<custom wx:for="{{a}}" wx:for-item="item" u-s="{{['d']}}" u-i="{{item.b}}" bind:__l="__l"><custom1 u-i="{{item.a}}" bind:__l="__l"/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-1' + '-' + i0 + ',' + ('2a9ec0b0-0' + '-' + i0), b: '2a9ec0b0-0' + '-' + i0 }; }) } return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-1' + '-' + i0 + ',' + ('2a9ec0b0-0' + '-' + i0), b: '2a9ec0b0-0' + '-' + i0 }; }) }
}`, }`,
...@@ -80,7 +80,7 @@ describe('compiler: transform component', () => { ...@@ -80,7 +80,7 @@ describe('compiler: transform component', () => {
test('component with v-for + component with v-for', () => { test('component with v-for + component with v-for', () => {
assert( assert(
`<custom v-for="item in items"><custom1 v-for="item1 in item.items"/></custom>`, `<custom v-for="item in items"><custom1 v-for="item1 in item.items"/></custom>`,
`<custom wx:for="{{a}}" wx:for-item="item" u-s="{{['d']}}" u-i="{{item.b}}" bind:__l="__l"><view slot="d"><custom1 wx:for="{{item.a}}" wx:for-item="item1" u-i="{{item1.a}}" bind:__l="__l"/></view></custom>`, `<custom wx:for="{{a}}" wx:for-item="item" u-s="{{['d']}}" u-i="{{item.b}}" bind:__l="__l"><custom1 wx:for="{{item.a}}" wx:for-item="item1" u-i="{{item1.a}}" bind:__l="__l"/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _f(item.items, (item1, k1, i1) => { return { a: '2a9ec0b0-1' + '-' + i0 + '-' + i1 + ',' + ('2a9ec0b0-0' + '-' + i0) }; }), b: '2a9ec0b0-0' + '-' + i0 }; }) } return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _f(item.items, (item1, k1, i1) => { return { a: '2a9ec0b0-1' + '-' + i0 + '-' + i1 + ',' + ('2a9ec0b0-0' + '-' + i0) }; }), b: '2a9ec0b0-0' + '-' + i0 }; }) }
}`, }`,
......
...@@ -4,14 +4,14 @@ describe('compiler: transform slot', () => { ...@@ -4,14 +4,14 @@ describe('compiler: transform slot', () => {
test('basic', () => { test('basic', () => {
assert( assert(
`<button><slot/></button>`, `<button><slot/></button>`,
`<button><slot name="d"/></button>`, `<button><slot/></button>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<button><slot name="default"/></button>`, `<button><slot name="default"/></button>`,
`<button><slot name="d"/></button>`, `<button><slot/></button>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
...@@ -29,7 +29,7 @@ describe('compiler: transform slot', () => { ...@@ -29,7 +29,7 @@ describe('compiler: transform slot', () => {
test('fallback content', () => { test('fallback content', () => {
assert( assert(
`<button><slot>Submit</slot></button>`, `<button><slot>Submit</slot></button>`,
`<button><block wx:if="{{$slots.d}}"><slot name="d"></slot></block><block wx:else>Submit</block></button>`, `<button><block wx:if="{{$slots.d}}"><slot></slot></block><block wx:else>Submit</block></button>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
...@@ -56,7 +56,7 @@ describe('compiler: transform slot', () => { ...@@ -56,7 +56,7 @@ describe('compiler: transform slot', () => {
test('slot with component', () => { test('slot with component', () => {
assert( assert(
`<view><custom><slot><view>fallback</view></slot></custom></view>`, `<view><custom><slot><view>fallback</view></slot></custom></view>`,
`<view><custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d"><block wx:if="{{$slots.d}}"><slot name="d"></slot></block><block wx:else><view>fallback</view></block></view></custom></view>`, `<view><custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><block wx:if="{{$slots.d}}"><slot></slot></block><block wx:else><view>fallback</view></block></custom></view>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
......
...@@ -158,7 +158,7 @@ describe(`compiler: v-for`, () => { ...@@ -158,7 +158,7 @@ describe(`compiler: v-for`, () => {
test(`template v-for w/ <slot/>`, () => { test(`template v-for w/ <slot/>`, () => {
assert( assert(
`<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 name="d"/></block>`, `<block wx:for="{{a}}" wx:for-item="item"><slot/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return {}; }) } return { a: _f(_ctx.items, (item, k0, i0) => { return {}; }) }
}` }`
...@@ -177,7 +177,7 @@ describe(`compiler: v-for`, () => { ...@@ -177,7 +177,7 @@ describe(`compiler: v-for`, () => {
test(`v-for on <slot/>`, () => { test(`v-for on <slot/>`, () => {
assert( assert(
`<slot v-for="item in items"></slot>`, `<slot v-for="item in items"></slot>`,
`<slot wx:for="{{a}}" wx:for-item="item" name="d"></slot>`, `<slot wx:for="{{a}}" wx:for-item="item"></slot>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _f(_ctx.items, (item, k0, i0) => { return {}; }) } return { a: _f(_ctx.items, (item, k0, i0) => { return {}; }) }
}` }`
......
...@@ -50,7 +50,7 @@ describe(`compiler: v-if`, () => { ...@@ -50,7 +50,7 @@ describe(`compiler: v-if`, () => {
test(`template v-if w/ single <slot/> child`, () => { test(`template v-if w/ single <slot/> child`, () => {
assert( assert(
`<template v-if="ok"><slot/></template>`, `<template v-if="ok"><slot/></template>`,
`<block wx:if="{{a}}"><slot name="d"/></block>`, `<block wx:if="{{a}}"><slot/></block>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return _e({ a: _ctx.ok }, _ctx.ok ? {} : {}) return _e({ a: _ctx.ok }, _ctx.ok ? {} : {})
}` }`
...@@ -59,7 +59,7 @@ describe(`compiler: v-if`, () => { ...@@ -59,7 +59,7 @@ describe(`compiler: v-if`, () => {
test(`v-if on <slot/>`, () => { test(`v-if on <slot/>`, () => {
assert( assert(
`<slot v-if="ok"/>`, `<slot v-if="ok"/>`,
`<slot wx:if="{{a}}" name="d"/>`, `<slot wx:if="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return _e({ a: _ctx.ok }, _ctx.ok ? {} : {}) return _e({ a: _ctx.ok }, _ctx.ok ? {} : {})
}` }`
......
...@@ -4,28 +4,28 @@ describe('compiler: transform v-slot', () => { ...@@ -4,28 +4,28 @@ describe('compiler: transform v-slot', () => {
test('default slot', () => { test('default slot', () => {
assert( assert(
`<custom><template v-slot/></custom>`, `<custom><template v-slot/></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d"/></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<custom><template #default/></custom>`, `<custom><template #default/></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d"/></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<custom>test</custom>`, `<custom>test</custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d">test</view></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0">test</custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<custom><div>test</div></custom>`, `<custom><div>test</div></custom>`,
`<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view slot="d">test</view></custom>`, `<custom u-s="{{['d']}}" u-i="2a9ec0b0-0"><view>test</view></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
...@@ -34,14 +34,14 @@ describe('compiler: transform v-slot', () => { ...@@ -34,14 +34,14 @@ describe('compiler: transform v-slot', () => {
test('named slots', () => { test('named slots', () => {
assert( assert(
`<custom><template v-slot:header/><template v-slot:default/><template v-slot:footer/></custom>`, `<custom><template v-slot:header/><template v-slot:default/><template v-slot:footer/></custom>`,
`<custom u-s="{{['header','d','footer']}}" u-i="2a9ec0b0-0"><view slot="header"/><view slot="d"/><view slot="footer"/></custom>`, `<custom u-s="{{['header','d','footer']}}" u-i="2a9ec0b0-0"><view slot="header"/><view/><view slot="footer"/></custom>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return {} return {}
}` }`
) )
assert( assert(
`<unicloud-db v-slot:default="{data, loading, error, options}"><view v-if="error">{{error.message}}</view><view v-else></view></unicloud-db>`, `<unicloud-db v-slot:default="{data, loading, error, options}"><view v-if="error">{{error.message}}</view><view v-else></view></unicloud-db>`,
`<unicloud-db u-s="{{['d']}}" slot="d" u-i="2a9ec0b0-0"><view wx:for="{{a}}" wx:for-item="v0" wx:key="c" slot="{{v0.d}}"><view wx:if="{{v0.a}}">{{v0.b}}</view><view wx:else></view></view></unicloud-db>`, `<unicloud-db u-s="{{['d']}}" u-i="2a9ec0b0-0"><view wx:for="{{a}}" wx:for-item="v0" wx:key="c" slot="{{v0.d}}"><view wx:if="{{v0.a}}">{{v0.b}}</view><view wx:else></view></view></unicloud-db>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: _w(({ data, loading, error, options }, s0, i0) => { return _e({ a: error }, error ? { b: _t(error.message) } : {}, { c: i0, d: s0 }); }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) } return { a: _w(({ data, loading, error, options }, s0, i0) => { return _e({ a: error }, error ? { b: _t(error.message) } : {}, { c: i0, d: s0 }); }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }) }
}` }`
......
...@@ -422,14 +422,15 @@ function genDirectiveNode( ...@@ -422,14 +422,15 @@ function genDirectiveNode(
if (prop.name === 'slot') { if (prop.name === 'slot') {
if (prop.arg) { if (prop.arg) {
const arg = prop.arg as SimpleExpressionNode const arg = prop.arg as SimpleExpressionNode
if (arg.isStatic) {
push( const slotName = dynamicSlotName(arg.content)
` slot="${ // 非作用域默认插槽不生成 slot 属性
arg.isStatic if (slotName !== SLOT_DEFAULT_NAME) {
? dynamicSlotName(arg.content) push(` slot="${slotName}"`)
: '{{' + arg.content + '}}' }
}"` } else {
) push(` slot="{{${arg.content}}}"`)
}
} }
} else if (prop.name === 'show') { } else if (prop.name === 'show') {
let hiddenPropName = 'hidden' let hiddenPropName = 'hidden'
......
...@@ -19,7 +19,7 @@ import { RENDER_SLOT } from '../runtimeHelpers' ...@@ -19,7 +19,7 @@ import { RENDER_SLOT } from '../runtimeHelpers'
import { genExpr } from '../codegen' import { genExpr } from '../codegen'
import { isScopedSlotVFor, isVForScope, TransformContext } from '../transform' import { isScopedSlotVFor, isVForScope, TransformContext } from '../transform'
import { processProps } from './transformElement' import { processProps } from './transformElement'
import { rewriteExpression } from './utils' import { removeAttribute, rewriteExpression } from './utils'
import { import {
createAttributeNode, createAttributeNode,
createBindDirectiveNode, createBindDirectiveNode,
...@@ -102,6 +102,16 @@ export function rewriteSlot(node: SlotOutletNode, context: TransformContext) { ...@@ -102,6 +102,16 @@ export function rewriteSlot(node: SlotOutletNode, context: TransformContext) {
]), ]),
context context
) )
} else {
// 非作用域默认插槽直接移除命名
if (slotName === `"${SLOT_DEFAULT_NAME}"`) {
removeAttribute(node, 'name')
}
}
} else {
// 非作用域默认插槽直接移除命名
if (slotName === `"${SLOT_DEFAULT_NAME}"`) {
removeAttribute(node, 'name')
} }
} }
} }
......
...@@ -16,6 +16,7 @@ import { ...@@ -16,6 +16,7 @@ import {
import { VUE_REF, VUE_REF_IN_FOR } from '@dcloudio/uni-cli-shared' import { VUE_REF, VUE_REF_IN_FOR } from '@dcloudio/uni-cli-shared'
import { import {
createSimpleExpression, createSimpleExpression,
ElementNode,
ExpressionNode, ExpressionNode,
NodeTypes, NodeTypes,
SimpleExpressionNode, SimpleExpressionNode,
...@@ -189,3 +190,10 @@ function isReferencedByIds(node: Expression, knownIds: string[]) { ...@@ -189,3 +190,10 @@ function isReferencedByIds(node: Expression, knownIds: string[]) {
export function isStaticLiteral(value: object | null | undefined) { export function isStaticLiteral(value: object | null | undefined) {
return isLiteral(value) && !isTemplateLiteral(value) return isLiteral(value) && !isTemplateLiteral(value)
} }
export function removeAttribute(node: ElementNode, name: string) {
const index = node.props.findIndex((prop) => prop.name === name)
if (index > -1) {
node.props.splice(index, 1)
}
}
...@@ -30,7 +30,6 @@ import { ...@@ -30,7 +30,6 @@ import {
import { dynamicSlotName, SLOT_DEFAULT_NAME } from '@dcloudio/uni-shared' import { dynamicSlotName, SLOT_DEFAULT_NAME } from '@dcloudio/uni-shared'
import { import {
createBindDirectiveNode, createBindDirectiveNode,
createDirectiveNode,
isUserComponent, isUserComponent,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { WITH_SCOPED_SLOT } from '../runtimeHelpers' import { WITH_SCOPED_SLOT } from '../runtimeHelpers'
...@@ -121,19 +120,6 @@ export const transformSlot: NodeTransform = (node, context) => { ...@@ -121,19 +120,6 @@ export const transformSlot: NodeTransform = (node, context) => {
) )
transformTemplateSlotElement(onComponentSlot, templateNode, node, context) transformTemplateSlotElement(onComponentSlot, templateNode, node, context)
node.children = [templateNode] node.children = [templateNode]
} else {
if (implicitDefaultChildren.length) {
// <custom>test</custom> => <custom><template #default>test</template></custom>
implicitDefaultChildren.forEach((child) => {
node.children.splice(node.children.indexOf(child), 1)
})
node.children.unshift(
createTemplateNode(
createDirectiveNode('slot', 'default'),
implicitDefaultChildren
)
)
}
} }
// 不支持 $slots, 则自动补充 props // 不支持 $slots, 则自动补充 props
if (slots.size && !context.miniProgram.slot.$slots) { if (slots.size && !context.miniProgram.slot.$slots) {
......
...@@ -630,6 +630,18 @@ function initProps(mpComponentOptions) { ...@@ -630,6 +630,18 @@ function initProps(mpComponentOptions) {
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
} }
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
/** /**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为'' * 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param * @param param
...@@ -646,10 +658,26 @@ function initPageProps({ properties }, rawProps) { ...@@ -646,10 +658,26 @@ function initPageProps({ properties }, rawProps) {
} }
else if (isPlainObject(rawProps)) { else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => { Object.keys(rawProps).forEach((key) => {
properties[key] = { const opts = rawProps[key];
type: String, if (isPlainObject(opts)) {
value: '', // title:{type:String,default:''}
}; let value = opts.default;
if (isFunction(value)) {
value = value();
}
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = {
type: opts.type,
value,
};
}
else {
// content:String
properties[key] = {
type: normalizePropType(opts),
};
}
}); });
} }
} }
......
...@@ -603,6 +603,18 @@ function initProps(mpComponentOptions) { ...@@ -603,6 +603,18 @@ function initProps(mpComponentOptions) {
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
} }
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
/** /**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为'' * 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param * @param param
...@@ -619,10 +631,26 @@ function initPageProps({ properties }, rawProps) { ...@@ -619,10 +631,26 @@ function initPageProps({ properties }, rawProps) {
} }
else if (isPlainObject(rawProps)) { else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => { Object.keys(rawProps).forEach((key) => {
properties[key] = { const opts = rawProps[key];
type: String, if (isPlainObject(opts)) {
value: '', // title:{type:String,default:''}
}; let value = opts.default;
if (isFunction(value)) {
value = value();
}
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = {
type: opts.type,
value,
};
}
else {
// content:String
properties[key] = {
type: normalizePropType(opts),
};
}
}); });
} }
} }
......
...@@ -589,6 +589,18 @@ function initProps(mpComponentOptions) { ...@@ -589,6 +589,18 @@ function initProps(mpComponentOptions) {
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
} }
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
/** /**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为'' * 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param * @param param
...@@ -605,10 +617,26 @@ function initPageProps({ properties }, rawProps) { ...@@ -605,10 +617,26 @@ function initPageProps({ properties }, rawProps) {
} }
else if (isPlainObject(rawProps)) { else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => { Object.keys(rawProps).forEach((key) => {
properties[key] = { const opts = rawProps[key];
type: String, if (isPlainObject(opts)) {
value: '', // title:{type:String,default:''}
}; let value = opts.default;
if (isFunction(value)) {
value = value();
}
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = {
type: opts.type,
value,
};
}
else {
// content:String
properties[key] = {
type: normalizePropType(opts),
};
}
}); });
} }
} }
......
...@@ -603,6 +603,18 @@ function initProps(mpComponentOptions) { ...@@ -603,6 +603,18 @@ function initProps(mpComponentOptions) {
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
} }
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
/** /**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为'' * 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param * @param param
...@@ -619,10 +631,26 @@ function initPageProps({ properties }, rawProps) { ...@@ -619,10 +631,26 @@ function initPageProps({ properties }, rawProps) {
} }
else if (isPlainObject(rawProps)) { else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => { Object.keys(rawProps).forEach((key) => {
properties[key] = { const opts = rawProps[key];
type: String, if (isPlainObject(opts)) {
value: '', // title:{type:String,default:''}
}; let value = opts.default;
if (isFunction(value)) {
value = value();
}
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = {
type: opts.type,
value,
};
}
else {
// content:String
properties[key] = {
type: normalizePropType(opts),
};
}
}); });
} }
} }
......
...@@ -581,6 +581,18 @@ function initProps(mpComponentOptions) { ...@@ -581,6 +581,18 @@ function initProps(mpComponentOptions) {
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
} }
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function parsePropType(type, defaultValue) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0];
}
return type;
}
function normalizePropType(type, defaultValue) {
const res = parsePropType(type);
return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
/** /**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为'' * 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param * @param param
...@@ -597,10 +609,26 @@ function initPageProps({ properties }, rawProps) { ...@@ -597,10 +609,26 @@ function initPageProps({ properties }, rawProps) {
} }
else if (isPlainObject(rawProps)) { else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => { Object.keys(rawProps).forEach((key) => {
properties[key] = { const opts = rawProps[key];
type: String, if (isPlainObject(opts)) {
value: '', // title:{type:String,default:''}
}; let value = opts.default;
if (isFunction(value)) {
value = value();
}
const type = opts.type;
opts.type = normalizePropType(type);
properties[key] = {
type: opts.type,
value,
};
}
else {
// content:String
properties[key] = {
type: normalizePropType(opts),
};
}
}); });
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册