hookEvent:监听组件生命周期
内部监听生命周期函数
原代码:
改进后的代码:
可以通过 $on, $once去监听所有的生命周期钩子函数。// 监听组件的updated钩子函数this.$on('hook:updated', () => {})
外部监听生命周期函数
Vue.observable状态管理
Vue组件间进行传递共享,一般 用 Vuex 管理状态。但对于小型项目, 使用 Vuex 是繁琐冗余的。可以使用 Vue2.6 提供的 Vue.observable在组件中引用
Vue.extend开发全局组件
Vue.extend是一个全局 API,开发一些全局组件比如 Loading, Notify, Message等组件时,可以使用 Vue.extend在使用 element-ui的 loading时,在代码中可能会这样写// 显示loadingconst loading = this.$loading()// 关闭loadingloading.close()
这样写可能没什么特别的,但是如果你这样写
const loading = this.$loading()const loading1 = this.$loading()setTimeout(() => { loading.close()}, 1000 * 3)
此时,调用两次
loading,但是只出现一次。并且关闭
loading,
loading1也被关闭。
Vue.extend +
单例模式去实现一个
loading
开发loading组件
使用loading组件
但这样使用并不能满足需求
通过js调用方法来显示关闭
loading将整个页面全部遮罩起来
通过Vue.extend将组件转换为全局组件
1. 改造loading组件,将组件的props改为data
export default { data() { return { text: '', visible: false } }}
2. 通过Vue.extend改造组件
3. 使用loading
经过改造, loading可以在全局使用。如果需要像 element-ui一样挂载到 Vue.prototype上面,通过 this.$loading调用,还需要改造一下// 将组件挂载到Vue.prototype上面Vue.prototype.$loading = Loading// 在export之前将Loading方法进行绑定export default Loading// 在组件内使用this.$loading()
自定义指令,从底层解决问题
loading
组件开发完后,其他开发在使用的时候又提出来两个需求
- 可以将loading挂载到某一个元素上面,现在只能是全屏使用
- 可以使用指令在指定的元素上面挂载loading
开发v-loading指令
在元素上面使用指令
自定义指令的使用场景
- 为组件添加loading效果
- 按钮级别权限控制 v-permission
- 代码埋点,根据操作类型定义指令
- input输入框自动获取焦点
深度watch与watch立即触发回调
在 Vue使用 watch去监听数据的变化。比如输入搜索关键字时,自动触发搜索。除了搜索框的 change事件之外,可以通过 watch监听搜索关键字的变化立即触发immediate: true
上面的代码可以在值发生变化时,触发加载数据。但是如果要 在页面初始化时候加载数据,还需要在 created或者 mounted再次调用 $_loadData方法。现在可以通过配置 watch的 立即触发属性 immediate: true深度监听deep: true
监听表单每一个属性,用 watch的 深度监听 deep$watch随时监听,随时取消
有一个表单,在编辑时,监听表单的变化。如果发生变化,则保存按钮启用,否则保存按钮禁用。新增表单可以直接通过watch去监听表单数据,如上例所述。但编辑表单,需要回填数据,改变formData,触发watch,无法准确的判断是否启用保存按钮。此时需要 $watch 在需要时,通过 this.$watch来监听数据变化。 this.$watch返回一个值 unwatch,是一个函数,在需要取消的时候,执行 unwatch()即可取消。 函数式组件:函数是组件(Vue的JSX) 函数式组件即,函数是组件。如 React,函数式组件,可以理解为 没有内部状态,没有生命周期钩子函数,没有this(不需要实例化的组件)。在日常开发中,纯展示性的业务组件,比如一些 详情页面, 列表界面等,有一个共同的特点是 只需要将外部传入的数据进行展现,不需要有内部状态,不需要在生命周期钩子函数里面做处理,此时可以使用函数式组件。上面的代码中,有一个render函数。这个是Vue使用JSX的写法。
函数式组件的优点:
- 不需要实例化,无状态,没有生命周期,所以渲染性能要好于普通组件
- 函数式组件结构比较简单,代码更清晰
函数式组件与普通组件的区别
- 函数式组件需要在声明组件是指定functional
- 函数式组件不需要实例化,没有this。this通过render函数的第二个参数来代替
- 函数式组件没有生命周期钩子函数,不能使用计算属性,watch等
- 函数式组件不能通过$emit对外暴露事件,调用事件只能通过context.listeners.click的方式调用外部传入的事件
- 因为函数式组件是没有实例化的,所以在外部通过ref去引用组件时,实际引用的是HTMLElement
- 函数式组件的props可以不用显示声明,所以没有在props里面声明的属性都会被自动隐式解析为prop。而普通组件所有未声明的属性都被解析到$attrs里面,并自动挂载到组件根元素上面(可以通过inheritAttrs属性禁止)
在Vue2.5之前,使用函数式组件只能通过JSX的方式,在之后,可以通过模板语法来生命函数式组件
<template functional> <img :src="props.avatar ? props.avatar : 'default-avatar.png'" />template>