Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Composition API plugin for Vue 2

License

NotificationsYou must be signed in to change notification settings

vuejs/composition-api

Repository files navigation

Vue 2 plugin forComposition API

npmGitHub Workflow StatusMinzipped size

English |中文Composition API Docs

⚠️ With the release ofVue 2.7, which has Composition API built-in,you no longer need this plugin. Thereby this plugin has entered maintenance mode and will only support Vue 2.6 or earlier. This project will reach End of Life by the end of 2022.

Installation

NPM

npm install @vue/composition-api# oryarn add @vue/composition-api

You must install@vue/composition-api as a plugin viaVue.use() before you can use theComposition API to compose your component.

importVuefrom'vue'importVueCompositionAPIfrom'@vue/composition-api'Vue.use(VueCompositionAPI)
// use the APIsimport{ref,reactive}from'@vue/composition-api'

💡 When you migrate to Vue 3, just replacing@vue/composition-api tovue and your code should just work.

CDN

Include@vue/composition-api after Vue and it will install itself automatically.

<scriptsrc="https://cdn.jsdelivr.net/npm/vue@2.6"></script><scriptsrc="https://cdn.jsdelivr.net/npm/@vue/composition-api@1.7.2"></script>

@vue/composition-api will be exposed to global variablewindow.VueCompositionAPI.

const{ ref, reactive}=VueCompositionAPI

TypeScript Support

TypeScript version>4.2 is required

To let TypeScript properly infer types inside Vue component options, you need to define components withdefineComponent

