1.新增v-slot:slotname 简写是#
2.1)$emit选项声明要自定义的事件名:$emit:['自定义时间名']
2) 在setup函数的形参中获取emit :emit('自定义事件名',传参)
3.Computed 与 watch
#computed
使用 getter 函数,并为从 getter 返回的值返回一个不变的响应式 ref 对象。
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // error
或者,它可以使用具有 get
和 set
函数的对象来创建可写的 ref 对象。
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
#watchEffect
在响应式地跟踪其依赖项时立即运行一个函数,并在更改依赖项时重新运行它。
const count = ref(0)
watchEffect(() => console.log(count.value))
// -> logs 0
setTimeout(() => {
count.value++
// -> logs 1
}, 100)
function watchEffect(
effect: (onInvalidate: InvalidateCbRegistrator) => void,
options?: WatchEffectOptions
): StopHandle
interface WatchEffectOptions {
flush?: 'pre' | 'post' | 'sync' // default: 'pre'
onTrack?: (event: DebuggerEvent) => void
onTrigger?: (event: DebuggerEvent) => void
}
interface DebuggerEvent {
effect: ReactiveEffect
target: any
type: OperationTypes
key: string | symbol | undefined
}
type InvalidateCbRegistrator = (invalidate: () => void) => void
type StopHandle = () => void
#watch
侦听器 data 源可以是返回值的 getter 函数,也可以是 ref:
// 侦听一个getter
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
/* ... */
}
)
// 直接侦听一个ref
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
})
#侦听多个源
侦听器还可以使用数组同时侦听多个源:
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
/* ... */
})
4.使用 setup
函数时,它将接受两个参数:
props
context
#props
setup
函数中的第一个参数是 props
。正如在一个标准组件中所期望的那样,setup
函数中的 props
是响应式的,当传入新的 prop 时,它将被更新。
// MyBook.vue
export default {
props: {
title: String
},
setup(props) {
console.log(props.title)
}
}
WARNING
但是,因为 props
是响应式的,你不能使用 ES6 解构,因为它会消除 prop 的响应性。
如果需要解构 prop,可以通过使用 setup
函数中的 toRefs
来安全地完成此操作。
// MyBook.vue
import { toRefs } from 'vue'
setup(props) {
const { title } = toRefs(props)
console.log(title.value)
}
#上下文
传递给 setup
函数的第二个参数是 context
。context
是一个普通的 JavaScript 对象,它暴露三个组件的 property:
// MyBook.vue
export default {
setup(props, context) {
// Attribute (非响应式对象)
console.log(context.attrs)
// 插槽 (非响应式对象)
console.log(context.slots)
// 触发事件 (方法)
console.log(context.emit)
}
}
context
是一个普通的 JavaScript 对象,也就是说,它不是响应式的,这意味着你可以安全地对 context
使用 ES6 解构。
// MyBook.vue
export default {
setup(props, { attrs, slots, emit }) {
...
}
}
attrs
和 slots
是有状态的对象,它们总是会随组件本身的更新而更新。这意味着你应该避免对它们进行解构,并始终以 attrs.x
或 slots.x
的方式引用 property。请注意,与 props
不同,attrs
和 slots
是非响应式的。如果你打算根据 attrs
或 slots
更改应用副作用,那么应该在 onUpdated
生命周期钩子中执行此操作。
6.
下表包含如何在 setup () 内部调用生命周期钩子:
选项式 API | Hook inside setup |
---|---|
beforeCreate | Not needed* |
created | Not needed* |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
TIP
因为 setup
是围绕 beforeCreate
和 created
生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup
函数中编写。
这些函数接受一个回调函数,当钩子被组件调用时将会被执行:
import { onMounted, onUpdated, onUnmounted } from 'vue'
const MyComponent = {
setup() {
onMounted(() => {
console.log('mounted!')
})
onUpdated(() => {
console.log('updated!')
})
onUnmounted(() => {
console.log('unmounted!')
})
}
}
7.提供provide/注入inject
父组件使用provide函数来提供
<!-- src/components/MyMap.vue -->
<template>
<MyMarker />
</template>
<script>
import { provide, reactive, 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
})
provide('location', location)
provide('geolocation', geolocation)
return {
location
}
},
methods: {
updateLocation() {
this.location = 'South Pole'
}
}
}
</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>