From a68a45e6ca0c09acc635da9a9f808df1c4c1877e Mon Sep 17 00:00:00 2001 From: Amour1688 <31695475+Amour1688@users.noreply.github.com> Date: Sat, 27 Jun 2020 09:31:41 +0800 Subject: [PATCH] use createVNode (#14) * chore: use createVNode * test: add patchFlag --- .../babel-plugin-jsx/src/transform-vue-jsx.js | 8 +- packages/babel-plugin-jsx/test/index.test.js | 81 +++++++------------ 2 files changed, 33 insertions(+), 56 deletions(-) diff --git a/packages/babel-plugin-jsx/src/transform-vue-jsx.js b/packages/babel-plugin-jsx/src/transform-vue-jsx.js index 234866b..ded0d00 100644 --- a/packages/babel-plugin-jsx/src/transform-vue-jsx.js +++ b/packages/babel-plugin-jsx/src/transform-vue-jsx.js @@ -369,14 +369,14 @@ const transformJSXElement = (t, path, state) => { const child = children.length === 1 && t.isStringLiteral(children[0]) ? children[0] : t.arrayExpression(children); - const { compatibleProps, usePatchFlag } = state.opts; + const { compatibleProps } = state.opts; if (compatibleProps && !state.get('compatibleProps')) { state.set('compatibleProps', addDefault( path, '@ant-design-vue/babel-helper-vue-compatible-props', { nameHint: '_compatibleProps' }, )); } - const createVNode = t.callExpression(createIdentifier(t, state, usePatchFlag ? 'createVNode' : 'h'), [ + const createVNode = t.callExpression(createIdentifier(t, state, 'createVNode'), [ tag, compatibleProps ? t.callExpression(state.get('compatibleProps'), [props]) : props, children[0] @@ -400,8 +400,8 @@ const transformJSXElement = (t, path, state) => { ]) : child ) : t.nullLiteral(), - patchFlag && usePatchFlag && t.addComment(t.numericLiteral(patchFlag), 'trailing', ` ${flagNames} `, false), - dynamicPropNames.size && usePatchFlag + patchFlag && t.addComment(t.numericLiteral(patchFlag), 'trailing', ` ${flagNames} `, false), + dynamicPropNames.size && t.arrayExpression([...dynamicPropNames.keys()].map((name) => t.stringLiteral(name))), ].filter(Boolean)); diff --git a/packages/babel-plugin-jsx/test/index.test.js b/packages/babel-plugin-jsx/test/index.test.js index 9a26f3a..330cd78 100644 --- a/packages/babel-plugin-jsx/test/index.test.js +++ b/packages/babel-plugin-jsx/test/index.test.js @@ -1,6 +1,12 @@ -import { ref } from 'vue'; +import { reactive, ref } from 'vue'; import { shallowMount, mount } from '@vue/test-utils'; +const patchFlagExpect = (wrapper, flag, dynamic) => { + const { patchFlag, dynamicProps } = wrapper.vm.$.subTree; + expect(patchFlag).toBe(flag); + expect(dynamicProps).toEqual(dynamic); +}; + describe('Transform JSX', () => { test('should render with render function', () => { const wrapper = shallowMount({ @@ -52,6 +58,7 @@ describe('Transform JSX', () => { ); }, }); + expect(wrapper.classes()).toStrictEqual([]); expect(wrapper.text()).toBe('1'); }); @@ -255,79 +262,49 @@ describe('Transform JSX', () => { }); }); -describe('Patch Flags', () => { - let renders = 0; - const Child = { - props: ['text'], - setup(props) { - return () => { - renders++; - return
{props.text}
; - }; - }, - }; - Child.inheritAttrs = false; - - it('should render when props change', async () => { - const wrapper = mount({ +describe('PatchFlags', () => { + test('static', () => { + const wrapper = shallowMount({ setup() { - const count = ref(0); - const inc = () => { - count.value++; - }; - return () => ( -
- -
- ); + return () =>
static
; }, }); - - expect(renders).toBe(1); - await wrapper.trigger('click'); - expect(renders).toBe(2); + patchFlagExpect(wrapper, 0, null); }); - it('should not render with static props', async () => { - renders = 0; + test('props', async () => { const wrapper = mount({ setup() { - const count = ref(0); - const inc = () => { - count.value++; + const visible = ref(true); + const onClick = () => { + visible.value = false; }; - return () => ( -
- -
- ); + return () =>
NEED_PATCH
; }, }); - expect(renders).toBe(1); + patchFlagExpect(wrapper, 8, ['onClick']); await wrapper.trigger('click'); - expect(renders).toBe(1); + expect(wrapper.html()).toBe('
NEED_PATCH
'); }); - it('should not render when props does not change', async () => { - renders = 0; + test('full props', async () => { const wrapper = mount({ setup() { - const count = ref(0); - const s = ref('a'); - const inc = () => { - count.value++; + const bindProps = reactive({ class: 'a', style: { marginTop: 10 } }); + const onClick = () => { + bindProps.class = 'b'; }; + return () => ( -
- - {count.value} -
+
full props
); }, }); + patchFlagExpect(wrapper, 16, ['onClick']); await wrapper.trigger('click'); - expect(renders).toBe(1); + + expect(wrapper.classes().sort()).toEqual(['b', 'static'].sort()); }); });