import{defineComponent}from'@vue/composition-api'exportdefaultdefineComponent({// type inference enabled})

JSX/TSX

JSX is now officially supported onvuejs/jsx. You can enable it by followingthis document. A community maintained version can be found atbabel-preset-vca-jsx by@luwanquan.

To support TSX, create a declaration file with the following content in your project.

// file: shim-tsx.d.tsimportVue,{VNode}from'vue';import{ComponentRenderProxy}from'@vue/composition-api';declare global{namespaceJSX{interfaceElementextendsVNode{}interfaceElementClassextendsComponentRenderProxy{}interfaceElementAttributesProperty{$props:any;// specify the property name to use}interfaceIntrinsicElements{[elem:string]:any;}}}

SSR

Even if there is no definitive Vue 3 API for SSR yet, this plugin implements theonServerPrefetch lifecycle hook that allows you to use theserverPrefetch hook found in the classic API.

import{onServerPrefetch}from'@vue/composition-api'exportdefault{setup(props,{ ssrContext}){constresult=ref()onServerPrefetch(async()=>{result.value=awaitcallApi(ssrContext.someId)})return{      result,}}}

Browser Compatibility

@vue/composition-api supports all modern browsers and IE11+. For lower versions IE you should installWeakMap polyfill (for example fromcore-js package).

Limitations

✅ Support     ❌ Not Supported

Ref Unwrap

Should NOT useref in a plain object when working withArray
consta={count:ref(0),}constb=reactive({list:[a],// `a.count` will not unwrap!!})// no unwrap for `count`, `.value` is requiredb.list[0].count.value===0// true
constb=reactive({list:[{count:ref(0),// no unwrap!!},],})// no unwrap for `count`, `.value` is requiredb.list[0].count.value===0// true
Should always useref in areactive when working withArray
consta=reactive({list:[reactive({count:ref(0),}),]})// unwrappeda.list[0].count===0// truea.list.push(reactive({count:ref(1),}))// unwrappeda.list[1].count===1// true

Template Refs

✅ String ref && return it fromsetup()
<template><divref="root"></div></template><script>exportdefault{setup(){constroot=ref(null)onMounted(()=>{// the DOM element will be assigned to the ref after initial renderconsole.log(root.value)// <div/>})return{        root,}},}</script>
✅ String ref && return it fromsetup() && Render Function / JSX
exportdefault{setup(){constroot=ref(null)onMounted(()=>{// the DOM element will be assigned to the ref after initial renderconsole.log(root.value)// <div/>})return{      root,}},render(){// with JSXreturn()=><divref="root"/>},}
❌ Function ref
<template><div:ref="el => root = el"></div></template><script>exportdefault{setup(){constroot=ref(null)return{        root,}},}</script>
❌ Render Function / JSX insetup()
exportdefault{setup(){constroot=ref(null)return()=>h('div',{ref:root,})// with JSXreturn()=><divref={root}/>},}
⚠️$refs accessing workaround

⚠️Warning: TheSetupContext.refs won't exist inVue 3.0.@vue/composition-api provide it as a workaround here.

If you really want to use template refs in this case, you can accessvm.$refs viaSetupContext.refs

exportdefault{setup(initProps,setupContext){constrefs=setupContext.refsonMounted(()=>{// the DOM element will be assigned to the ref after initial renderconsole.log(refs.root)// <div/>})return()=>h('div',{ref:'root',})// with JSXreturn()=><divref="root"/>},}

Reactive

⚠️reactive()mutates the original object

reactive usesVue.observable underneath which willmutate the original object.

💡 In Vue 3, it will return a new proxy object.

⚠️set anddel workaround for adding and deleting reactive properties

⚠️ Warning:set anddel do NOT exist in Vue 3. We provide them as a workaround here, due to the limitation ofVue 2.x reactivity system.

In Vue 2, you will need to callset to track new keys on anobject(similar toVue.set but forreactive objects created by the Composition API). In Vue 3, you can just assign them like normal objects.

Similarly, in Vue 2 you will need to calldel toensure a key deletion triggers view updates in reactive objects (similar toVue.delete but forreactive objects created by the Composition API). In Vue 3 you can just delete them by callingdelete foo.bar.

import{reactive,set,del}from'@vue/composition-api'consta=reactive({foo:1})// add new reactive keyset(a,'bar',1)// remove a key and trigger reactivitydel(a,'bar')

Watch

onTrack andonTrigger are not available inWatchOptions
watch(()=>{/* ... */},{immediate:true,onTrack(){},// not availableonTrigger(){},// not available})

createApp

⚠️createApp() is global

In Vue 3,createApp() is introduced to provide context(plugin, components, etc.) isolation between app instances. Due the design of Vue 2, in this plugin, we providecreateApp() as a forward compatible API which is just an alias of the global.

constapp1=createApp(RootComponent1)app1.component('Foo',Foo)// equivalent to Vue.component('Foo', Foo)app1.use(VueRouter)// equivalent to Vue.use(VueRouter)constapp2=createApp(RootComponent2)app2.component('Bar',Bar)// equivalent to Vue.component('Bar', Bar)

createElement /h

⚠️createElement /h workaround

createElement /h in Vue 2 is only accessable inrender() function. To use it outside ofrender(), you can explicitly bind a component instance to it.

⚠️Warning: This ability is provided as a workaround Vue 2, it's not part of the Vue 3 API.

import{has_h}from'@vue/composition-api'exportdefault{setup(){constvm=getCurrentInstance()consth=_h.bind(vm)return()=>h('div',{ref:'root',})},}

shallowReadonly

⚠️shallowReadonly() will create a new object and with the same root properties, new properties added willnot be readonly or reactive.

💡 In Vue 3, it will return a new proxy object.

readonly

⚠️readonly() providesonly type-level readonly check.

readonly() is provided as API alignment with Vue 3 on type-level only. UseisReadonly() on it or it's properties can not be guaranteed.

props

⚠️toRefs(props.foo) will incorrectly warn when accessing nested levels of props.
    ⚠️isReactive(props.foo) will return false.
defineComponent({setup(props){const{ bar}=toRefs(props.foo)// it will `warn`// use this insteadconst{ foo}=toRefs(props)consta=foo.value.bar}})

computed().effect

⚠️computed() has a propertyeffect set totrue instead of aReactiveEffect.

Due to the difference in implementation, there is no such concept as aReactiveEffect in@vue/composition-api. Therefore,effect is merelytrue to enable differentiating computed from refs:

functionisComputed<T>(o:ComputedRef<T>|unknown):o isComputedRef<T>functionisComputed(o:any):o isComputedRef{return!!(isRef(o)&&o.effect)}

Missing APIs

The following APIs introduced in Vue 3 are not available in this plugin.

  • onRenderTracked
  • onRenderTriggered
  • isProxy

Reactive APIs indata()

❌ Passingref,reactive or other reactive apis todata() would not work.
exportdefault{data(){return{// will result { a: { value: 1 }} in templatea:ref(1),}},}

emits Options

emits option is provided in type-level only, in order to align with Vue 3's type interface. Does NOT have actual effects on the code.
defineComponent({emits:{// has no effectssubmit:(eventOption)=>{if(...){        returntrue}else{console.warn('Invalid submit event payload!')returnfalse}}}})

Performance Impact

Due the limitation of Vue2's public API.@vue/composition-api inevitably introduces some performance overhead. Note that in most scenarios, this shouldn't be the source of performance issues.

You can check thebenchmark results for more details.

About

Composition API plugin for Vue 2

Resources

License

Stars

Watchers

Forks

Contributors93


[8]ページ先頭

©2009-2025 Movatter.jp