Skip to content

Commit

Permalink
refactor: rename createComponent as defineComponent (vuejs#230)
Browse files Browse the repository at this point in the history
Since Vue `3.0.0-alpha.1`, `createComponent` has been renamed `defineComponent`.
See vuejs/core@1c4cdd8
  • Loading branch information
cexbrayat authored and pikax committed Apr 19, 2020
1 parent 391f1a1 commit 497b7e5
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 27 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ After installing the plugin you can use the [Composition API](https://vue-compos

**This plugin requires TypeScript version >3.5.1. If you are using vetur, make sure to set `vetur.useWorkspaceDependencies` to `true`.**

To let TypeScript properly infer types inside Vue component options, you need to define components with `createComponent`:
To let TypeScript properly infer types inside Vue component options, you need to define components with `defineComponent`:

```ts
import { createComponent } from '@vue/composition-api';
import { defineComponent } from '@vue/composition-api';

const Component = createComponent({
const Component = defineComponent({
// type inference enabled
});

Expand Down
6 changes: 3 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ Vue.use(VueCompositionApi);

**请使用最新版的 TypeScript,如果你使用了 `vetur`,请将 `vetur.useWorkspaceDependencies` 设为 `true`**

为了让 TypeScript 正确的推导类型,我们必须使用 `createComponent` 来定义组件:
为了让 TypeScript 正确的推导类型,我们必须使用 `defineComponent` 来定义组件:

```ts
import { createComponent } from '@vue/composition-api';
import { defineComponent } from '@vue/composition-api';

const Component = createComponent({
const Component = defineComponent({
// 启用类型推断
});

Expand Down
4 changes: 2 additions & 2 deletions src/apis/computed.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getCurrentVue, getCurrentVM } from '../runtimeContext';
import { createRef, Ref } from '../reactivity';
import { createComponentInstance } from '../helper';
import { defineComponentInstance } from '../helper';
import { warn } from '../utils';

interface Option<T> {
Expand All @@ -25,7 +25,7 @@ export function computed<T>(
set = options.set;
}

const computedHost = createComponentInstance(getCurrentVue(), {
const computedHost = defineComponentInstance(getCurrentVue(), {
computed: {
$$state: {
get,
Expand Down
4 changes: 2 additions & 2 deletions src/apis/watch.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ComponentInstance } from '../component';
import { Ref, isRef } from '../reactivity';
import { assert, logError, noopFn } from '../utils';
import { createComponentInstance } from '../helper';
import { defineComponentInstance } from '../helper';
import { getCurrentVM, getCurrentVue } from '../runtimeContext';
import { WatcherPreFlushQueueKey, WatcherPostFlushQueueKey } from '../symbols';

Expand Down Expand Up @@ -262,7 +262,7 @@ export function watch(
let vm = getCurrentVM();
if (!vm) {
if (!fallbackVM) {
fallbackVM = createComponentInstance(getCurrentVue());
fallbackVM = defineComponentInstance(getCurrentVue());
}
vm = fallbackVM;
} else if (!hasWatchEnv(vm)) {
Expand Down
32 changes: 30 additions & 2 deletions src/component/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,31 @@ interface ComponentOptionsWithoutProps<Props = unknown, RawBindings = Data> {
setup?: SetupFunction<Props, RawBindings>;
}

// overload 1: object format with no props
export function defineComponent<RawBindings>(
options: ComponentOptionsWithoutProps<unknown, RawBindings>
): VueProxy<unknown, RawBindings>;
// overload 2: object format with object props declaration
// see `ExtractPropTypes` in ./componentProps.ts
export function defineComponent<
Props,
RawBindings = Data,
PropsOptions extends ComponentPropsOptions = ComponentPropsOptions
>(
// prettier-ignore
options: (
// prefer the provided Props, otherwise infer it from PropsOptions
HasDefined<Props> extends true
? ComponentOptionsWithProps<PropsOptions, RawBindings, Props>
: ComponentOptionsWithProps<PropsOptions, RawBindings>) &
Omit<Vue2ComponentOptions<Vue>, keyof ComponentOptionsWithProps<never, never>>
): VueProxy<PropsOptions, RawBindings>;
// implementation, close to no-op
export function defineComponent(options: any) {
return options as any;
}

// createComponent is kept around for retro-compatibility
// overload 1: object format with no props
export function createComponent<RawBindings>(
options: ComponentOptionsWithoutProps<unknown, RawBindings>
Expand All @@ -89,7 +114,10 @@ export function createComponent<
: ComponentOptionsWithProps<PropsOptions, RawBindings>) &
Omit<Vue2ComponentOptions<Vue>, keyof ComponentOptionsWithProps<never, never>>
): VueProxy<PropsOptions, RawBindings>;
// implementation, close to no-op
// implementation, deferring to defineComponent, but logging a warning in dev mode
export function createComponent(options: any) {
return options as any;
if (process.env.NODE_ENV !== 'production') {
Vue.util.warn('`createComponent` has been renamed to `defineComponent`.');
}
return defineComponent(options);
}
1 change: 1 addition & 0 deletions src/component/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export {
Data,
createComponent,
defineComponent,
SetupFunction,
SetupContext,
ComponentInstance,
Expand Down
4 changes: 2 additions & 2 deletions src/createElement.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Vue from 'vue';
import { currentVM, getCurrentVue } from './runtimeContext';
import { createComponentInstance } from './helper';
import { defineComponentInstance } from './helper';
import { warn } from './utils';

type CreateElement = Vue['$createElement'];
Expand All @@ -11,7 +11,7 @@ const createElement: CreateElement = function createElement(...args: any) {
if (!currentVM) {
warn('`createElement()` has been called outside of render function.');
if (!fallbackCreateElement) {
fallbackCreateElement = createComponentInstance(getCurrentVue()).$createElement;
fallbackCreateElement = defineComponentInstance(getCurrentVue()).$createElement;
}

return fallbackCreateElement.apply(fallbackCreateElement, args);
Expand Down
2 changes: 1 addition & 1 deletion src/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function ensureCurrentVMInFn(hook: string): ComponentInstance {
return vm!;
}

export function createComponentInstance<V extends Vue = Vue>(
export function defineComponentInstance<V extends Vue = Vue>(
Ctor: VueConstructor<V>,
options: ComponentOptions<V> = {}
) {
Expand Down
8 changes: 7 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ if (currentVue && typeof window !== 'undefined' && window.Vue) {
export default plugin;
export { default as createElement } from './createElement';
export { SetupContext };
export { createComponent, ComponentRenderProxy, PropType, PropOptions } from './component';
export {
createComponent,
defineComponent,
ComponentRenderProxy,
PropType,
PropOptions,
} from './component';
// For getting a hold of the interal instance in setup() - useful for advanced
// plugins
export { getCurrentVM as getCurrentInstance } from './runtimeContext';
Expand Down
4 changes: 2 additions & 2 deletions src/reactivity/reactive.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AnyObject } from '../types/basic';
import { getCurrentVue } from '../runtimeContext';
import { isPlainObject, def, hasOwn, warn } from '../utils';
import { isComponentInstance, createComponentInstance } from '../helper';
import { isComponentInstance, defineComponentInstance } from '../helper';
import {
AccessControlIdentifierKey,
ReactiveIdentifierKey,
Expand Down Expand Up @@ -113,7 +113,7 @@ function observe<T>(obj: T): T {
if (Vue.observable) {
observed = Vue.observable(obj);
} else {
const vm = createComponentInstance(Vue, {
const vm = defineComponentInstance(Vue, {
data: {
$$state: obj,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createComponent, createElement as h, ref, SetupContext } from '../../src';
import { createComponent, defineComponent, createElement as h, ref, SetupContext } from '../../src';
import Router from 'vue-router';

const Vue = require('vue/dist/vue.common.js');
Expand All @@ -18,16 +18,16 @@ const isSubType = <SuperType, SubType>(shouldBeEqual: SubType extends SuperType
expect(true).toBe(true);
};

describe('createComponent', () => {
describe('defineComponent', () => {
it('should work', () => {
const Child = createComponent({
const Child = defineComponent({
props: { msg: String },
setup(props) {
return () => h('span', props.msg);
},
});

const App = createComponent({
const App = defineComponent({
setup() {
const msg = ref('hello');
return () =>
Expand All @@ -45,7 +45,7 @@ describe('createComponent', () => {
});

it('should infer props type', () => {
const App = createComponent({
const App = defineComponent({
props: {
a: {
type: Number,
Expand All @@ -69,7 +69,7 @@ describe('createComponent', () => {
interface IPropsType {
b: string;
}
const App = createComponent<IPropsType>({
const App = defineComponent<IPropsType>({
props: {
b: {},
},
Expand All @@ -86,7 +86,7 @@ describe('createComponent', () => {
});

it('no props', () => {
const App = createComponent({
const App = defineComponent({
setup(props, ctx) {
isTypeEqual<SetupContext, typeof ctx>(true);
isTypeEqual<unknown, typeof props>(true);
Expand All @@ -98,7 +98,7 @@ describe('createComponent', () => {
});

it('infer the required prop', () => {
const App = createComponent({
const App = defineComponent({
props: {
foo: {
type: String,
Expand Down Expand Up @@ -138,10 +138,42 @@ describe('createComponent', () => {
{
path: '/',
name: 'root',
component: createComponent({}),
component: defineComponent({}),
},
],
});
});
});

describe('retro-compatible with createComponent', () => {
it('should still work and warn', () => {
const warn = jest.spyOn(global.console, 'error').mockImplementation(() => null);
const Child = createComponent({
props: { msg: String },
setup(props) {
return () => h('span', props.msg);
},
});

const App = createComponent({
setup() {
const msg = ref('hello');
return () =>
h('div', [
h(Child, {
props: {
msg: msg.value,
},
}),
]);
},
});
const vm = new Vue(App).$mount();
expect(vm.$el.querySelector('span').textContent).toBe('hello');
expect(warn.mock.calls[0][0]).toMatch(
'[Vue warn]: `createComponent` has been renamed to `defineComponent`.'
);
warn.mockRestore();
});
});
});

0 comments on commit 497b7e5

Please sign in to comment.