Vue3学习笔记
组合式API入口-setup
setup在beforeCreate钩子之前自动执行。
Vue3由于语法分割,不再使用this去编写业务逻辑,this指向undefined。
setup语法糖下局部组件无需注册直接可以使用。
原始复杂写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <script> export default { setup () { console.log('setup', this); // 数据 const message = 'this is a message!'; // 函数 const logMessage = () => { console.log(message); } return { message, logMessage } } } </script>
|
语法糖写法:
1 2 3 4 5 6 7 8
| <script lang="ts" setup> // 数据 const message = 'this is a message' // 函数 const logMessage = () => { console.log(message) } </script>
|
组合式API-reactive和ref
共同作用:用函数调用的方式生成响应式数据
不同之处:
1、reactive不能处理简单类型的数据
2、ref参数类型支持更好但是必须通过.value访问修改
3、ref函数的内部实现依赖于reactive函数
建议用ref
1 2 3
| <script setup> import { ref, reactive } from 'vue' </script>
|
组合式API-computed
对于任何复杂逻辑,都应当使用computed计算属性。
核心步骤:
1、导入computed函数
2、执行函数在回调参数中return基于响应式数据做计算的值,用变量接受
1 2 3 4 5 6
| <script setup> import { computed } from 'vue' const computedState = computed(() => { return 基于响应式数据做计算之后的值 }) </script>
|
最佳实践:
1、计算属性中不应有“副作用”,比如异步请求、修改dom,只注重于做计算
2、避免直接修改计算属性的值,计算属性应该是只读的,不直接去修改它
组合式API-watch
作用:侦听一个或多个数据的变化,数据变化时执行回调函数
额外参数:
1、immediate(立即执行)
2、deep(深度侦听),监听嵌套对象
侦听单个数据:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script setup> // 导入watch import { ref, watch } from 'vue' const count = ref(0) // 调用watch侦听变化 // watch中ref对象不需要加.value watch(count, (newValue, oldValue) => { console.log('count发生了变化') }, { // 最开始监听的时候便自动执行一次 immediate: true }) </script>
|
侦听多个数据:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script setup> // 导入watch import { ref, watch } from 'vue' const count = ref(0) const name = ref('ac') // 侦听多个数据,同时监听count,name两个的变化 watch( [count, name], ([newCount, newName], [oldCount, oldName]) => { console.log('count或者name发生了变化') } ) </script>
|
深度监听:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script setup> // 导入watch import { ref, watch } from 'vue' const state = ref({ count : 0}) const changeStateByCount = () => { // 直接修改属性 -> 不会触发回调 state.value.count++ } // watch深度监听 watch(state, () => { console.log('count变化了') }, { //默认不会触发回调,加入deep后则可以触发 deep: true }) </script>
|
精确侦听对象的某个属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script setup> import { ref, watch } from 'vue' const info = ref({ name: 'ac', age: 18 }) // 精确侦听某个属性 watch( () => info.value.age, () => { console.log('age改变了') } ) </script>
|
deep性能损耗,尽量不开启deep。
组合式API-生命周期函数
生命周期:
选项式API(Vue2) |
组合式API(Vue3) |
beforeCreate/created |
setup |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeUnmount |
onBeforeUnmount |
unmounted |
onUnmounted |
生命函数是可以执行多次的,多次执行时传入的回调会在时机成熟时依次执行。
组合式API没有onCreated钩子函数,直接写到setup中。
组合式API中组件卸载完毕时执行onUnmounted钩子函数。
组合式API-父子通信
父传子
1、父组件中给子组件绑定属性
2、子组件内部通过props选项接收
3、子组件通过defineProps”编译器宏“接收子组件传递的数据,defineProps({属性名:类型})
父组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script setup> import { ref } from 'vue' import { Son } from 'Son.vue' const count = ref(100) </script>
<template> <div class="father"> <h2>父组件App</h2> <!-- 绑定属性 --> <Son :count="count" message="father message" /> <div> </template>
<style scoped></style>
|
子组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <script setup> // defineProps接收数据 const props = defineProps({ message: String, count: Number }) console.log(props.message) </script>
<template> <div class="son <h3>子组件App</h3> <div> 父组件传入的数据 - {{ message }} - {{ count }} </div> <div> </template>
<style scoped></style>
|
子传父
1、父组件中给子组件标签通过@绑定事件
2、子组件内部通过$emit方法触发事件
3、子组件通过defineEmits编译器宏生成emit方法,defineEmits([‘事件名称’])
父组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script setup> import { Son } from 'Son.vue' const getMessage = (msg) => { console.log(msg) } </script>
<template> <div class="father"> <h2>父组件App</h2> <Son @get-message="getMessage" /> </div> </template>
<style scope></style>
|
子组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <script setup> import { Son } from 'Son.vue' const emit = defineEmits(['get-Message']) const sendMsg = () => { // 触发自定义事件,传数据给父组件 emit('get-Message','this is son message') } </script>
<template> <div class="son"> <h2>子组件father</h2> <button @click="sendMsg">触发自定义事件</button> </div> </template>
<style scope></style>
|
组合式API-模板引用
1、调用ref函数生成一个ref对象
2、通过ref标识绑定ref对象到标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <script setup> import { ref, onMounted } from 'vue' // 调用ref函数 -> ref对象 const h1Ref = ref(null)
// 组件挂载完毕之后才能获取 onMounted(() => { console.log(h1Ref.value) }) </script>
<template> <!-- 通过ref标识绑定ref对象 --> <h1 ref="h1Ref">我是dom标签h1</h1> </template>
<style scope></style>
|
默认情况下在