npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vue/composition-api

v1.7.2

Published

Provide logic composition capabilities for Vue.

Downloads

596,052

Readme

@vue/composition-api

用于提供 组合式 API 的 Vue 2 插件.

npm GitHub Workflow Status

English | 中文 ・ 组合式 API 文档

⚠️ 随着 Vue 2.7的发布,它内置了Composition API,你不再需要这个插件了。因此,这个插件已经进入维护模式,将只支持Vue 2.6 或更早的版本。本项目将在 2022 年底达到生命终点(EOL)。

安装

NPM

npm install @vue/composition-api
# or
yarn add @vue/composition-api

在使用 @vue/composition-api 前,必须先通过 Vue.use() 进行安装。之后才可使用新的 组合式 API 进行组件开发。

import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'

Vue.use(VueCompositionAPI)
// 使用 API
import { ref, reactive } from '@vue/composition-api'

:bulb: 当迁移到 Vue 3 时,只需简单的将 @vue/composition-api 替换成 vue 即可。你现有的代码几乎无需进行额外的改动。

CDN

在 Vue 之后引入 @vue/composition-api ,插件将会自动完成安装。

<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/@vue/[email protected]"></script>

@vue/composition-api 将会暴露在全局变量 window.VueCompositionAPI 中。

const { ref, reactive } = VueCompositionAPI

TypeScript 支持

本插件要求使用 TypeScript 4.2 或以上版本

为了让 TypeScript 在 Vue 组件选项中正确地进行类型推导,我们必须使用 defineComponent 来定义组件:

import { defineComponent } from '@vue/composition-api'

export default defineComponent({
  // 类型推断启用
})

JSX/TSX

JSX 现已在 vuejs/jsx 中官方支持。你可以根据这篇文档开启支持。你也可以使用由 @luwanquan 维护的社区版本 babel-preset-vca-jsx

对于 TSX 支持,请在你的项目中创建如下声明文件:

// file: shim-tsx.d.ts
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; // specify the property name to use
    }
    interface IntrinsicElements {
      [elem: string]: any;
    }
  }
}

SSR

尽管 Vue 3 暂时没有给出确定的 SSR 的 API,这个插件实现了 onServerPrefetch 生命周期钩子函数。这个钩子允许你使用传统 API 中的 serverPrefetch 函数。

import { onServerPrefetch } from '@vue/composition-api'

export default {
  setup(props, { ssrContext }) {
    const result = ref()

    onServerPrefetch(async () => {
      result.value = await callApi(ssrContext.someId)
    })

    return {
      result,
    }
  },
}

浏览器兼容性

@vue/composition-api 支持所有现代浏览器以及IE11+。对于更低版本的IE浏览器你需要安装WeakMap polyfill (例如使用 core-js库)。

限制

:white_check_mark: 支持     :x: 不支持

Ref 自动展开 (unwrap)

const a = {
  count: ref(0),
}
const b = reactive({
  list: [a], // `a.count` 不会自动展开!!
})

// `count` 不会自动展开, 须使用 `.value`
b.list[0].count.value === 0 // true
const b = reactive({
  list: [
    {
      count: ref(0), // 不会自动展开!!
    },
  ],
})

// `count` 不会自动展开, 须使用 `.value`
b.list[0].count.value === 0 // true
const a = reactive({
  count: ref(0),
})
const b = reactive({
  list: [a],
})
// 自动展开
b.list[0].count === 0 // true

b.list.push(
  reactive({
    count: ref(1),
  })
)
// 自动展开
b.list[1].count === 1 // true

模板 Refs

<template>
  <div ref="root"></div>
</template>

<script>
  export default {
    setup() {
      const root = ref(null)

      onMounted(() => {
        // 在初次渲染后 DOM 元素会被赋值给 ref
        console.log(root.value) // <div/>
      })

      return {
        root,
      }
    },
  }
</script>
export default {
  setup() {
    const root = ref(null)

    onMounted(() => {
      // 在初次渲染后 DOM 元素会被赋值给 ref
      console.log(root.value) // <div/>
    })

    return {
      root,
    }
  },
  render() {
    // 使用 JSX
    return () => <div ref="root" />
  },
}
<template>
  <div :ref="el => root = el"></div>
</template>

<script>
  export default {
    setup() {
      const root = ref(null)

      return {
        root,
      }
    },
  }
</script>
export default {
  setup() {
    const root = ref(null)

    return () =>
      h('div', {
        ref: root,
      })

    // 使用 JSX
    return () => <div ref={root} />
  },
}

:warning: 警告: SetupContext.refs 并非 Vue 3.0 的一部分, @vue/composition-api 将其暴露在 SetupContext 中只是临时提供一种变通方案。

