Vue3
初始化
创建一个项目
npm init vue@next
vue3的生命周期
setUp() { // -> beforeCreate + created
onBeforeMount(() => {})
onMounted(() => {})
onBeforeUpdate(() => {})
onUpdated(() => {})
onActivated(() => {}) // 被 <keep-alive> 缓存的组件激活时
onDeactivated(() => {}) // 被 <keep-alive> 缓存的组件停用时
onBeforeUnmount(() => {})
onUnmounted(() => {})
onErrorCaptured(() => {}) // 当捕获一个来自子孙组件的错误时被调用,返回 false 以阻止该错误继续向上传播
}
watch 侦听器的使用
import { watch } from 'vue'
watch(count, () => {
console.log(count.value)
})
watch([count1, count2], () => {})
watch([count1, () => data.count2], () => {}) // 监听 reactive 包装的响应式对象使用函数式返回
const props = defineProps<{
name: string
}>()
watch(() => props.name, () => {
// 如果是监听一个对象属性,第一个参数需要函数的形式
})
计算属性
import { compute } from 'vue'
const single = ref(4)
const double = computed(() => {
return single.value * 2
})
const double = computed({
get: () => {
return single.value * 2
},
set(value) {
console.log(value)
}
})
依赖注入
- 父组件提供
<script setup>
import { provide } from 'vue'
const count = ref(0)
provide(/* 注入名 */ 'count', /* 值 */ count)
</script>
- 应用级提供
import { createApp } from 'vue'
const app = createApp({})
app.provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
- 接收
// 如果没有祖先组件提供 "message"
// `value` 会是 "这是默认值"
const value = inject('message', '这是默认值')
Teleport
将 teleport 包裹的元素传送到 指定 的元素中,例如 to=“body”
<template>
<teleport to="#modal">
<div v-if="isOpen" class="modal-box">
<slot> <h2>this is a modal</h2> </slot>
<button @click="closeModal">关闭</button>
</div>
</teleport>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
props: {
isOpen: Boolean
},
emits: {
'close-modal': null // 这里要先声明emit
},
setup (props, context) {
const closeModal = () => {
context.emit('close-modal')
}
return {
closeModal
}
}
})
</script>
通过 ref 获取 DOM 节点
dom 上的 ref 命名与 setup() 函数中 return 出来的变量名一致即可拿到 ref
<template>
<div ref="drapdownRef" class="dropdown"/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const drapdownRef = ref<null | HTMLElement>(null)
if (drapdownRef.value) {
console.log(drapdownRef.value)
}
</script>
vue3 中的 template 要实现 ts 补全
// 在 vscode 的 setting.json 中添加
"vetur.experimental.templateInterpolationService": true
style 样式类使用变量 v-bind 语法糖
<template>
<div class="test-bind">...</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const color1 = ref('red')
</script>
<style scoped>
.test-bind{
color: v-bind(color1);
}
</style>
这种写法其实是如下实现的一个语法糖:
<template>
<div :style={'--custom-color': color1 } class="test-bind">...</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const color1 = ref('red')
</script>
<style scoped>
.test-bind{
color: var(--custom-color);
}
</style>
属性继承
<template>
<div v-bind="$attrs">
</template>
$attrs 既可以将父组件传进来的属性传递给子组件,也可以将子组件的事件抛出到父组件