@vue/composition-api速成课(通俗易懂版)

简介: @vue/composition-api速成课(通俗易懂版)

Composition API 将是 Vue 3 的核心功能,它具有许多更改和性能改进。我们也可以在 Vue 2 中通过 npm 插件@vue/composition-api 使用它。本人重点将带你了解:

  1. @vue/composition-api常见 api 使用
  2. vue3 代码逻辑提取和复用
  3. 如何使用provide+inject替代vuex方案


vue2 使用 composition-api


主文件 main.ts 或者 app.vue 添加

import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)

Composition API 不再传入 data、mounted 等参数, 通过引入的 refonMounted等方法实现数据的双向绑定、生命周期函数的执行。


核心语法


reactive:接收一个普通对象然后返回该普通对象的响应式代理。

ref:接受一个参数值并返回一个响应式且可改变的 ref 对象。ref 对象拥有一个指向内部值的单一属性 .value。

computed:传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象。

readonly:传入一个对象(响应式或普通)或 ref,返回一个原始对象的只读代理。一个只读的代理是“深层的”,对象内部任何嵌套的属性也都是只读的。

watchEffect:立即执行传入的一个函数,并响应式追踪其依赖,并在其依赖变更时重新运行该函数。可显式的调用返回值以停止侦听。

watch:全等效于 2.x this.\$watch (以及 watch 中相应的选项)。


setup 函数


现在要介绍的第一个 API 就是 setup 函数。setup 函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点。先看个简单 demo

<template>
  <button @click="increase">count is: {{ count }}</button>
</template>
<script>
  export default {
    setup() {
      let count = 0
      const increase = () => count++
      return { count, increase }
    },
  }
</script>

1、调用时机

创建组件实例,然后初始化 props ,紧接着就调用 setup 函数。从 vue2 生命周期钩子的视角来看,它会在 beforeCreate 钩子之后,created 之前被调用。

2、模板中使用

如果 setup 返回一个对象,则对象的属性将会被合并到组件模板的渲染上下文。

3、渲染函数 / JSX 中使用

setup 也可以返回一个函数,函数中也能使用当前 setup 函数作用域中的响应式数据:

import { h, ref, reactive } from '@vue/composition-api'
export default {
  setup() {
    const count = ref(0)
    const object = reactive({ foo: 'bar' })
    return () => h('div', [count.value, object.foo])
  },
}

4、两个参数props(注意 props 对象是响应式的),context(上下文对象,从原来 2.x 中 this 选择性地暴露了一些 property。)

const MyComponent = {
  setup(props, context) {
    let {
      attrs,
      emit,
      isServer,
      listeners,
      parent,
      refs,
      root,
      slots,
      ssrContext,
    } = context
  },
}


ref & reactive


App.vue 中,点击事件绑定了 increase,然后修改了 count, 但是页面并没有发生改变,这是因为 setup 函数返回的对象中 count 不是响应式数据, 那么如何创建响应式数据呢?此时就要掌握响应式系统 API,我们可以使用 refreactive 创建。

<template>
  <button @click="increase">
    count is: {{ count }}, state.count is {{ state.count }}
  </button>
</template>
<script>
  import { ref, reactive } from 'vue'
  export default {
    setup() {
      let count = ref(0) // { value: 0 }
      let state = reactive({ number: 0 })
      const increase = () => {
        count.value++
        state.count++
      }
      return { count, state, increase }
    },
  }
</script>

接受一个参数值并返回一个响应式且可改变的 ref 对象。ref 对象拥有一个指向内部值的单一属性 .value

ref 作为渲染上下文的属性返回(即在 setup() 返回的对象中)并在模板中使用时, 它会自动解套,无需在模板内额外书写 .value

Vue 本身已经有 "ref" 的概念了。但只是为了在模板中获取 DOM 元素或组件实例 (“模板引用”)。新的 ref 系统同时用于逻辑状态和模板引用。

reactive 接收一个普通对象然后返回该普通对象的响应式代理。

响应式转换是“深层的”:会影响对象内部所有嵌套的属性。基于 ES2015 的 Proxy 实现,返回的代理对象不等于原始对象。建议仅使用代理对象而避免依赖原始对象。

不要解构返回的代理对象,那样会使其失去响应性:

<template>
  <button @click="increase">count is: {{ count }}</button>
</template>
<script>
  import { ref, reactive } from '@vue/composition-api'
  export default {
    setup() {
      let state = reactive({ count: 0 })
      const increase = () => state.count++
      return { ...state, increase } // 展开state属性将失去响应式
    },
  }
</script>


toRef 和 toRefs


那如果我们真的想展开 state 的属性,在模板使用 count 而不是 state.count 的写法那怎么办呢?我们可以使用 toReftoRefs 这两个 API,进行转换成 ref 对象,之前已经介绍了 ref 对象是可以直接在模板中使用的。

toRef 可以用来为一个 reactive 对象的属性创建一个 ref。这个 ref 可以被传递并且能够保持响应性。

<template>
  <button @click="increase">
    count is: {{ count }},count2 is: {{ count2 }}
  </button>
</template>
<script>
  import { ref, reactive, toRef, toRefs } from '@vue/composition-api'
  export default {
    setup() {
      let state = reactive({ count: 0 })
      let countRef = toRef(state, 'count')
      let state2 = reactive({ count2: 0 })
      const increase = () => state.count++
      let stateAsRefs = toRefs(state2)
      return { count: countRef, increase, ...stateAsRefs }
    },
  }
</script>

把一个响应式对象转换成普通对象,该普通对象的每个 property 都是一个 ref ,和响应式对象 property 一一对应。

computed & watch

