Vue 先初始化子组件再初始化父组件的方法(自定义父子组件mounted执行顺序) 每日简讯
1、引用关系说明最终目的:使用写在前面:
(资料图片仅供参考)
本篇内容内容主要讲述了,在使用
Konva
进行开发过程中遇到的一些问题。(既然是组件加载顺序,主要牵扯到的就是,父子组件的关系,父子组件的生命周期)众所周知,
Vue
中父子组件生命周期的执行顺序为:// 挂载阶段父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted// 更新阶段父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated// 销毁阶段父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
然而,在某些情况下我们有其他需求,例如我们不得不让子组件的初始化在父组件初始化完成之后再进行(一般是针对
mounted
),下面将进行详细说明
Konva
库绘制组件,该组件由两个按钮、一个电平表、一个增益控制推杆,这些子组件组合起来构成所需组件,并将其绘制到Stage
中的Layer
上Stage
和Layer
只有一个,所以应当写在App.vue中,使用时将Layer
传递给子组件(且这个Layer应当是响应式的);且由于要绘制所需组件,因此自然是要引用所需组件,即所需组件是App.vue的子组件所需组件应当引用各个子组件,它是各个子组件的父亲综上,是一个三层的继承关系,此外,由于有了Stage
和Layer
才能绘制所需组件,有了所需组件才能绘制各个子组件,此时,各个控件的初始化顺序与生命周期刚好相反。2、两层继承关系示例假如说目前我只有两层继承关系,
App.vue
和所需组件Channel.vue
代码在下方展示,详细的内容我将在代码中使用注释详细说明,请按照注释编号顺序进行阅读和理解
App.vue
要点:
layer
依赖注入,使所有的子组件可以获取父组件的layer
进行依赖注入时需要使用响应式,以便于父组件知道layer
的改变(类比C语言的直接传参和指针传参)需要将所需组件引用、注册并展示到页面上
<script>import Konva from "konva";import { computed } from "vue";// 5. 引入所需组件用于绘制和页面展示import Channel from "./components/Channel.vue";export default { // 2. 父组件将 layer 传递给子组件,子组件没有 layer 就无法绘制组件 provide() {// 依赖注入,所有子组件可获取 return { // 3. 传递给子组件的 layer应当是响应式的,否则对子组件的修改无法同步到父组件的layer layer: computed(() => this.layer), // 4. 响应式的区别,类比C语言的直接传参和指针传参 } }, components: { // 6. 注册子组件 Channel, }, mounted() { // 0.初始化组件 this.initializeKonva(); window.addEventListener("resize", this.handleResize); }, beforeUnmount() { window.removeEventListener("resize", this.handleResize); }, data() { return { stage: null, layer: null, }; }, methods: { initializeKonva() { this.stage = new Konva.Stage({ container: "frame", width: window.innerWidth, height: window.innerHeight, }); // 1. 这里为了解耦和效率,全局使用一个layer this.layer = new Konva.Layer(); this.stage.add(this.layer); }, handleResize() { this.stage.width(window.innerWidth); this.stage.height(window.innerHeight); this.stage.batchDraw(); }, },};</script>
Channel.vue
要点:
接收
layer
使用
this.$nextTick(() => { 初始化代码 })
,会使得初始化代码在父组件的初始化完成后再执行
this.$nextTick()
是Vue.js
提供的一个方法,用于在DOM更新之后执行回调函数。它的作用是确保在下次DOM
更新循环结束之后执行回调函数,以确保操作的准确性和可靠性。在
Vue.js
中,当数据发生改变时,Vue
会异步地更新DOM
。这意味着在修改数据后立即访问更新后的DOM
可能无法得到正确的结果,因为此时DOM
可能尚未完成更新。通过使用
this.$nextTick()
方法,我们可以将回调函数延迟到下一次DOM
更新循环之后执行。在这个时候,Vue
已经完成了所有的异步DOM
更新,我们可以放心地操作更新后的DOM
元素,确保获取到准确的结果。绘制完成后更新
layer
<script>import Konva from "konva";export default { // 1. 接收父组件依赖注入的 layer inject: ["layer"], components: {}, data() {return {};}, mounted() { // 2. 使用 this.$nextTick(() => {}),在DOM更新之后执行回调函数 this.$nextTick(() => { // 3. 初始化 this.initializeKonva(); }); }, methods: { initializeKonva() { this.group = new Konva.Group({ // ... }); const backgroundRect = new Konva.Rect({ // ... }); const textTop = new Konva.Text({ // ... }); this.textLevel = new Konva.Text({ // ... }); this.textGain = new Konva.Text({ // ... }); const textBottom = new Konva.Text({ // ... }); const line1 = new Konva.Line({ // ... }); const line2 = new Konva.Line({ // ... }); const line3 = new Konva.Line({ // ... }); this.group.add(backgroundRect, textTop, this.textLevel, this.textGain, textBottom, line1, line2, line3); // 4. layer 是通过依赖注入传递,inject接收的,使用 this 访问 this.layer.add(this.group); // 5. 更新 layer this.layer.draw(); }, },};</script>
3、三层及以上继承关系示例在上面的内容中,使用this.$nextTick(() => { 回调 })
解决了两层继承关系中的反向初始化顺序的问题。但是这本质上更像是一种小聪明,当到了三层以上继承关系的时候这种方法不能有任何效果,因为子组件和孙子组件如果不同时使用this.$nextTick(() => { 回调 })
总会有人在父组件之前初始化,而如果都用了this.$nextTick(() => { 回调 })
那么它们两个本身的初始化顺序仍然是先子后父,一定会出问题。所以要使用其他的方式来解决这个问题代码在下方展示,详细的内容我将在代码中使用注释详细说明,请按照注释编号顺序进行阅读和理解
Channel.vue
要点:
接收layer
等不再赘述使用this.$nextTick(() => { 初始化代码 })
,会使得初始化代码在父组件的初始化完成后再执行设置flag
用于判断当前组件初始化是否完成,使用v-if="flag"
控制子组件初始化时机
<script>import Konva from "konva";import SwitchButton from "./SwitchButton.vue";import LevelMeter from "./LevelMeter.vue";import Gain from "./Gain.vue";export default { inject: ["layer"], components: { SwitchButton, LevelMeter, Gain, }, data() { return { // ... // 0. 准备一个flag用于确认初始化时机 flag: false, group: null, }; }, mounted() { // 1. 存在父亲,切需要使用父亲中的 layer ,等待父组件初始化完成 this.$nextTick(() => { this.initializeKonva(); // 2. 使用flag判断是否已经初始化完成 this.flag = true; }); }, methods: { initializeKonva() { // ... this.layer.add(this.group); this.layer.draw(); }, handleDBChange(newDB) { // ... }, handleLevelChange(newLevel) { // ... }, },};</script>
关键词:
相关阅读
-
Vue 先初始化子组件再初始化父组件的方...
>**写在前面:**>>*本篇内容内容主要讲述了,在使用`Konva`进行开发过 -
价格实惠!小米笔记本电脑RedmiBook Pr...
这款小米笔记本电脑红米RedmiBookPro14锐龙版价格实惠!实际到手仅需36 -
萝莉身御姐心的皇冠SportCross,能打动...
对于中国消费者而言,皇冠可以说是块耳熟能详、家喻户晓的金字招牌。但 -
研究表明 卷发或是人类大脑发育关键
参考消息网7月5日报道据美国《新闻周刊》网站6月27日报道,科学家发现 -
自贡富顺:35千伏瓦市变电站投运 为群...
“高温天气不担心用电了。”近日,自贡市富顺县富世街道高山村居民... -
2023年梅花金银兔纪念币价格(2023年07...
金投网提供2023年梅花金银兔纪念币价格今天多少一克(2023年07月06日)
精彩放送
-
Vue 先初始化子组件再初始化父组件的方...
>**写在前面:**>>*本篇内容内容主要讲述了,在使用`Konva`进行开发过 -
价格实惠!小米笔记本电脑RedmiBook Pr...
这款小米笔记本电脑红米RedmiBookPro14锐龙版价格实惠!实际到手仅需36 -
萝莉身御姐心的皇冠SportCross,能打动...
对于中国消费者而言,皇冠可以说是块耳熟能详、家喻户晓的金字招牌。但 -
研究表明 卷发或是人类大脑发育关键
参考消息网7月5日报道据美国《新闻周刊》网站6月27日报道,科学家发现 -
自贡富顺:35千伏瓦市变电站投运 为群...
“高温天气不担心用电了。”近日,自贡市富顺县富世街道高山村居民... -
2023年梅花金银兔纪念币价格(2023年07...
金投网提供2023年梅花金银兔纪念币价格今天多少一克(2023年07月06日) -
蔡秋凤闽南语全部歌曲(蔡秋凤)|环球最新
1、我一直喜欢闽南歌,特别喜欢蔡秋凤的歌,我收藏了好多她的歌曲,其 -
全球热门:本田中国公布6月销量 同比下滑19.8%
本田中国在近期公布6月以及2023年上半年销量。根据数据,本田2023年6月 -
今日快看!美媒:澳大利亚房租飞涨,分时...
由于房租持续上涨,不少澳大利亚大学生开始和他人“共享床位”以节... -
当前看点!宁夏全面推行“六级”耕地保护...
宁夏近日印发《关于全面推行“六级”耕地保护网格化监管的通知》,...