用法:<script setup lang="ts">// 在这里写vue的逻辑</script><template> <div>哈哈</div></template>
2、ref & reactive & 事件
说明:
1、ref:需要响应式的常量,赋值时需要xxx.value
2、reactive:需要响应式的对象或者数组,可直接使用或赋值
3、事件:在setup script中,直接定义事件
用法:<script setup lang="ts">import { ref, reactive } from 'vue'// 常量const name = ref('小明')// 对象、数组const user = reactive({ name: '小红', gender: '女'})const handleAdd = () => { arr.push({ name: '哈哈哈' }) }</script><template> <button @click="switchName">我叫 {{name}},性别{{user.gender}} </button> <button @click="handleAdd">新增</button></template>
3、computed & watch & watchEffect
说明:
1、computed:计算函数
2、watch:监听函数,可监听常量和引用变量,可传immediate和deep。可监听对象也可只监听对象的某个属性
3、watchEffect:跟watch差不多,但是watchEffect不需要说明监听谁,用到谁就监听谁
用法:<script setup lang="ts">import { ref, reactive, computed,watch, watchEffect } from 'vue'// 常量const name = ref('小明')// 对象、数组const user = reactive({ name: '小红', gender: '女'})// computed计算出userTextconst userText = computed(() => { return `我叫${user.name},我是${user.gender}的`})// 监听user对象watch(user, (next) => { console.log('user被修改了', next) }, { immediate: false, // 首次执行 deep: true // 深度监听对象})// 可监听对象的某个属性,这里监听user.genderwatch(() => user.gender, (next, pre) => { console.log('user.gender被修改了', next, pre) })// 不需要说明监听谁// 用到user.gender就监听user.genderwatchEffect(() => { const gender = user.gender console.log('user.gender被修改了', gender) })</script><template> <div>{{ userText }}</div></template>
4、生命周期
vue2 - vue3
beforeCreate -> 没了
created -> 没了
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeUnmount -> onBeforeUnmount
unmounted -> onUnmounted
activated -> onActivated
deactivated -> onDeactivated
errorCaptured -> onErrorCaptured
<script setup lang="ts"> import {onBeforeMount,onMounted,onUpdated,onBeforeUpdate,onBeforeUnmount, onUnmounted,onActivated,onDeactivated,onErrorCaptured} from 'vue'onBeforeMount(() => { console.log('挂载前') })onMounted(() => { console.log('挂载') })onBeforeUpdate(() => { console.log('更新前') })onUpdated(() => { console.log('更新') })onBeforeUnmount(() => { console.log('销毁前') })onUnmounted(() => { console.log('销毁') })onActivated(() => { console.log('kee-alive激活本组件') })onDeactivated(() => { console.log('kee-alive隐藏本组件') })onErrorCaptured(() => { console.log('错误捕获') }) </script>
5、defineProps & defineEmits
父组件:<script setup lang="ts">import { ref } from 'vue'import Dialog from './Dialog.vue'const msg = ref('我是msg')const changeMsg = (val: string) => { msg.value = val }</script><template>// 传进子组件<Dialog :msg="msg" @changeMsg="changeMsg" /></template>
子组件:<script setup lang="ts">import { defineProps, defineEmits } from 'vue'// 注册父传子的propsconst { msg } = defineProps({ msg: {type: String,required: true } })// 注册父传子的事件const emits = defineEmits(['changeMsg'])const handleClick = () => { // 修改父组件的值 emits('changeMsg', '修改msg') }</script><template> <div @click="handleClick">{{ msg }}</div></template>
6、defineExpose
说明:这个API主要主要作用是:将子组件的东西暴露给父组件,好让父组件可以使用
<!-- 子组件 --><script setup>import { ref } from 'vue'const msg = ref('hello vue3!')function change() { msg.value = 'hi vue3!' console.log(msg.value) }// 属性或方法必须暴露出去,父组件才能使用defineExpose({ msg, change })</script>
<!-- 父组件 --><script setup>import ChildView from './ChildView.vue'import { ref, onMounted } from 'vue'const child = ref(null)onMounted(() => { console.log(child.value.msg) // hello vue3! child.value.change() // hi vue3!})</script><template> <ChildView ref="child"></ChildView></template>
7、全局API
说明:
1、vue3已经没有filter这个全局方法了
2、vue.component -> app.component
3、vue.directive -> app.directive
4、之前Vue.xxx现在都改成app.xxx
// 全局自定义指令app.directive('focus', { mounted(el) { el.focus() } })// 全局自定义组件import CustomComp from './components/CustomComp.vue'app.component('CustomComp', CustomComp)
8、自定义指令
vue2:Vue.directive('xxx', { // 指令绑定到指定节点,只执行一次 bind() {}, // 指定节点插入dom inserted() { }, // 节点VNode更新时,可能刚更新,没完全更新 update() {}, // VNode完全更新 componentUpdated() {}, // 指令从指定节点解绑,只执行一次 unbind() {} })
vue3: app.directive('xxx', {// 在绑定元素的 attribute 或事件监听器被应用之前调用, 在指令需要附加须要在普通的 v-on 事件监听器前调用的事件监听器时,这很有用created() {},// 当指令第一次绑定到元素并且在挂载父组件之前调用beforeMount() {},// 在绑定元素的父组件被挂载后调用mounted() {},// 在更新包含组件的 VNode 之前调用beforeUpdate() {},// 在包含组件的 VNode 及其子组件的 VNode 更新后调用updated() {},// 在卸载绑定元素的父组件之前调用beforeUnmount() {},// 当指令与元素解除绑定且父组件已卸载时, 只调用一次unmounted() {}, });
9、defineAysncCompoment & Suspense
说明:这个API用来加载异步组件,就是用不到他就不加载,用到了才会加载
注:defineAysncCompoment需配合vue3的内置全局组件Suspense使用,需要用Suspense包住异步组件
const AsyncPopup = defineAsyncComponent({ loader: () => import("./LoginPopup.vue"), // 加载异步组件时要使用的组件 loadingComponent: LoadingComponent, // 加载失败时要使用的组件 errorComponent: ErrorComponent, // 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms) delay: 1000, // 如果提供了 timeout ,并且加载组件的时间超过了设定值,将显示错误组件 // 默认值:Infinity(即永不超时,单位 ms) timeout: 3000 })// 使用时,可控制显隐 <Suspense v-if="show" > <AsyncPopup /> </Suspense>
10、自定义hook——useUser
// useUser.tsimport { reactive, computed } from 'vue'const useUser = () => { const user = reactive({name: '小红',gender: '女' }) const userText = computed(() => `我叫${user.name},我是${user.gender}的`) const switchGender = () => { user.gender = '男' } return { switchGender, userText, } }export default useUser
使用hook<script setup lang="ts">import useUser from './useUser'const {userText,switchGender} = useUser()</script><template> <div @click="switchGender">{{ userText }} </div></template>
11、useRouter & useRoute
说明:
1、useRouter:用来执行路由跳转
2、useRoute:用来获取路由参数
<script setup>import { useRouter } from 'vue-router'const router = useRouter()function onClick() { // 跳转 router.push({path: '/about',query: { msg: 'hello vue3!'} }) }</script>
<script setup>import { useRoute } from 'vue-router'const route = useRoute()console.log(route.query.msg) // hello vue3!</script>
12、Teleport
说明:Teleport可以将你的组件,挂载到任意一个节点之下,只要你指定一个选择器,可以是id、class
// Dialog.vue<template> <div>hello world</div></template>
<script setup lang="ts">import Dialog from './Dialog.vue'</script><template> // 将Dialog组件挂载到id为app的节点下 <Teleport to="#app"><Dialog /> </Teleport></template>