很激动进入了 Vue 3 的学习,作为一个已经上线了三年多的框架,很多项目都开始使用 Vue 3 来编写了
这一组文章主要聚焦于 Vue 3 的新技术和新特性
如果想要学习基础的 Vue 语法可以看我专栏中的其他博客
Vue(一):Vue 入门与 Vue 指令
Vue(二):计算属性与 watch 监听器
Vue(三):Vue 生命周期与工程化开发
一篇文章快速通关 Vuex(适合小白学习)
Vue 框架前导:详解 Ajax
快速打通 Vue 3(一):基本介绍与组合式 API
快速打通 Vue 3(二):响应式对象基础
快速打通 Vue 3(三):Vue3 中的 watch 监听器与新特性
上一篇 Vue3 博客:快速打通 Vue 3(三):Vue3 中的 watch 监听器与新特性
后续还会继续更新,期待大家的关注!
因为我想要将 Vue3 分模块整理,后面要接一篇路由的整理,所以这篇文章会比较短,后面路由想保证量大管饱(bushi)。
06. 标签的 ref 属性
当我们想要获取一个标签对应的
DOM
元素的时候在JavaScript
中,我们通过document.querySelector()
来借助类选择器的写法获取,但是在Vue
中,我们的DOM
元素是挂载在同一个网页上的,这些名称难免会重复,所以需要别的方式去获取。
6.1 用在普通标签上
这里就需要借助给标签加上 ref
属性
直接来上代码
<template>
<h1 ref="h1">111</h1>
<button @click="getLog">命令展示</button>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const h1 = ref();
const getLog = () => {
console.log(h1.value);
}
</script>
这里我们书写了一个 h1
标签,给 h1
加上 ref
属性,属性值为 h1
,下面来通过与属性值同名的响应式变量来获取这个 DOM
元素。
可以直接拿到这个对象,像我们之前去操作 DOM
元素那样,可以对它进行任何操作。
- 补充:这里为什么不直接写
console.log(h1.vale)
而是要书写一个函数然后绑定事件?主要原因是我们执行javaScript
代码的时候,这个元素还没有挂载完成,在后面学习生命周期后,可以通过钩子函数实现在挂载完成后打印。
6.2 用在组件标签上
<template>
<Son ref="son"></Son>
<button @click="showMessage">打印信息</button>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Son from './components/Son.vue';
const son = ref();
const showMessage = () => {
console.log(son.value);
}
</script>
和上面相同,打印出来的是子组件的示例对象,但示例对象中的信息我们是无法拿到的,需要子组件去配置
defineExpose({暴露出去的信息})
<template>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const a = ref();
const b = ref();
const c = ref();
defineExpose({a, b, c});
</script>
我们就能拿到暴露出来的信息,也可以通过数组来导出。
07. 生命周期
Vue
组件实例在创建时要经历一系列的初始化步骤,在此过程中Vue
会在特定的事件去调用特定的函数,从而让开发者有机会在特定的阶段去运行自己的代码,这些待定的函数称之为生命周期钩子。
与 Vue2
相比, Vue3
对生命周期做了简化,不再去写选项式API,而是采用函数的方式去代替,并且对各个生命周期的函数都做了简化:
-
Vue2 的生命周期
创建阶段:
beforeCreate
、created
挂载阶段:
beforeMount
、mounted
更新阶段:
beforeUpdate
、updated
销毁阶段:
beforeDestroy
、destroyed
-
Vue3 的生命周期
创建阶段:
setup
挂载阶段:
onBeforeMount
、onMounted
更新阶段:
onBeforeUpdate
、onUpdated
卸载阶段:
onBeforeUnmount
、onUnmounted
比较重要的两个阶段就是创建阶段和挂载阶段,在更新阶段我们可以向服务端请求数据,挂载完成后我们可以获取 DOM
元素然后对其进行操作。
在 Vue3
中将其创建阶段简化为 setup
,方便了代码的书写。
我们上面提到为什么不使用 console.log(h1.value)
直接打印而是要写个函数,就是因为当我们能看到那个按钮的时候说明已经挂载完毕了,可以来获取元素了,如果直接打印获取到的就是 undefined
。
但通过生命周期函数可以实现:
<template>
<h1 ref="h1">111</h1>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
const h1 = ref();
onMounted(() => {
console.log(h1.value);
})
</script>
我们在挂载完毕后再打印就能够获取到了。
再来查看一个父子组件的生命周期关系
<template>
<Son></Son>
</template>
<script setup lang="ts">
import { onBeforeMount, onBeforeUpdate, onMounted } from 'vue';
import Son from './components/Son.vue';
console.log("父组件 - 创建阶段");
onBeforeMount(() => {
console.log("父组件 - 挂载前阶段")
})
onMounted(() => {
console.log("父组件 - 挂载后阶段")
})
onBeforeUpdate(() => {
console.log("父组件 - 更新前阶段")
})
onBeforeUpdate(() => {
console.log("父组件 - 更新后阶段")
})
</script>
<template>
</template>
<script setup lang="ts">
import { onBeforeMount, onBeforeUpdate, onMounted } from 'vue';
console.log("子组件 - 创建阶段");
onBeforeMount(() => {
console.log("子组件 - 挂载前阶段")
})
onMounted(() => {
console.log("子组件 - 挂载后阶段")
})
onBeforeUpdate(() => {
console.log("子组件 - 更新前阶段")
})
onBeforeUpdate(() => {
console.log("子组件 - 更新后阶段")
})
</script>
打印结果
先去加载完成子组件再去加载父组件,所以通过网络请求数据并且传入子组件需要在父组件的创建阶段完成。