Vue中自定义指令
🍤自定义指令介绍
在Vue的模板语法中我们学习过各种各样的指令: v-show、 v-for、 v-model等等,除了使用这些指令之外, Vue也允许我们来自定义自己的指令。
注意:在Vue中,代码的复用和抽象主要还是通过组件;
通常在某些情况下,你需要
对DOM元素进行底层操作
,这个时候就会用到自定义指令
;
自定义指令分为两种:
自定义局部指令:组件中通过 directives 选项,只能在当前组件中使用;
自定义全局指令: app的 directive 方法,可以在任意组件中被使用;
比如我们来做一个非常简单的案例:当某个元素挂载完成后可以自定获取焦点
实现方式一:如果我们使用默认的实现方式;
实现方式二:自定义一个 v-focus 的局部指令;
实现方式三:自定义一个 v-focus 的全局指令;
接下来我们看看三种方式分别如何实现
🍤自定义指令使用
实现方式一:聚焦的默认实现
通过ref操作DOM获取到元素, 再对元素添加focus
但是这个方式有一个明显缺点, 当多个页面都需要此功能时, 我们多个页面都需要如下操作一遍, 会非常麻烦
<input type="text" ref="inputRef">
<script setup>
import { ref, onMounted } from "vue"
const inputRef = ref()
onMounted(() => {
inputRef.value.focus()
})
</script>
实现方式二:自定义一个局部指令
例如我们自定义一个v-focus指令, 这个自定义指令实现非常简单,我们只需要在组件选项中使用
directives
即可;它是一个对象,在对象中编写我们自定义指令的名称(注意:这里不需要加v-);
自定义指令有一个生命周期,是在组件挂载后调用的 mounted,我们可以在其中完成操作;
当然, 自定义的局部指令只能在当前定义的组件中使用, 其他组件无法使用自定义指令
Options API 实现方式
<input type="text" v-focus>
<script>
export default {
directives: {
focus: {
// 自定义指令的生命周期函数, 当绑定的元素被挂载之后, 会执行, 并将该元素el传入
mounted(el) {
el.focus()
}
}
}
}
</script>
Composition API 实现方式
<input type="text" v-focus>
<script setup>
// 自定义指令
const vFocus = {
// 自定义指令的生命周期函数
mounted(el) {
el.focus()
}
}
</script>
实现方式三:自定义全局指令
在开发中我们常用的是自定义全局指令, 自定义一个全局的指令可以让我们在任何地方直接使用
我们之前是在mian.js中注册的全局组件, 全局指令同样是在main.js中注册的
const app = createApp(App)
app.directive("focus", {
mounted(el) {
el.focus()
}
})
🍤指令的生命周期
一个自定义指令定义的对象, Vue提供了如下的几个钩子函数:
- created:元素已创建, 在绑定元素的 attribute 或事件监听器被应用之前调用;
- beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用;
- mounted:在绑定元素的父组件被挂载后调用;
- beforeUpdate:在更新包含组件的 VNode 之前调用, 绑定元素的内部或后代元素更新也会执行;
- updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用;
- beforeUnmount:在卸载绑定元素的父组件之前调用;
- unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次;
const vMy = {
created() {
console.log("created")
},
beforeMount() {
console.log("beforeMount")
},
mounted() {
console.log("mounted")
},
beforeUpdate() {
console.log("beforeUpdate")
},
updated() {
console.log("updated")
},
beforeUnmount() {
console.log("beforeUnmount")
},
unmounted() {
console.log("unmounted")
},
}
🍤指令参数和修饰符
如果我们指令需要接受一些参数或者修饰符我们可以如下进行操作:
<h2 v-my:info.aaa.bbb="{name: chenyq, age: 18}">app</h2>
info是参数的名称;
aaa-bbb是修饰符的名称;
等于符号后面是传入的具体的值;
在我们的生命周期中,我们可以通过第二个参数 bindings
获取到对应的内容:
bindings对应的是一个对象
对象中, arg存放的是参数, modifiers中存放的是修饰符, value中存放的是参数值
演示代码: 例如传入一个文本替换当前元素中的文本
<h2 v-my:info="message">app</h2>
<script setup>
const message = "哈哈哈哈"
const vMy = {
mounted(el, bindings) {
// 通过bindings获取到参数值
el.textContent = bindings.value
},
}
</script>
🍤自定义指令练习
自定义指令案例:时间戳的显示需求:
在开发中,大多数情况下从服务器获取到的都是时间戳;
我们需要将时间戳转换成具体格式化的时间来展示;
在Vue2中我们可以通过过滤器来完成;
在Vue3中我们可以通过 计算属性(computed) 或者 自定义一个方法(methods) 来完成;
其实我们还可以通过一个自定义的指令来完成;
我们来实现一个可以自动对时间格式化的指令v-format-time:
这里我使用的是自定义局部指令演示, 正常情况应该是自定义全局指令;
演示代码如下
<!-- 默认格式展示 -->
<h2 v-time>{{ timestamp }}</h2>
<!-- 自定义格式展示 -->
<h2 v-time="'YYYY/MM/DD'">{{ timestamp }}</h2>
<script setup>
import dayjs from "dayjs"
const timestamp = 1295658132
const vTime = {
mounted(el, bindings) {
// 1.如果传入的是秒钟, 我们将其转为毫秒
let timestamp = el.textContent
if (timestamp.length === 10) {
timestamp = timestamp * 1000
}
// 2.接收参数, 可以自定义时间的格式
let value = bindings.value
if (!value) {
value = "YYYY-MM-DD HH:mm:ss"
}
// 3.对时间进行格式化
const formatTime = dayjs(timestamp).format(value)
el.textContent = formatTime
},
}
</script>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/120070.html