Vue 学习之路 —— 组合式 API

8 篇文章 0 订阅

一、 setup

·1、Props 和 Context

setup 接受两个参数 props 和 context。

简例:

// MyBook.vue

import { toRefs, toRef } from 'vue'

setup(props) {
  const { title } = toRefs(props)

  console.log(title.value)
}

export default {
  setup(props, context) {
    const { title } = toRefs(props)

    console.log(title.value)

    // 如果 props 传入的参数是可选,则用 toRef

    const name = toRef(props, 'name')
    console.log(name.value)

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

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

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

    // 暴露公共 property (函数)
    console.log(context.expose)
  }
}

执行 setup 时,你只能访问以下 property

  • props
  • attrs
  • slots
  • emit

2、结合模板使用

简例

<!-- MyBook.vue -->
<template>
  <div>{{ collectionName }}: {{ readersNumber }} {{ book.title }}</div>
</template>

<script>
  import { ref, reactive } from 'vue'

  export default {
    props: {
      collectionName: String
    },
    setup(props) {
      const readersNumber = ref(0)
      const book = reactive({ title: 'Vue 3 Guide' })

      // 暴露给 template
      return {
        readersNumber,
        book
      }
    }
  }
</script>


// 也可以返回渲染函数

import { h, ref } from 'vue'
export default {
  setup(props, { expose }) {
    const count = ref(0)
    const increment = () => ++count.value

    expose({ // 通过 expose 去避免返回渲染函数导致其他变量无法运用在模板上
      increment
    })

    return () => h('div', count.value)
  }
}

尽量避免使用 this ,因为 setup 是创建组件之前调用的,很可能因为作用域不同,导致使用 this 会混淆。


二、生命周期钩子

选项式 APIHook inside setup
beforeCreateNot needed*
createdNot needed*
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted
errorCapturedonErrorCaptured
renderTrackedonRenderTracked
renderTriggeredonRenderTriggered
activatedonActivated
deactivatedonDeactivated

想要在beforeCreate 和 created 的钩子运行的代码可以直接在 setup 里面写,其他的如下简例:

// MyBook.vue

export default {
  setup() {
    // mounted
    onMounted(() => {
      console.log('Component is mounted!')
    })
  }
}

三、Provide / Inject

provide 允许通过两个参数定义,provide(name, value)

简例

<!-- src/components/MyMap.vue -->
<template>
  <MyMarker />
</template>

<script>
import { provide } from 'vue'
import MyMarker from './MyMarker.vue'

export default {
  components: {
    MyMarker
  },
  setup() {
    provide('location', 'North Pole')
    provide('geolocation', {
      longitude: 90,
      latitude: 135
    })
  }
}
</script>

然后我们需要用 inject 来接收,同样的也是两个参数 inject(name, 默认值)

简例

<!-- src/components/MyMarker.vue -->
<script>
import { inject } from 'vue'

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

    return {
      userLocation,
      userGeolocation
    }
  }
}
</script>

在使用 provide 和 inject 的时候,有以下几点需要注意的

  • 如果传的值需要更改的时候,更改的位置要在 provide 的组件里面
  • 如果有需要到在 inject 的组件里更改,provide 可以传递更改的方法
  • 为了避免误操作更改 provide 传递的值,可以设置 readonly

简例

<!-- 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>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值