Vue Composition API
Vue Composition API
@vue/composition-api
provides a way to use Vue 3.0
's Composition api in Vue 2.x
.
中文文档
Navigation
Installation
npm
npm install @vue/composition-api --save
yarn
yarn add @vue/composition-api
CDN
<script src="https://unpkg.com/@vue/composition-api/dist/vue-composition-api.umd.js"></script>
By using the global variable window.vueCompositionApi
Usage
You must install @vue/composition-api
via Vue.use()
before using other APIs:
import Vue from 'vue';
import VueCompositionApi from '@vue/composition-api';
Vue.use(VueCompositionApi);
After installing the plugin you can use the Composition API to compose your component.
TypeScript
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 defineComponent
:
import { defineComponent } from '@vue/composition-api';
const Component = defineComponent({
});
const Component = {
};
TSX
:rocket: An Example Repository with TS and TSX support is provided to help you start.
To support TSX, create a declaration file with following content in your project.
import Vue, { VNode } from 'vue';
import { ComponentRenderProxy } from '@vue/composition-api';
declare global {
namespace JSX {
interface Element extends VNode {}
interface ElementClass extends ComponentRenderProxy {}
interface ElementAttributesProperty {
$props: any;
}
interface IntrinsicElements {
[elem: string]: any;
}
}
}
Limitations
Ref
Unwrap
Unwrap
is not working with Array index.
Should not store ref
as a direct child of Array
:
const state = reactive({
list: [ref(0)],
});
state.list[0].value === 0;
state.list.push(ref(1));
state.list[1].value === 1;
Should not use ref
in a plain object when working with Array
:
const a = {
count: ref(0),
};
const b = reactive({
list: [a],
});
b.list[0].count.value === 0;
const b = reactive({
list: [
{
count: ref(0),
},
],
});
b.list[0].count.value === 0;
Should always use ref
in a reactive
when working with Array
:
const a = reactive({
count: ref(0),
});
const b = reactive({
list: [a],
});
b.list[0].count === 0;
b.list.push(
reactive({
count: ref(1),
})
);
b.list[1].count === 1;
Using reactive
will mutate the origin object
This is an limitation of using Vue.observable
in Vue 2.
Vue 3 will return an new proxy object.
watch()
API
onTrack
and onTrigger
are not available in WatchOptions
.
Template Refs
:white_check_mark:
Support :x: Not Supported
:white_check_mark:
String ref && return it from setup()
:
<template>
<div ref="root"></div>
</template>
<script>
export default {
setup() {
const root = ref(null);
onMounted(() => {
console.log(root.value);
});
return {
root,
};
},
};
</script>
:white_check_mark:
String ref && return it from setup()
&& Render Function / JSX:
export default {
setup() {
const root = ref(null);
onMounted(() => {
console.log(root.value);
});
return {
root,
};
},
render() {
return () => <div ref="root" />;
},
};
:x: Function ref:
<template>
<div :ref="el => root = el"></div>
</template>
<script>
export default {
setup() {
const root = ref(null);
return {
root,
};
},
};
</script>
:x: Render Function / JSX in setup()
:
export default {
setup() {
const root = ref(null);
return () =>
h('div', {
ref: root,
});
return () => <div ref={root} />;
},
};
If you really want to use template refs in this case, you can access vm.$refs
via SetupContext.refs
.
:warning: Warning: The SetupContext.refs
won't exist in Vue 3.0
. @vue/composition-api
provide it as a workaround here.
export default {
setup(initProps, setupContext) {
const refs = setupContext.refs;
onMounted(() => {
console.log(refs.root);
});
return () =>
h('div', {
ref: 'root',
});
return () => <div ref="root" />;
},
};
You may also need to augment the SetupContext
when working with TypeScript:
import Vue from 'vue';
import VueCompositionApi from '@vue/composition-api';
Vue.use(VueCompositionApi);
declare module '@vue/composition-api/dist/component/component' {
interface SetupContext {
readonly refs: { [key: string]: Vue | Element | Vue[] | Element[] };
}
}
SSR
Even if there is no definitive Vue 3 API for SSR yet, this plugin implements the onServerPrefetch
lifecycle hook that allows you to use the serverPrefetch
hook found in the classic API.
import { onServerPrefetch } from '@vue/composition-api';
export default {
setup (props, { ssrContext }) {
const result = ref();
onServerPrefetch(async () => {
result.value = await callApi(ssrContext.someId);
});
return {
result,
};
},
};