钩子函数
文章开头先复习一下vue3文档对自定义指令生命周期的说明
created- 新增!在元素的 attribute 或事件监听器被应用之前调用。bind→beforeMountinserted→mountedbeforeUpdate:新增!在元素本身被更新之前调用,与组件的生命周期钩子十分相似。update→ 移除!该钩子与 updated 有太多相似之处,因此它是多余的。请改用 updated。componentUpdated→updatedbeforeUnmount:新增!与组件的生命周期钩子类似,它将在元素被卸载之前调用。unbind->unmounted
函数简写
你可能想在 mounted 和 updated 时触发相同行为,而不关心其他的钩子函数。那么你可以通过将这个回调函数传递给指令来实现:
app.directive('pin', (el, binding) => {
el.style.position = 'fixed'
const s = binding.arg || 'top'
el.style[s] = binding.value + 'px'
})
实战
产品的需求是这样的:数值如果涨(即正数),字体颜色展示为红色, 数值如果跌(即负数),字体颜色展示为绿色。因此写一个自定义指令实现。
实现思路: 用innerText获取dom元素包裹的数值, 判断若数值大于0,则添加字体红色的样式,若数值小于0,则添加字体绿色的样式。
代码如下: ps(用到了上面提到的函数简写)
export default function (el: HTMLElement, binding: any): void {
//v-color有绑定值就取绑定值, 没有就取标签之间的内容
const val = binding.value ? Number(binding.value) : Number(el.innerText.replace(/\+|\%/g, ''))
if (isNaN(val)) return
if (val > 0) {
el.style.color = '#FE3C3C'
} else if (val < 0) {
el.style.color = '#00AF0D'
} else {
el.style.color = '#333'
}
}
这段代码作用是兼容处理了%和带有+号数值的数据,将数值的%和+号去掉,避免带有符号的数值在下面和0无法做大小比较。
const val = binding.value ? Number(binding.value) : Number(el.innerText.replace(/\+|\%/g, ''))
最后在创建vue实例的地方注册一下自定义指令就可以全局使用了
import { createApp } from 'vue';
import App from './App.vue';
import color from './utils/directives/v-color';
app = createApp(App);
app.directive('color', color);
<div>
<label>当日盈亏:</label>
<span v-color>{{ DecimalDigitsFormat(assetsData.dayProfit) || '--' }}</span>
</div>
效果如图: