重看Vue文档第四天(组合式API)

组合式API
  • 如果能够将同一个逻辑关注点相关代码收集在一起会更好,而这正是组合式API使我们能够做到的;
  • 新的setup选项在组件被创建之前执行,一旦props被解析完成,它就将被作为组合式API的入口;
  • setup的调用发生在dataproperty、computedproperty或methods被解析之前,所以它们无法在setup中被获取;
  • 在js中,NumberString等基本类型是通过值而非引用传递的;
  • ref为我们的值创建了一个响应式引用;
  • computed输出的是一个只读的响应式引用;
  • 使用toRefs创建对props中的userproperty的响应式引用;
  • 继续其他任务之前,我们首先要将上述代码提取到一个独立的组合式函数中;
  • 现在我们有了多个单独的功能模块,接下来就可以开始在组件中引入并使用它们了。
Setup
  • 使用setup函数时,它将接收两个参数:propscontext
  • props是响应式的,不能使用ES6解构,它会消除prop的响应性;
  • 如果需要解构prop,可以在setup函数中使用toRefs函数来完成此操作;
  • 传递给setup函数的第二个参数是contextcontext是一个普通的js对象,暴露了其它可能在setup中有用的值;
// MyBook.vue

export default {
  setup(props, context) {
    // Attribute (非响应式对象,等同于 $attrs)
    console.log(context.attrs)

    // 插槽 (非响应式对象,等同于 $slots)
    console.log(context.slots)

    // 触发事件 (方法,等同于 $emit)
    console.log(context.emit)

    // 暴露公共 property (函数)
    console.log(context.expose)
  }
}
  • context是一个普通的js对象(非响应式),意味着你可以安全地对context使用ES6解构:
// MyBook.vue
export default {
  setup(props, { attrs, slots, emit, expose }) {
    ...
  }
}
  • attrsslots是有状态的对象,但其property是非响应式的;
  • 如果打算根据attrsslots的更改应用副作用,那么应该在onBeforeUpdate生命周期钩子中执行此操作;
  • 执行setup时,你只能访问以下property:propsarrtsslotsemit,你将无法访问datacomputedmethodsrefs
  • 注意,从setup返回的refs在模板中访问时是被自动浅解包的,因此不应在模板中使用.value
  • 可以通过调用expose来解决这个问题,给它传递一个对象,其中定义的property将可以被外部组件实例访问,譬如通过父组件的模板ref访问。
生命周期钩子
  • 你可以通过在生命周期钩子前面加上“on”来访问组件的生命周期钩子;
  • 因为setup是围绕beforeCreatecreated生命周期钩子运行的,所以不需要显式地定义它们;
  • 这些函数接受一个回调函数,当钩子被组件调用时会被执行。
Provide/Inject
  • 当使用响应式provide/inject值时,建议尽可能将响应式property的所有修改限制在定义provide的组件内部;
  • 有时我们需要在注入数据的组件内部更新 inject 的数据;
  • 在这种情况下,我们建议 provide 一个方法来负责改变响应式 property;
  • 如果要确保通过 provide 传递的数据不会被 inject 的组件更改,我们建议对提供者的 property 使用 readonly
  • 使用provide:
<!-- src/components/MyMap.vue -->
<template>
  <MyMarker />
</template>

<script>
import { provide, reactive, readonly, ref } from 'vue'
import MyMarker from './MyMarker.vue'

export default {
  components: {
    MyMarker
  },
  setup() {
    const location = ref('North Pole')
    const geolocation = reactive({
      longitude: 90,
      latitude: 135
    })

    const updateLocation = () => {
      location.value = 'South Pole'
    }

    provide('location', readonly(location))
    provide('geolocation', readonly(geolocation))
    provide('updateLocation', updateLocation)
  }
}
</script>
  • 使用inject:
<!-- src/components/MyMarker.vue -->
<script>
import { inject } from 'vue'

export default {
  setup() {
    const userLocation = inject('location', 'The Universe')
    const userGeolocation = inject('geolocation')
    const updateUserLocation = inject('updateLocation')

    return {
      userLocation,
      userGeolocation,
      updateUserLocation
    }
  }
}
</script>
模板引用
  • 略。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值