主题
Vue基础
生命周期

上图中是选项式API的生命周期钩子函数,组合式API的生命周期钩子函数(下表红色字体)总是比选项式先调用。
| 顺序 | 父组件 | 子组件 |
|---|---|---|
| 1 | beforeCreate | |
| 2 | created | |
| 3 | onBeforeMount | |
| 4 | beforeMount | |
| 5 | beforeCreate | |
| 6 | created | |
| 7 | onBeforeMount | |
| 8 | beforeMount | |
| 9 | onMounted | |
| 10 | mounted | |
| 11 | onMounted | |
| 12 | mounted | |
| 更新阶段 | ||
| 13 | onBeforeUpdate | |
| 14 | beforeUpdate | |
| 15 | onUpdated | |
| 16 | updated | |
| 卸载阶段 | ||
| 17 | onBeforeUnmount | |
| 18 | beforeUnmount | |
| 19 | onUnmounted | |
| 20 | unmounted |
父组件请求数据传入子组件
第一种方式:
javascript
created () {
console.log("parent created start---------")
this.fetchWords() // 异步网络请求
console.log("parent: ", this.words) // this.words 初始化为[]
console.log("parent created end---------")
}日志输出为:
console
parent created start---------
parent: []
parent created end---------
child created---
child mounted
child: [] // 将words传递给子组件的props仍然是空数组
parent mounted---第二种方式:
javascript
async created () {
console.log("parent created start---------")
await this.fetchWords()
console.log("parent: ", this.words)
console.log("parent created end---------")
}日志输出为:
console
parent created start---------
child created---
child mounted---
child: []
parent mounted---
parent: [xxx, xxx,...] 获取到数据
parent created end---------总结
通过异步请求的数据,从父组件传给子组件时,都为空,所以必须在子组件中监听传递的数据。
reactive和ref
| reactive | ref |
|---|---|
| 只能创建对象类型(对象、数组、Map、Set等)的代理,对简单数据类型无效。 | 可包装简单类型和对象类型。包装对象类型将转换成reactive包装。 |
| 直接获取值 | 需要使用 .value 来获取值。 |
| 对响应式变量直接赋值,将丢失初始引用的响应性连接。 | 对响应式变量 .value 赋值,不会丢失初始引用的响应性连接。 |
| 将响应式对象的属性解构到本地变量:如果解构的是对象类型,则依然保持连接; 但如果解构出来的是基础数据类型,则需要使用 toRef 或 toRefs 重新包装,否则将丢失响应性连接。 | |
使用建议:
- 业务中很多时候是通过网络请求获取列表数据然后直接赋值,所以包装数组对象最好使用
ref,不会丢失响应性连接。 - 父组件中包装的简单数据类型如
count = ref(0),传到子组件中包装为ct = ref(props.count),这两者没有响应性连接,子组件中的ct只是使用父组件的count值作为初始值,父子组件修改不会影响对方。如果想让父组件修改时同时修改子组件的值,可以使用watch监听父组件的count值,并修改子组件的ct值。如果想让双方互相影响,可以使用v-model双向绑定。 - 父组件中的对象数据类型传递到子组件中,父子组件修改(不是重新赋值)会相互影响,因为对象数据类型传递的是引用。