两个参数:
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
- 当我们要修改响应式provide和inject的值时, 我们最好将对值的修改写在provide的组件内部
- 当我们需要在子孙组件内部修改inject的值时, 一般使用provide的一个方法改变响应式的property
// 1. 在provide所在的组件创建修改值得方法
setup () {
const updateLocation = () => {
location.value = 'South Pole'
}
provide('updateLocation', updateLocation)
}
// 2. 在inject组件中调用这个方法
setup () {
const updateUserLocation = inject('updateLocation')
return { updateUserLocation }
}
// 外部可以直接调用
- 如果要确保通过provide传递的数据不会被inject更改, 可以对提供者的property使用readonly
import { provide, reactive, readonly, ref } from 'vue'
setup() {
provide('location', readonly(location))
}