学习笔记-setup()

692 阅读3分钟

两个参数:

props

context

props

setup函数中的第一个参数是props, 并且props是响应式的, 传入新的prop时, 它将被更新。

因为props是响应式的, 所以不能使用es6的解构, 它会消除props的响应性

 

toRefs()

如果需要对props做解构, 可以使用toRefs对props进行处理

import { toRefs } from 'vue'
setup( props ) {
   const { title } = toRefs(props)
   console.log(title.value)
}

toRef()

如果title是可选的(不是必传的, require不为true), props中可能没有title, 这种情况下, toRefs不会为title创建一个ref, 需要使用toRef替代它

 import { toRef } from 'vue'
 setup( props ) {
   const { title } = toRef(props, 'title')
   console.log(title.value)
 }

 

context

context就是一个普通的JavaScript对象, 它暴露给组件三个property

export default {
  setup(props, context) {
    // Attribute (非响应式对象)
    console.log(context.attrs)
    // 插槽 (非响应式对象)
    console.log(context.slots)
    // 触发事件 (方法)
    console.log(context.emit)
  }
}


// context是非响应式的, 可以对其进行解构
export default {
  setup(props, { attrs, slots, emit }) {
    ...
  }
}

 

访问组件的property

执行setup方法的时候, 组件实例还没有创建, 只能访问以下property

props

attrs

slots

emit

无法访问以下组件选项

data

methods

computed

 

结合模板使用

因为setup返回的refs在模板中访问是被自动浅解包的, 因为不用在模板中使用 .value

 

this问题

在setup内部, this不是该组件实例的引用, 因为setup是在解析其他组件选项之前调用的, 所以setup中的this和其他选项中的this完全不一样

 

生命周期钩子

setup是围绕beforeCreate和created生命周期函数钩子定义的, 所以不需要显示的定义他们,

在这些钩子里面任何代码都应该写在setup中

 

provide和inject

我们也可以在setup中使用provide和inject

示例:

正常情况下得组件传值

// 父组件
provide: {
  location: 'beijing',
  geolocation: {
      longitude: 90,
      latitude: 135
  }
}
// 子组件
inject: [ 'location', 'geolocation' ]

 

使用provide和inject重写

provide()

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

  • name(String类型)
  • value
// 父组件
import { provide } from 'vue'
setup () {
  provide('location', '北京')
  provide('geolocation', {
    longitude: 90,
    latitude: 135
  })
}

inject()

函数有两个参数

  • 要inject的property的name
  • 默认值 (可选)
import { inject } from 'vue'
setup() {
  // 获取location, 给了一个默认值
  const userLocation = inject('location', 'The Universe')
  const userGeolocation = inject('geolocation')
  return {
    userLocation,
    userGeolocation 
  }
}

 

增加响应性

为了增加provide和inject的响应性, 我们在provide值时使用ref和reactive

import { provide, ref, reactive } from 'vue'
setup() {
  const location = ref('beijing')
  const geolocation = reactive({
    longitude: 90,
    latitude: 135
  })
  provide('location ', location )
  provide('geolocation', geolocation )
}

修改响应式的property

  1. 当我们要修改响应式provide和inject的值时, 我们最好将对值的修改写在provide的组件内部
  2. 当我们需要在子孙组件内部修改inject的值时, 一般使用provide的一个方法改变响应式的property
// 1. 在provide所在的组件创建修改值得方法
setup () {
   const updateLocation = () => {
    location.value = 'South Pole'
  }
  provide('updateLocation', updateLocation)
}

 

// 2. 在inject组件中调用这个方法
setup () {
   const updateUserLocation = inject('updateLocation')
   return { updateUserLocation }
}
// 外部可以直接调用
  1. 如果要确保通过provide传递的数据不会被inject更改, 可以对提供者的property使用readonly
import { provide, reactive, readonly, ref } from 'vue'
setup() {
  provide('location', readonly(location))
}