vue3 组合式api

127 阅读2分钟

setup

一个组件选项,在组件被创建之前props 被解析之后执行。它是组合式 API 的入口。

接收两个参数:

  1. props :该 props 对象将仅包含显性声明的 prop。并且,所有声明了的 prop,不管父组件是否向其传递了,都将出现在 props 对象中。其中未被传入的可选的 prop 的值会是 undefined。 如果需要检测一个可选的 prop 是否未被传递,你可以将其默认值设置为一个 Symbol:
const isAbsent = Symbol()
export default {
  props: {
    foo: { default: isAbsent }
  },
  setup(props) {
    if (props.foo === isAbsent) {
      // foo 没有被传入。
    }
  }
}
  1. {SetupContext} context 看一下类型
interface SetupContext {
  attrs: Data // 数据
  slots: Slots // 插槽
  emit: (event: string, ...args: unknown[]) => void // 发送
  expose: (exposed?: Record<string, any>) => void // 暴漏
}

如果返回了渲染函数,则不能再返回其他 property。如果需要将 property 暴露给外部访问,比如通过父组件的 ref,可以使用 expose

import { h } from 'vue'

export default {
  setup(props, { expose }) {
    const reset = () => {
      // 某些重置逻辑
    }
    
    // expose 只能被调用一次。
    // 如果需要暴露多个 property,则它们
    // 必须全部包含在传递给 expose 的对象中。
    expose({
      reset
    })

    return () => h('div')
  }
}

生命周期钩子

通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。

1657163107078.png

Provide / Inject

provide 和 inject 启用依赖注入。这两者只能在使用当前活动实例的setup() 期间被调用。父组件提供的provide可以在任意子组件,或者子组件的后代们进行获取到,并且如果provide的value是ref或者reactive类型,则修改父组件的值也会在后代中响应。注意如果需要修改响应的数据,建议在父组件中去修改,而不建议直接在inject的地方去做修改。可以在父组件中提供修改的方法。如果害怕误修改,可以给添加readonly,例如 provide('location', readonly(location))

provide 函数允许你通过两个参数定义 property:

  1. name (<String> 类型)
  2. value

父组件,在父组件中provide的一个值出去

<template>
  <div id="app">
    <MyBook></MyBook> // 子组件
  </div>
</template>
<script>
import MyBook from './components/mybook.vue'
import { provide } from 'vue' // 需要引入provide
export default {
  name: 'App',
  components: {
    MyBook
  },
  setup() {
    provide('location', 'North Pole') // 如果想父组件修改响应子组件,这里可以改为ref变量,或者reactive
    provide('geolocation', {
      longitude: 90,
      latitude: 135
    })
  },
}
</script>

子组件,在子组件中就可以直接inject 进来,

<template>
  <div>
    {{geolocations}}
  </div>
</template>

<script>
import { inject } from 'vue' // 引入inject,inject不用考虑引入的层级,在只要祖先有provide值就可以。

export default {
  setup( props, { expose } ) {
    const geolocations = inject('geolocation') // 注入geolocation值

    return {
      geolocations,
    }
  },
}
</script>