const countDouble = computed(() => count.value * 2)
watch(
  () => state.count,
  (count, prevCount) => {
    /* ... */
  }
)


代码逻辑提取和复用


Composition API 的第一个明显优势是很容易提取逻辑。解决了


逻辑提取


export const useCount = (number) => {
  const count = ref(0)
  const increase = () => {
    count.value += 1
  }
  const reset = () => {
    count.value = 0
  }
  onMounted(() => {
    count.value = number
  })
  return {
    count,
    increase,
    reset,
  }
}


代码复用


// 另外一个文件使用:
const { count, increase } = useCount(1)
console.log(count) //输出1
increase()
console.log(count) //输出2
reset()
console.log(count) //输出0

有效的解决了 mixins 复用命名冲突,难以识别命名来自哪个 mixin 文件的问题。


替代 vuex 状态管理


状态 store 可以放在一个单一的文件或者目录里,比如设置一个全局组件可以只用的配置 config

//context/config.ts
import { provide, inject, ref, onMounted, readonly } from '@vue/composition-api'
const configSymbol: symbol = Symbol()
export const useProvider = {
  setup() {
    let config = ref(null)
    const configServer = async () => {
      // await 一些异步操作,比如api等
      config.value = { name: '名字' }
    }
    onMounted(async () => {
      await configServer()
    })
    provide(configSymbol, {
      //导出只读的config只有函数内部可以修改状态
      config: readonly(config),
    })
  },
}
export const useInject = () => {
  return inject(configSymbol)
}

在最顶层的组件(例如 main.ts)上注入,config 就可以在所有的组件中使用

import { defineComponent } from '@vue/composition-api'
import { useProvider } from './context/config'
export default defineComponent({
  setup() {
    useProvider()
  },
})

业务逻辑页面使用 config

import { useInject } from './context/config'
const Components = {
  setup() {
    const { config } = useInject()
    console.log(config.value.name) //输出“名字”
    return {
      config,
    }
  },
}

目录
相关文章
|
2月前
|
JavaScript 前端开发 API
深入浅出:Vue 3 Composition API 的魅力与实践
【2月更文挑战第13天】 本文将探索 Vue 3 的核心特性之一——Composition API。通过对比 Options API,本文旨在揭示 Composition API 如何提高代码的组织性和可复用性,并通过实际案例展示其在现代前端开发中的应用。不同于传统的技术文章摘要,我们将通过一个具体的开发场景,引领读者步入 Composition API 的世界,展现它如何优雅地解决复杂组件逻辑的管理问题,从而激发读者探索和运用 Vue 3 新特性的热情。
25 1
|
2月前
|
JavaScript 前端开发 API
深入浅出:Vue 3 Composition API 的魅力
【2月更文挑战第13天】 在前端开发的世界里,Vue.js 一直占据着重要的地位。随着 Vue 3 的推出,Composition API 成为了开发者热议的焦点。本文将从一个独特的视角探讨 Composition API 的核心优势,通过对比 Options API,解析其如何优化代码组织和提升项目的可维护性。我们将通过实际案例,深入理解 Composition API 的使用方法和最佳实践,帮助开发者更好地把握这一新工具,激发前端开发的无限可能。
|
设计模式 资源调度 JavaScript
vue脚手架基础API全面讲解【内附多个案例】
vue脚手架基础API全面讲解【内附多个案例】
vue脚手架基础API全面讲解【内附多个案例】
|
1月前
|
JavaScript API UED
Vue3.0新特性解析与实战:Composition API、Teleport与Suspense
【4月更文挑战第6天】Vue3.0引入了颠覆性的Composition API,通过函数式方法提升代码可读性和复用性,例如`setup()`、`ref`等,便于逻辑模块化。实战中,自定义的`useUser`函数可在多个组件中共享用户信息逻辑。另外,Teleport允许组件渲染到DOM特定位置,解决模态框等场景的上下文问题。再者,Suspense提供异步组件加载的延迟渲染,使用fallback内容改善用户体验。这些新特性显著优化了开发和性能,适应现代Web需求。
23 0
|
2月前
|
JavaScript 前端开发 API
深入浅出:Vue 3 Composition API 的革新之旅
【2月更文挑战第11天】本文将带你深入探索 Vue 3 中的 Composition API,一项革命性的特性,旨在提高代码的组织性和可复用性。我们将通过实际案例,对比传统的 Options API,深入理解 Composition API 如何优化组件逻辑的组织和重用,从而让前端开发变得更加高效和灵活。文章不仅仅是技术指南,更是对前端开发模式思考的一次探索之旅。
|
2月前
Vue3-Composition-API-学习笔记
Vue3-Composition-API-学习笔记
23 3
|
2月前
|
JavaScript 前端开发 API
深入浅出Vue 3 Composition API:重塑前端开发范式
【2月更文挑战第12天】 本文旨在深入探讨Vue 3中的Composition API,一种全新的组件和逻辑复用方式。相较于传统的Options API,Composition API提供了更为灵活和高效的代码组织机制。通过实例和对比分析,我们将揭示其如何优化代码结构,提升项目的可维护性和扩展性。文章不仅为初学者铺平进入Vue 3世界的道路,也为有经验的开发者提供了深度思考的视角,探索前端开发的新范式。
|
5月前
|
存储 JavaScript 前端开发
Vue3中的组合式API的详细教程和介绍
Vue3中的组合式API的详细教程和介绍
51 0
|
7月前
|
JavaScript 前端开发 API
Vue 3的革命性新特性:深入了解Composition API
Vue 3的革命性新特性:深入了解Composition API
43 1
|
11月前
|
前端开发 JavaScript 测试技术