返回正文全局注册(
Are you an LLM? You can read better optimized documentation at /zh-CN/blog/2025-08/vue3_render_directive.md for this page in Markdown format
Vue3 项目在render函数中使用自定义指令
一、定义自定义指令
ts
const inputQuantity = {
mounted(el, binding) {
el.addEventListener('input', (e) => {
// 验证输入值
const value = e.target.value
const min = binding.value?.min || 0
const max = binding.value?.max || Infinity
if (/^\d*$/.test(value)) {
let numValue = parseInt(value) || min
// 限制范围
if (numValue < min) numValue = min
if (numValue > max) numValue = max
// 更新模型值
binding.instance[numValue] = numValue
el.value = numValue
} else {
el.value = binding.value?.lastValid || min
}
binding.value.lastValid = el.value
})
}
}
export default inputQuantity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
directives/inputQuantity.ts
二、注册指令
全局注册(main.ts
)###
ts
import { createApp } from 'vue'
import inputQuantity from './directives/inputQuantity'
const app = createApp(App)
app.directive('input-quantity', inputQuantity)
1
2
3
4
5
2
3
4
5
组件内注册
ts
import inputQuantity from './directives/inputQuantity'
export default {
directives: {
'input-quantity': inputQuantity
},
// ...
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
三、在 render 函数中使用自定义指令
在 render 函数中使用指令需要用到vue的两个内部函数 resolveDirective
和 withDirectives
;
resolveDirective
用于解析指令;withDirectives
函数把指令注册对应的VNode对象上
ts
import { h, withDirectives, resolveDirective } from 'vue'
export default {
render() {
// 解析自定义指令
const vInputQuantity = resolveDirective('input-quantity')
// 创建基础 input 节点
const inputNode = h('input', {
type: 'number',
value: this.quantity,
class: 'quantity-input'
})
// 应用自定义指令
return withDirectives(inputNode, [
[
vInputQuantity,
{
min: 1,
max: 100,
lastValid: 1
}
],
// 可同时添加其他指令
```
[resolveDirective('focus'), { autoFocus: true }]
])
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
VN/A |
本站访客数
--次 本站总访问量
--人次