目录前言几种用法用法一 将放在多个生命周期的逻辑,统一到一个生命周期中用法二 监听子组件生命周期运行的情况运用场景场景一场景二场景三所有生命周期执行的顺序第一次渲染更新时组件摧毁时总
@hook是什么?用来监听组件生命周期的回调函数。
这和生命周期函数mounted,created,updated有什么区别?
区别1:@hook 会在对应的生命周期函数执行后执行。
区别2:@hook 可以在父组件监听子组件的生命周期运行情况。
从这段Vue源代码中我们能看到hook的部分调用逻辑,vm.$emit('hook:' + hook)
其实就是在调用我们写的@hook:mounted="xxx"
,@hook这个api却没有在官方文档中出现,所以鲜有人知道它的存在和用法。
通常写法
export default {
components: {},
data: () => {
return {
name: 'dx',
};
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log(this.name);
// 每一个小时刷新一次页面
setInterval(() => {
location.reload()
}, 60 * 60 * 1000);
},
}
@hook的用法
export default {
components: {},
data: () => {
return {
name: 'dx',
};
},
created() {
console.log('created');
this.$on('hook:beforeMount', () => {
console.log('beforeMount');
});
this.$on('hook:mounted', () => {
console.log(this.name); // this 就是组件实例自己
// 每一个小时刷新一次页面
setInterval(() => {
location.reload();
}, 60 * 60 * 1000);
});
},
};
注意
hook:beforeMount
this.$on
第二个回调函数的this
指的是当前组件实例本身,无论这个回调函数是否是箭头函数。通常写法
// 父组件
<Children @buttonRender="ButtonRender"/>
export default {
name: 'Parents',
components: {
Children
},
data: () => {
return {
name: 'dx',
};
},
methods: {
ButtonRender() {
console.log('渲染完成')
}
}
}
// 子组件
export default {
name: 'Children',
components: {},
data: () => {},
methods: {},
mounted() {
this.$emit('buttonRender')
}
}
@hook的写法
<Children @hook:mounted="ButtonRender"/>
export default {
name: 'Parents',
components: {
Children
},
data: () => {
return {
name: 'dx',
};
},
methods: {
ButtonRender() {
console.log('渲染完成')
}
}
}
注意
为了解决3的问题,我尝试着想到一种方法,利用ref获取子组件的实例,将子组件的实例拿到父组件的this中。ButtonRender中的this就是父组件实例,和寻常methods中的函数没区别。
<Children ref="child1" @hook:mounted="ButtonRender"/>
export default {
name: 'Parents',
components: {
Children
},
data: () => {
return {
name: 'dx'
};
},
mounted() {},
methods: {
ButtonRender() {
console.log(this.$refs.child1) // this.$refs.child1就是子组件Children的实例了
console.log('渲染完成')
}
}
};
但是,我们都知道,vue ref的绑定都是挂载完成之后,所以这个方法也只能用在@hook:mounted
、@hook:updated
等mounted之后执行的生命周期中,而不能用在 比如@hook:beforeMount
中。
许多时候,我们不得不在不同的生命周期中执行某些逻辑,并且这些逻辑会用到一些通用的变量,这些通用变量按照之前的方式,我们不得不存在data中。
<script>
export default {
data() {
return {
timer:null
}
}
mounted () {
this.timer = setInterval(() => {
// todo
}, 1000);
}
beforeDestroy () {
clearInterval(this.timer)
}
}
</script>
优化后,就不存在这个问题,是不是很好用。
<script>
export default {
mounted () {
const timer = setInterval(() => {
// todo
}, 1000);
this.$once('hook:beforeDestroy', function () {
clearInterval(timer)
})
}
}
</script>
如果属于同一业务的逻辑要在不同的生命周期中执行,下面这样会更利于阅读和维护。
export default {
created() {
this.$on('hook:mounted', () => {
挂载时执行一些业务A相关逻辑
})
this.$on('hook:updated', () => {
挂载时执行一些业务A相关逻辑
})
this.$once('hook:beforeDestroy', () => {
挂载时执行一些业务A相关逻辑
})
}
}
想要监听别人封装好的组件(第三方组件)的生命周期,你不可能去第三方子组件的生命周期中写代码。
比如 element-ui 的button组件,在子组件渲染完成后,我想做某些逻辑变更。
<el-button type="primary" @hook:mounted="ButtonRender" :disabled="disabled">{{name}}</el-button>
export default {
name: 'Parents',
data: () => {
return {
name: 'dx',
disabled: true
};
},
methods: {
ButtonRender() {
this.disabled = false
this.name = 'yx'
}
}
}
父beforeCreate
父 hook:beforeCreate
父created
父 hook:created
父beforeMount
父 hook:beforeMount
子beforeCreate
子hook:beforeCreate
子created
子hook:created
子beforeMount
子hook:beforeMount
子mounted
子hook:mounted
父mounted
父 hook:mounted
父beforeUpdate
父hook:beforeUpdate
子beforeUpdate
子hook:beforeUpdate
子updated
子hook:updated
父updated
父hook:updated
父beforeDestroy
父hook:beforeDestroy
子beforeDestroy
子hook:beforeDestroy
子destroyed
子hook:destroyed
父destroyed
父hook:destroyed
以上内容涉及到vue父子组件生命周期执行顺序的知识,但对于@hook:xxx来说,在xxx执行后就会立即执行@hook:xxx
到此这篇关于vue2中@hook的解析与妙用的文章就介绍到这了,更多相关vue2 @hook妙用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: vue2中@hook的解析与妙用实例
本文链接: https://lsjlt.com/news/198642.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0