Vue3 的组合式 API 浅谈(一)

180 阅读3分钟

Vue3 和 Vue2 版本的区别

Vue3 是 Vue 的一个里程碑式的进化,相比 Vue2 版本有很多变更,有必要先介绍一下Vue3 与 Vue2 之间主要的一些区别:

  1. Vue3 框架做了大量的性能优化,包括虚拟 DOM,编译模板、代理的新数据监听,体积更小的打包文件等。
  2. 新的组合式 API (composition-api),更适合大型项目的构建,去除繁琐的 this 操作;
  3. 由于是基于 TypeScript 编写,对 TypeScript 原生支持更好,更强大的智能类型推导功能;
  4. 生命周期的一些改变,vue2 中的 beforeCreate 和 created 被一个新增的 setup 生命周期函数代替;
  5. 一些常见 API 如 v-model 的变化,支持对一个组件同时进行多个 v-model 的数据绑定。

需要提到一点,尤大为了兼容照顾老版本 Vue2 的用户使用方便,设计 Vue3 是向下兼容 Vue2 API 的,但是 Vue3 中提供了一种全新的 Composition API,即组合式 API。

setup 函数 ———— 组合式入口函数

  • 类型: Function

setup 函数是一个新的组件选项。它是 Vue3 组件内部使用组合式 API 的入口函数。

  • 调用时机:

在创建组件实例前,在初始 prop 解析之后立即调用 setup。它将接收两个参数:propscontext。在生命周期方面,它是在 beforeCreate钩子之前调用的。

需要注意的是,在 setup 中应该避免使用 this,因为它不会找到组件实例。setup 的调用发生在 datacomputed或 methods 被解析之前,所以它们无法在 setup 中被获取。

  • setup 函数的传入参数: setup 函数将接收到的 prop 作为其第一个参数,此 props 对象是响应式的,即在传入新的 props 时会对其进行更新,可通过使用 watchEffect 或 watch 进行观测和响应。 不要使用 ES6 语法解构 props 对象,否则它会失去响应式。

props 对象在开发过程中对于用户区代码是不可变的 (如果用户代码尝试对其进行更改,则会发出警告)。

第二个参数 context 提供了一个上下文对象,该对象暴露了多个在 setup 中可使用的对象和函数: attrsslots 和 emit 分别等同于 $attrs$slots和 $emit 实例 property。

const MyComponent = {
  setup(props, context) {
    context.attrs
    context.slots
    context.emit
    context.expose
  }
}

attrs 和 slots 是内部组件实例上相应值的代理。这样可以确保它们始终会显示最新值。

其实,组件使用 props 比其他 property 更常见,并且很多情况下组件仅使用一个参数 props

举一个把 setup 添加到组件中的实例:

export default {
  components: { A, B, C },
  props: {
    user: {
      type: String,
      required: true
    }
  },
  setup(props) {
    const nameList = [props.user]
    return { nameList } // 这里返回的任何内容都可以用于组件的其余部分
  }
  // 组件的“其余部分”
}

需要注意,这样定义的 nameList 变量是非响应式的,不能达到使用预期。

如果需要构建响应式的变量,那么需要用到 ref 函数。

带 ref 的响应式变量

在 Vue 3中,我们可以通过一个新的 ref 函数使任何响应式变量在任何地方起作用,如下所示:

import { ref } from 'vue'

const number = ref(0)

ref 接收参数并将其包裹在一个带有 value property 的对象中返回,然后可以使用该 property 访问或更改响应式变量的值。把数据封装成对象,这样我们就可以在整个应用中安全传递它,而不必担心失去其响应性特性。

setup (props) {
  const nameList = ref([])
  const getnameList = () => {
    nameList.value = [props.user]
  }

  onMounted(getnameList) // 在 `mounted` 时调用 `getnameList`

  return {
    nameList,
    getnameList
  }
}

如果需要对 prop 的变化做出反应。需要用到独立的 watch 函数

watch 响应式更改

watch 设置变量的监听器,它接受3个参数:

  • 一个想要监听的响应式引用或 getter 函数
  • 一个回调函数
  • 可选的配置选项
import { ref, watch } from 'vue'

const counter = ref(0)
watch(counter, (newValue, oldValue) => {
 console.log('The new counte is ' + counter.value)
})