如果你依然选择在 setup() 中写 render 函数,那么你可以使用 SetupContext.refs 来访问模板引用,它等价于 Vue 2.x 中的 this.$refs:

export default {
  setup(initProps, setupContext) {
    const refs = setupContext.refs
    onMounted(() => {
      // 在初次渲染后 DOM 元素会被赋值给 ref
      console.log(refs.root) // <div/>
    })

    return () =>
      h('div', {
        ref: 'root',
      })

    // 使用 JSX
    return () => <div ref="root" />
  },
}

如果项目使用了 TypeScript,你还需要扩展 SetupContext 类型:

import Vue from 'vue'

declare module '@vue/composition-api' {
  interface SetupContext {
    readonly refs: { [key: string]: Vue | Element | Vue[] | Element[] }
  }
}

Reactive

此行为与 Vue 2 中的 Vue.observable 一致

:bulb: 在 Vue 3 中,reactive() 会返回一个新的的代理对象

⚠️ 警告: setdel 并非 Vue 3 的一部分。由于 Vue 2.x 响应式系统的限制, 我们在这里提供它们作为一种变通方案。 在 Vue 2中,你将需要调用set 去追踪object上新的属性 (与Vue.set类似,但用于由 Composition API 创建的reactive objects)。在 Vue 3 中,你只需要像对待普通对象一样直接为属性赋值即可。

同样地, 在 Vue 2 中你将需要调用del确保响应式对象中属性的删除将触发视图更新 (与Vue.delete类似,但用于由 Composition API 创建的reactive objects)。在Vue3中,你只需要通过调用 delete foo.bar 来删除它们。

import { reactive, set, del } from '@vue/composition-api'

const a = reactive({
  foo: 1
})

// 添加新的响应式属性
set(a, 'bar', 1)

// 刪除属性并触发响应式更新
del(a, 'bar')

Watch

watch(
  () => {
    /* ... */
  },
  {
    immediate: true,
    onTrack() {}, // 不可用
    onTrigger() {}, // 不可用
  }
)

createApp

在 Vue3 中,引入了 createApp() 来隔离不同应用实例的上下文(plugin, components 等)。 由于 Vue2 的设计,在这个插件中,我们提供 createApp() 作为一个向前兼容的 API ,它只是全局的一个别名。

const app1 = createApp(RootComponent1)
app1.component('Foo', Foo) // 相当于 Vue.component('Foo', Foo)
app1.use(VueRouter) // 相当于 Vue.use(VueRouter)

const app2 = createApp(RootComponent2)
app2.component('Bar', Bar) // 相当于 Vue.component('Bar', Bar)

createElement / h

在 Vue2中 createElement / h 只能通过 render() 函数访问。要在 render()之外使用它, 你可以显式地给它绑定一个组件实例。

:warning: 警告: 此功能是作为 Vue 2 的变通方法提供的,它不是 Vue 3 API 的一部分。

import { h as _h } from '@vue/composition-api'

export default {
  setup() {
    const vm = getCurrentInstance()
    const h = _h.bind(vm)

    return () =>
      h('div', {
        ref: 'root',
      })
  },
}

shallowReadonly

:bulb: 在 Vue 3 中,shallowReadonly() 会返回一个新的的代理对象

readonly

readonly() 只在类型层面提供和 Vue 3 的对齐。在其返回值或其属性上使用 isReadonly() 检查的结果将无法保证。

props

defineComponent({
  setup(props) {
    const { bar } = toRefs(props.foo) // it will `warn`

    // use this instead
    const { foo } = toRefs(props)
    const a = foo.value.bar
  }
})

computed().effect

由于实现上的不同, 在 @vue/composition-api 中没有 ReactiveEffect 这种概念。 因此, effecttrue 只是为了能够区分 computed 和 refs:

function isComputed<T>(o: ComputedRef<T> | unknown): o is ComputedRef<T>
function isComputed(o: any): o is ComputedRef {
  return !!(isRef(o) && o.effect)
}

缺失的 API

以下在 Vue 3 新引入的 API ,在本插件中暂不适用:

  • onRenderTracked
  • onRenderTriggered
  • isProxy

data() 中使用组合式 API

export default {
  data() {
    return {
      // 在模版中会成为 { a: { value: 1 } }
      a: ref(1),
    }
  },
}

emit 选项

defineComponent({
  emit: {
    // 无效
    submit: (eventOption) => {
      if (...) {
        return true
      } else {
        console.warn('Invalid submit event payload!')
        return false
      }
    }
  }
})

性能影响

由于 Vue 2 的公共 API 的限制,@vue/composition-api 不可避免地引入了额外的性能开销。除非在极端情况下,否则这并不会对你造成影响。

你可以查看这个 跑分结果 了解更多信息。